Skip to content

[lldb] lldb accepts non-DW_TAG_base_type DIEs as DW_OP_convert type operands #208197

Description

@jielun-wu

Per DWARF v5 Section 2.5.1.6, a nonzero DW_OP_convert operand references a type DIE in the current compilation unit, and that DIE must be a DW_TAG_base_type.

LLDB validates only the resolved DIE's size and encoding, not its tag. As a result, a non-base type DIE is accepted whenever it happens to carry base-type-like attributes — a DW_AT_byte_size/DW_AT_bit_size and a signed/unsigned DW_AT_encoding.

Source Evidence

The nonzero-operand path is Evaluate_DW_OP_convert in DWARFExpression.cpp, which resolves the target type through DWARFUnit::GetDIEBitSizeAndSign in DWARFUnit.cpp:

llvm::Expected<std::pair<uint64_t, bool>>
DWARFUnit::GetDIEBitSizeAndSign(uint64_t relative_die_offset) const {
  const uint64_t abs_die_offset = relative_die_offset + GetOffset();
  DWARFDIE die = const_cast<DWARFUnit *>(this)->GetDIE(abs_die_offset);
  if (!die)
    return llvm::createStringError("cannot resolve DW_OP_convert type DIE");
  uint64_t encoding =
      die.GetAttributeValueAsUnsigned(DW_AT_encoding, DW_ATE_hi_user);
  uint64_t bit_size = die.GetAttributeValueAsUnsigned(DW_AT_byte_size, 0) * 8;
  if (!bit_size)
    bit_size = die.GetAttributeValueAsUnsigned(DW_AT_bit_size, 0);
  if (!bit_size)
    return llvm::createStringError("unsupported type size");
  bool sign;
  switch (encoding) {
  case DW_ATE_signed:
  case DW_ATE_signed_char:
    sign = true;
    break;
  case DW_ATE_unsigned:
  case DW_ATE_unsigned_char:
    sign = false;
    break;
  default:
    return llvm::createStringError("unsupported encoding");
  }
  return std::pair{bit_size, sign};
}

It resolves the DIE and reads DW_AT_encoding, DW_AT_byte_size, and DW_AT_bit_size, but never checks that die.Tag() is DW_TAG_base_type. Any DIE carrying a signed/unsigned encoding and a size is therefore accepted. (A DIE without a signed/unsigned encoding falls into the default: unsupported encoding path, so the DIEs that slip through are exactly the non-base types that still have such an encoding and a size, such as DW_TAG_enumeration_type.)

Metadata

Metadata

Assignees

No one assigned

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions