diff --git a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h --- a/llvm/include/llvm/ObjectYAML/DWARFEmitter.h +++ b/llvm/include/llvm/ObjectYAML/DWARFEmitter.h @@ -40,6 +40,7 @@ Error emitDebugAddr(raw_ostream &OS, const Data &DI); Error emitDebugStrOffsets(raw_ostream &OS, const Data &DI); Error emitDebugRnglists(raw_ostream &OS, const Data &DI); +Error emitDebugLoclists(raw_ostream &OS, const Data &DI); Expected>> emitDebugSections(StringRef YAMLString, bool ApplyFixups = false, diff --git a/llvm/include/llvm/ObjectYAML/DWARFYAML.h b/llvm/include/llvm/ObjectYAML/DWARFYAML.h --- a/llvm/include/llvm/ObjectYAML/DWARFYAML.h +++ b/llvm/include/llvm/ObjectYAML/DWARFYAML.h @@ -185,16 +185,28 @@ std::vector Offsets; }; +struct DWARFOperation { + dwarf::LocationAtom Operator; + std::vector Values; +}; + struct RnglistEntry { dwarf::RnglistEntries Operator; std::vector Values; }; -struct Rnglist { - std::vector Entries; +struct LoclistEntry { + dwarf::LoclistEntries Operator; + std::vector Values; + Optional DescriptorLength; + std::vector Descriptors; +}; + +template struct ListEntries { + std::vector Entries; }; -struct RnglistTable { +template struct ListTable { dwarf::DwarfFormat Format; Optional Length; yaml::Hex16 Version; @@ -202,7 +214,7 @@ yaml::Hex8 SegSelectorSize; Optional OffsetEntryCount; Optional> Offsets; - std::vector Lists; + std::vector> Lists; }; struct Data { @@ -223,7 +235,8 @@ std::vector CompileUnits; std::vector DebugLines; - Optional> DebugRnglists; + Optional>> DebugRnglists; + Optional>> DebugLoclists; bool isEmpty() const; @@ -249,9 +262,17 @@ LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::SegAddrPair) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::AddrTableEntry) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::StringOffsetsTable) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistTable) -LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::Rnglist) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListTable) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListEntries) LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::RnglistEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListTable) +LLVM_YAML_IS_SEQUENCE_VECTOR( + llvm::DWARFYAML::ListEntries) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::LoclistEntry) +LLVM_YAML_IS_SEQUENCE_VECTOR(llvm::DWARFYAML::DWARFOperation) namespace llvm { namespace yaml { @@ -320,18 +341,28 @@ static void mapping(IO &IO, DWARFYAML::SegAddrPair &SegAddrPair); }; -template <> struct MappingTraits { - static void mapping(IO &IO, DWARFYAML::RnglistTable &RnglistTable); +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::DWARFOperation &DWARFOperation); +}; + +template +struct MappingTraits> { + static void mapping(IO &IO, DWARFYAML::ListTable &ListTable); }; -template <> struct MappingTraits { - static void mapping(IO &IO, DWARFYAML::Rnglist &Rnglist); +template +struct MappingTraits> { + static void mapping(IO &IO, DWARFYAML::ListEntries &ListEntries); }; template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::RnglistEntry &RnglistEntry); }; +template <> struct MappingTraits { + static void mapping(IO &IO, DWARFYAML::LoclistEntry &LoclistEntry); +}; + template <> struct MappingTraits { static void mapping(IO &IO, DWARFYAML::AddrTableEntry &AddrTable); }; @@ -428,6 +459,24 @@ } }; +#define HANDLE_DW_LLE(unused, name) \ + io.enumCase(value, "DW_LLE_" #name, dwarf::DW_LLE_##name); + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::LoclistEntries &value) { +#include "llvm/BinaryFormat/Dwarf.def" + } +}; + +#define HANDLE_DW_OP(id, name, version, vendor) \ + io.enumCase(value, "DW_OP_" #name, dwarf::DW_OP_##name); + +template <> struct ScalarEnumerationTraits { + static void enumeration(IO &io, dwarf::LocationAtom &value) { +#include "llvm/BinaryFormat/Dwarf.def" + } +}; + } // end namespace yaml } // end namespace llvm diff --git a/llvm/lib/ObjectYAML/DWARFEmitter.cpp b/llvm/lib/ObjectYAML/DWARFEmitter.cpp --- a/llvm/lib/ObjectYAML/DWARFEmitter.cpp +++ b/llvm/lib/ObjectYAML/DWARFEmitter.cpp @@ -442,8 +442,49 @@ } static Expected -writeRnglistEntry(raw_ostream &OS, const DWARFYAML::RnglistEntry &Entry, - uint8_t AddrSize, bool IsLittleEndian) { +writeDWARFExpression(raw_ostream &OS, + const DWARFYAML::DWARFOperation &Operation, + uint8_t AddrSize, bool IsLittleEndian) { + auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error { + if (Operation.Values.size() != ExpectedOperands) { + return createStringError( + errc::invalid_argument, + "invalid number (%zu) of operands for the operator: %s, %" PRIu64 + " expected", + Operation.Values.size(), + dwarf::OperationEncodingString(Operation.Operator).str().c_str(), + ExpectedOperands); + } + + return Error::success(); + }; + + uint64_t ExpressionBegin = OS.tell(); + writeInteger((uint8_t)Operation.Operator, OS, IsLittleEndian); + switch (Operation.Operator) { + case dwarf::DW_OP_consts: + if (Error Err = CheckOperands(1)) + return std::move(Err); + encodeSLEB128(Operation.Values[0], OS); + break; + case dwarf::DW_OP_stack_value: + if (Error Err = CheckOperands(0)) + return std::move(Err); + break; + default: + return createStringError( + errc::not_supported, + "DWARF expression: " + + dwarf::OperationEncodingString(Operation.Operator) + + " is not supported"); + } + return OS.tell() - ExpressionBegin; +} + +static Expected writeListEntry(raw_ostream &OS, + const DWARFYAML::RnglistEntry &Entry, + uint8_t AddrSize, + bool IsLittleEndian) { uint64_t BeginOffset = OS.tell(); writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian); @@ -515,9 +556,122 @@ return OS.tell() - BeginOffset; } -Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) { - assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call"); - for (const DWARFYAML::RnglistTable &Table : *DI.DebugRnglists) { +static Expected writeListEntry(raw_ostream &OS, + const DWARFYAML::LoclistEntry &Entry, + uint8_t AddrSize, + bool IsLittleEndian) { + uint64_t BeginOffset = OS.tell(); + writeInteger((uint8_t)Entry.Operator, OS, IsLittleEndian); + + auto CheckOperands = [&](uint64_t ExpectedOperands) -> Error { + if (Entry.Values.size() != ExpectedOperands) { + return createStringError( + errc::invalid_argument, + "invalid number (%zu) of operands for the operator: %s, %" PRIu64 + " expected", + Entry.Values.size(), + dwarf::LocListEncodingString(Entry.Operator).str().c_str(), + ExpectedOperands); + } + + return Error::success(); + }; + + auto WriteAddress = [&](uint64_t Addr) -> Error { + if (Error Err = + writeVariableSizedInteger(Addr, AddrSize, OS, IsLittleEndian)) + return createStringError( + errc::not_supported, + "unable to write address for the operator %s: %s", + dwarf::LocListEncodingString(Entry.Operator).str().c_str(), + toString(std::move(Err)).c_str()); + return Error::success(); + }; + + auto WriteDWARFOperations = [&]() -> Error { + std::string OpBuffer; + raw_string_ostream OpBufferOS(OpBuffer); + uint64_t DescriptorLength = 0; + + for (const DWARFYAML::DWARFOperation &Op : Entry.Descriptors) { + if (Expected OpSize = + writeDWARFExpression(OpBufferOS, Op, AddrSize, IsLittleEndian)) + DescriptorLength += *OpSize; + else + return OpSize.takeError(); + } + + if (Entry.DescriptorLength) + DescriptorLength = *Entry.DescriptorLength; + else + DescriptorLength = OpBuffer.size(); + + encodeULEB128(DescriptorLength, OS); + OS.write(OpBuffer.data(), OpBuffer.size()); + + return Error::success(); + }; + + switch (Entry.Operator) { + case dwarf::DW_LLE_end_of_list: + if (Error Err = CheckOperands(0)) + return std::move(Err); + break; + case dwarf::DW_LLE_base_addressx: + if (Error Err = CheckOperands(1)) + return std::move(Err); + encodeULEB128(Entry.Values[0], OS); + break; + case dwarf::DW_LLE_startx_endx: + case dwarf::DW_LLE_startx_length: + case dwarf::DW_LLE_offset_pair: + if (Error Err = CheckOperands(2)) + return std::move(Err); + encodeULEB128(Entry.Values[0], OS); + encodeULEB128(Entry.Values[1], OS); + if (Error Err = WriteDWARFOperations()) + return std::move(Err); + break; + case dwarf::DW_LLE_default_location: + if (Error Err = CheckOperands(0)) + return std::move(Err); + if (Error Err = WriteDWARFOperations()) + return std::move(Err); + break; + case dwarf::DW_LLE_base_address: + if (Error Err = CheckOperands(1)) + return std::move(Err); + if (Error Err = WriteAddress(Entry.Values[0])) + return std::move(Err); + break; + case dwarf::DW_LLE_start_end: + if (Error Err = CheckOperands(2)) + return std::move(Err); + if (Error Err = WriteAddress(Entry.Values[0])) + return std::move(Err); + cantFail(WriteAddress(Entry.Values[1])); + if (Error Err = WriteDWARFOperations()) + return std::move(Err); + break; + case dwarf::DW_LLE_start_length: + if (Error Err = CheckOperands(2)) + return std::move(Err); + if (Error Err = WriteAddress(Entry.Values[0])) + return std::move(Err); + encodeULEB128(Entry.Values[1], OS); + if (Error Err = WriteDWARFOperations()) + return std::move(Err); + break; + } + + return OS.tell() - BeginOffset; +} + +template +Error emitDWARFLists(raw_ostream &OS, + ArrayRef> Tables, + bool IsLittleEndian, bool Is64BitAddrSize) { + for (const DWARFYAML::ListTable &Table : Tables) { // sizeof(version) + sizeof(address_size) + sizeof(segment_selector_size) + // sizeof(offset_entry_count) = 8 uint64_t Length = 8; @@ -526,7 +680,7 @@ if (Table.AddrSize) AddrSize = *Table.AddrSize; else - AddrSize = DI.Is64BitAddrSize ? 8 : 4; + AddrSize = Is64BitAddrSize ? 8 : 4; // Since the length of the current range lists entry is undetermined yet, we // firstly write the content of the range lists to a buffer to calculate the @@ -539,11 +693,11 @@ // range list. std::vector Offsets; - for (const DWARFYAML::Rnglist &List : Table.Lists) { + for (const DWARFYAML::ListEntries &List : Table.Lists) { Offsets.push_back(ListBufferOS.tell()); - for (const DWARFYAML::RnglistEntry &Entry : List.Entries) { + for (const EntryType &Entry : List.Entries) { Expected EntrySize = - writeRnglistEntry(ListBufferOS, Entry, AddrSize, DI.IsLittleEndian); + writeListEntry(ListBufferOS, Entry, AddrSize, IsLittleEndian); if (!EntrySize) return EntrySize.takeError(); Length += *EntrySize; @@ -568,17 +722,17 @@ if (Table.Length) Length = *Table.Length; - writeInitialLength(Table.Format, Length, OS, DI.IsLittleEndian); - writeInteger((uint16_t)Table.Version, OS, DI.IsLittleEndian); - writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian); - writeInteger((uint8_t)Table.SegSelectorSize, OS, DI.IsLittleEndian); - writeInteger((uint32_t)OffsetEntryCount, OS, DI.IsLittleEndian); + writeInitialLength(Table.Format, Length, OS, IsLittleEndian); + writeInteger((uint16_t)Table.Version, OS, IsLittleEndian); + writeInteger((uint8_t)AddrSize, OS, IsLittleEndian); + writeInteger((uint8_t)Table.SegSelectorSize, OS, IsLittleEndian); + writeInteger((uint32_t)OffsetEntryCount, OS, IsLittleEndian); auto EmitOffsets = [&](ArrayRef Offsets, uint64_t OffsetsSize) { for (uint64_t Offset : Offsets) { cantFail(writeVariableSizedInteger( OffsetsSize + Offset, Table.Format == dwarf::DWARF64 ? 8 : 4, OS, - DI.IsLittleEndian)); + IsLittleEndian)); } }; @@ -595,6 +749,18 @@ return Error::success(); } +Error DWARFYAML::emitDebugRnglists(raw_ostream &OS, const Data &DI) { + assert(DI.DebugRnglists && "unexpected emitDebugRnglists() call"); + return emitDWARFLists( + OS, *DI.DebugRnglists, DI.IsLittleEndian, DI.Is64BitAddrSize); +} + +Error DWARFYAML::emitDebugLoclists(raw_ostream &OS, const Data &DI) { + assert(DI.DebugLoclists && "unexpected emitDebugRnglists() call"); + return emitDWARFLists( + OS, *DI.DebugLoclists, DI.IsLittleEndian, DI.Is64BitAddrSize); +} + using EmitFuncType = Error (*)(raw_ostream &, const DWARFYAML::Data &); static Error diff --git a/llvm/lib/ObjectYAML/DWARFYAML.cpp b/llvm/lib/ObjectYAML/DWARFYAML.cpp --- a/llvm/lib/ObjectYAML/DWARFYAML.cpp +++ b/llvm/lib/ObjectYAML/DWARFYAML.cpp @@ -50,6 +50,8 @@ SecNames.insert("debug_str_offsets"); if (DebugRnglists) SecNames.insert("debug_rnglists"); + if (DebugLoclists) + SecNames.insert("debug_loclists"); return SecNames; } @@ -75,6 +77,7 @@ IO.mapOptional("debug_addr", DWARF.DebugAddr); IO.mapOptional("debug_str_offsets", DWARF.DebugStrOffsets); IO.mapOptional("debug_rnglists", DWARF.DebugRnglists); + IO.mapOptional("debug_loclists", DWARF.DebugLoclists); IO.setContext(OldContext); } @@ -236,27 +239,43 @@ IO.mapOptional("Offsets", StrOffsetsTable.Offsets); } +void MappingTraits::mapping( + IO &IO, DWARFYAML::DWARFOperation &DWARFOperation) { + IO.mapRequired("Operator", DWARFOperation.Operator); + IO.mapOptional("Values", DWARFOperation.Values); +} + void MappingTraits::mapping( IO &IO, DWARFYAML::RnglistEntry &RnglistEntry) { IO.mapRequired("Operator", RnglistEntry.Operator); IO.mapOptional("Values", RnglistEntry.Values); } -void MappingTraits::mapping(IO &IO, - DWARFYAML::Rnglist &Rnglist) { - IO.mapOptional("Entries", Rnglist.Entries); +void MappingTraits::mapping( + IO &IO, DWARFYAML::LoclistEntry &LoclistEntry) { + IO.mapRequired("Operator", LoclistEntry.Operator); + IO.mapOptional("Values", LoclistEntry.Values); + IO.mapOptional("DescriptorsLength", LoclistEntry.DescriptorLength); + IO.mapOptional("Descriptors", LoclistEntry.Descriptors); +} + +template +void MappingTraits>::mapping( + IO &IO, DWARFYAML::ListEntries &ListEntries) { + IO.mapOptional("Entries", ListEntries.Entries); } -void MappingTraits::mapping( - IO &IO, DWARFYAML::RnglistTable &RnglistTable) { - IO.mapOptional("Format", RnglistTable.Format, dwarf::DWARF32); - IO.mapOptional("Length", RnglistTable.Length); - IO.mapOptional("Version", RnglistTable.Version, 5); - IO.mapOptional("AddressSize", RnglistTable.AddrSize); - IO.mapOptional("SegmentSelectorSize", RnglistTable.SegSelectorSize, 0); - IO.mapOptional("OffsetEntryCount", RnglistTable.OffsetEntryCount); - IO.mapOptional("Offsets", RnglistTable.Offsets); - IO.mapOptional("Lists", RnglistTable.Lists); +template +void MappingTraits>::mapping( + IO &IO, DWARFYAML::ListTable &ListTable) { + IO.mapOptional("Format", ListTable.Format, dwarf::DWARF32); + IO.mapOptional("Length", ListTable.Length); + IO.mapOptional("Version", ListTable.Version, 5); + IO.mapOptional("AddressSize", ListTable.AddrSize); + IO.mapOptional("SegmentSelectorSize", ListTable.SegSelectorSize, 0); + IO.mapOptional("OffsetEntryCount", ListTable.OffsetEntryCount); + IO.mapOptional("Offsets", ListTable.Offsets); + IO.mapOptional("Lists", ListTable.Lists); } void MappingTraits::mapping( diff --git a/llvm/lib/ObjectYAML/ELFEmitter.cpp b/llvm/lib/ObjectYAML/ELFEmitter.cpp --- a/llvm/lib/ObjectYAML/ELFEmitter.cpp +++ b/llvm/lib/ObjectYAML/ELFEmitter.cpp @@ -978,6 +978,8 @@ Err = DWARFYAML::emitDebugStrOffsets(*OS, DWARF); else if (Name == ".debug_rnglists") Err = DWARFYAML::emitDebugRnglists(*OS, DWARF); + else if (Name == ".debug_loclists") + Err = DWARFYAML::emitDebugLoclists(*OS, DWARF); else llvm_unreachable("unexpected emitDWARF() call"); diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-loclists.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-loclists.yaml new file mode 100644 --- /dev/null +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-loclists.yaml @@ -0,0 +1,800 @@ +## Test that yaml2obj emits a .debug_loclists section when requested. + +## a) Generate and verify a little endian DWARF32 .debug_loclists section in a 64-bit object file. + +# RUN: yaml2obj --docnum=1 -DENDIAN=ELFDATA2LSB %s -o %t1.dwarf32.le.o +# RUN: llvm-readobj --sections --section-data %t1.dwarf32.le.o | \ +# RUN: FileCheck -DSIZE=133 -DADDRALIGN=1 %s --check-prefixes=SHDR,DWARF32-LE + +# SHDR: Index: 1 +# SHDR-NEXT: Name: .debug_loclists (1) +# SHDR-NEXT: Type: SHT_PROGBITS (0x1) +# SHDR-NEXT: Flags [ (0x0) +# SHDR-NEXT: ] +# SHDR-NEXT: Address: 0x0 +# SHDR-NEXT: Offset: 0x40 +# SHDR-NEXT: Size: [[SIZE]] +# SHDR-NEXT: Link: 0 +# SHDR-NEXT: Info: 0 +# SHDR-NEXT: AddressAlignment: [[ADDRALIGN]] +# SHDR-NEXT: EntrySize: 0 +# DWARF32-LE-NEXT: SectionData ( +# DWARF32-LE-NEXT: 0000: 3D000000 05000800 03000000 0C000000 |=...............| +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- offset_entry_count (4-byte) +## ^------- offsets[0] (4-byte) +# DWARF32-LE-NEXT: 0010: 1B000000 2F000000 01B42402 B424A186 |..../.....$..$..| +## ^------- offsets[1] (4-byte) +## ^------- offsets[2] (4-byte) +## ^- DW_LLE_base_addressx +## ^--- operands[0] (ULEB128) 0x1234 +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^--- operands[1] (ULEB128) 0x4321 +# DWARF32-LE-NEXT: 0020: 010411B4 249F0003 B424A186 0102117D |....$....$.....}| +## -- +## ^- location descriptors length (ULEB128) 0x04 +## ^- DW_OP_consts +## ^---- operands[0] (SLEB128) +0x1234 +## ^- DW_OP_stack_value +## ^- DW_LLE_end_of_list +## ^- DW_LLE_startx_length +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x02 +## ^- DW_OP_consts +## ^- operands[0] (SLEB128) -0x03 +# DWARF32-LE-NEXT: 0030: 04B424A1 86010311 B4240005 0311B424 |..$......$.....$| +## ^- DW_LLE_offset_pair +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +## ^- DW_LLE_default_location +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +# DWARF32-LE-NEXT: 0040: 00400000 00050008 00020000 00080000 |.@..............| +## ^- DW_LLE_end_of_list +## ^-------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^-------- offset_entry_count (4-byte) +## ^----- offsets[0] (4-byte) +# DWARF32-LE-NEXT: 0050: 00270000 00063412 00000000 00000734 |.'....4........4| +## -- +## ^-------- offsets[1] (4-byte) +## ^- DW_LLE_base_address +## ^----------------- operands[0] (8-byte) +## ^- DW_LLE_start_end +## ^- operands[0] (8-byte) +# DWARF32-LE-NEXT: 0060: 12000000 00000021 43000000 00000003 |.......!C.......| +## --------------- +## ^----------------- operands[1] (8-byte) +## ^- location descriptors length (ULEB128) 0x03 +# DWARF32-LE-NEXT: 0070: 11B42400 08341200 00000000 00A18601 |..$..4..........| +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +## ^- DW_LLE_start_length +## ^----------------- operands[0] (8-byte) +## ^----- operands[1] (LEB128) 0x4321 +# DWARF32-LE-NEXT: 0080: 0311B424 00 |...$.| +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +# DWARF32-LE-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: [[ENDIAN]] + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_base_addressx + Values: [ 0x1234 ] + - Operator: DW_LLE_startx_endx + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Operator: DW_OP_stack_value + - Operator: DW_LLE_end_of_list + - Entries: + - Operator: DW_LLE_startx_length + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + ## Test a negative number (-3). + Values: [ 0xfffffffffffffffd ] + - Operator: DW_LLE_offset_pair + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Operator: DW_LLE_end_of_list + - Entries: + - Operator: DW_LLE_default_location + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Operator: DW_LLE_end_of_list + - Lists: + - Entries: + - Operator: DW_LLE_base_address + Values: [ 0x1234 ] + - Operator: DW_LLE_start_end + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Operator: DW_LLE_end_of_list + - Entries: + - Operator: DW_LLE_start_length + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Operator: DW_LLE_end_of_list + +## b) Generate and verify a big endian DWARF32 .debug_loclists section in a 64-bit object file. + +# RUN: yaml2obj --docnum=1 -DENDIAN=ELFDATA2MSB %s -o %t.dwarf32.be.o +# RUN: llvm-readobj --sections --section-data %t.dwarf32.be.o | \ +# RUN: FileCheck -DSIZE=133 -DADDRALIGN=1 %s --check-prefixes=SHDR,DWARF32-BE + +# DWARF32-BE-NEXT: SectionData ( +# DWARF32-BE-NEXT: 0000: 0000003D 00050800 00000003 0000000C |...=............| +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- offset_entry_count (4-byte) +## ^------- offsets[0] (4-byte) +# DWARF32-BE-NEXT: 0010: 0000001B 0000002F 01B42402 B424A186 |......./..$..$..| +## ^------- offsets[1] (4-byte) +## ^------- offsets[2] (4-byte) +## ^- DW_LLE_base_addressx +## ^--- operands[0] (ULEB128) 0x1234 +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^--- operands[1] (ULEB128) 0x4321 +# DWARF32-BE-NEXT: 0020: 010411B4 249F0003 B424A186 0102117D |....$....$.....}| +## -- +## ^- location descriptors length (ULEB128) 0x04 +## ^- DW_OP_consts +## ^---- operands[0] (SLEB128) +0x1234 +## ^- DW_OP_stack_value +## ^- DW_LLE_end_of_list +## ^- DW_LLE_startx_length +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x02 +## ^- DW_OP_consts +## ^- operands[0] (SLEB128) -0x03 +# DWARF32-BE-NEXT: 0030: 04B424A1 86010311 B4240005 0311B424 |..$......$.....$| +## ^- DW_LLE_offset_pair +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +## ^- DW_LLE_default_location +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +# DWARF32-BE-NEXT: 0040: 00000000 40000508 00000000 02000000 |....@...........| +## ^- DW_LLE_end_of_list +## ^-------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^-------- offset_entry_count (4-byte) +## ^----- offsets[0] (4-byte) +# DWARF32-BE-NEXT: 0050: 08000000 27060000 00000000 12340700 |....'........4..| +## -- +## ^-------- offsets[1] (4-byte) +## ^- DW_LLE_base_address +## ^----------------- operands[0] (8-byte) +## ^- DW_LLE_start_end +## ^- operands[0] (8-byte) +# DWARF32-BE-NEXT: 0060: 00000000 00123400 00000000 00432103 |......4......C!.| +## --------------- +## ^----------------- operands[1] (8-byte) +## ^- location descriptors length (ULEB128) 0x03 +# DWARF32-BE-NEXT: 0070: 11B42400 08000000 00000012 34A18601 |..$.........4...| +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +## ^- DW_LLE_start_length +## ^----------------- operands[0] (8-byte) +## ^----- operands[1] (LEB128) 0x4321 +# DWARF32-BE-NEXT: 0080: 0311B424 00 |...$.| +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +# DWARF32-BE-NEXT: ) + +## c) Generate and verify a little endian DWARF64 .debug_loclists section in a 64-bit object file. + +# RUN: yaml2obj --docnum=2 -DENDIAN=ELFDATA2LSB %s -o %t2.dwarf64.le.o +# RUN: llvm-readobj --sections --section-data %t2.dwarf64.le.o | \ +# RUN: FileCheck -DSIZE=47 -DADDRALIGN=1 %s --check-prefixes=SHDR,DWARF64-LE + +# DWARF64-LE-NEXT: SectionData ( +# DWARF64-LE-NEXT: 0000: FFFFFFFF 23000000 00000000 05000800 |....#...........| +## ^------------------------- unit_length (12-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +# DWARF64-LE-NEXT: 0010: 02000000 10000000 00000000 1A000000 |................| +## ^------- offset_entry_count (4-byte) +## ^---------------- offsets[0] (8-byte) +## ^------- offsets[1] (8-byte) +# DWARF64-LE-NEXT: 0020: 00000000 02B424A1 86010311 B42400 |......$......$.| +## -------- +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +# DWARF64-LE-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: [[ENDIAN]] + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Format: DWARF64 + Lists: + - Entries: + - Operator: DW_LLE_startx_endx + Values: [ 0x1234, 0x4321 ] + Descriptors: + - Operator: DW_OP_consts + Values: [ 0x1234 ] + - Entries: + - Operator: DW_LLE_end_of_list + +## d) Generate and verify a big endian DWARF64 .debug_loclists section in a 64-bit object file. + +# RUN: yaml2obj --docnum=2 -DENDIAN=ELFDATA2MSB %s -o %t2.dwarf64.be.o +# RUN: llvm-readobj --sections --section-data %t2.dwarf64.be.o | \ +# RUN: FileCheck -DSIZE=47 -DADDRALIGN=1 %s --check-prefixes=SHDR,DWARF64-BE + +# DWARF64-BE-NEXT: SectionData ( +# DWARF64-BE-NEXT: 0000: FFFFFFFF 00000000 00000023 00050800 |...........#....| +## ^------------------------- unit_length (12-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +# DWARF64-BE-NEXT: 0010: 00000002 00000000 00000010 00000000 |................| +## ^------- offset_entry_count (4-byte) +## ^---------------- offsets[0] (8-byte) +## ^------- offsets[1] (8-byte) +# DWARF64-BE-NEXT: 0020: 0000001A 02B424A1 86010311 B42400 |......$......$.| +## -------- +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x03 +## ^- DW_OP_consts +## ^--- operands[0] (SLEB128) +0x1234 +## ^- DW_LLE_end_of_list +# DWARF64-BE-NEXT: ) + +## e) Test that the length, version, segment_selector_size, address_size, offset_entry_count, +## offsets and location descriptors length fields can be specified manually. + +# RUN: yaml2obj --docnum=3 %s -o %t3.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t3.o | \ +# RUN: FileCheck %s --check-prefix=OVERWRITE + +# OVERWRITE: Hex dump of section '.debug_loclists': +# OVERWRITE-NEXT: 0x00000000 34120000 06000303 04000000 01000000 4............... +## ^------- unit_length (4-byte) 0x1234 +## ^--- version (2-byte) 0x06 +## ^- address_size (1-byte) 0x03 +## ^- segment_selector_size (1-byte) 0x03 +## ^------- offset_entry_count (4-byte) 0x04 +## ^------- offsets[0] (4-byte) 0x01 +# OVERWRITE-NEXT: 0x00000010 02b424a1 8601a186 019f00 ..$........ +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^------ location descriptors length (ULEB128) 0x4321 +## ^- DW_OP_stack_value +## ^- DW_LLE_end_of_list + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Length: 0x1234 + Version: 6 + AddressSize: 3 + SegmentSelectorSize: 3 + OffsetEntryCount: 4 + Offsets: [ 0x01 ] + Lists: + - Entries: + - Operator: DW_LLE_startx_endx + Values: [ 0x1234, 0x4321 ] + DescriptorsLength: 0x4321 + Descriptors: + - Operator: DW_OP_stack_value + - Entries: + - Operator: DW_LLE_end_of_list + +## f) Test that location descriptors can be omitted in the YAML description. + +# RUN: yaml2obj --docnum=4 %s -o %t4.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t4.o | \ +# RUN: FileCheck %s --check-prefix=OMIT-DESCRIPTORS + +# OMIT-DESCRIPTORS: Hex dump of section '.debug_loclists': +# OMIT-DESCRIPTORS-NEXT: 0x00000000 42000000 05000800 01000000 04000000 B............... +# OMIT-DESCRIPTORS-NEXT: 0x00000010 02b424a1 86010003 b424a186 010004b4 ..$......$...... +## ^- DW_LLE_startx_endx +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x00 +## ^- DW_LLE_startx_length +## ^--- operands[0] (ULEB128) 0x1234 +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x00 +## ^- DW_LLE_offset_pair +## ^- operands[0] (ULEB128) 0x1234 +# OMIT-DESCRIPTORS-NEXT: 0x00000020 24a18601 00050007 34120000 00000000 $.......4....... +## -- +## ^----- operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x00 +## ^- DW_LLE_default_location +## ^- location descriptors length (ULEB128) 0x00 +## ^- DW_LLE_start_end +## ^---------------- operands[0] (8-byte) +# OMIT-DESCRIPTORS-NEXT: 0x00000030 21430000 00000000 00083412 00000000 !C........4..... +## ^---------------- operands[1] (8-byte) +## ^- location descriptors length (ULEB128) 0x00 +## ^- DW_LLE_start_length +## ^------------ operands[0] (8-byte) +# OMIT-DESCRIPTORS-NEXT: 0x00000040 0000a186 0100 ...... +## ---- +## ^------ operands[1] (ULEB128) 0x4321 +## ^- location descriptors length (ULEB128) 0x00 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_startx_endx + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_startx_length + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_offset_pair + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_default_location + - Operator: DW_LLE_start_end + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_start_length + Values: [ 0x1234, 0x4321 ] + +## g) Test that the default value of the address_size field in a 32-bit object file is 4. + +# RUN: yaml2obj --docnum=5 %s -o %t5.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t5.o | \ +# RUN: FileCheck %s --check-prefix=ADDRSIZE32 + +# ADDRSIZE32: Hex dump of section '.debug_loclists': +# ADDRSIZE32-NEXT: 0x00000000 24000000 05000400 01000000 04000000 $............... +## ^- address_size (1-byte) 0x04 +# ADDRSIZE32-NEXT: 0x00000010 06341200 00073412 00002143 00000008 .4....4...!C.... +## ^- DW_LLE_base_address +## ^-------- operands[0] (4-byte) +## ^- DW_LLE_start_end +## ^-------- operands[0] (4-byte) +## ^-------- operands[1] (4-byte) +## ^- DW_LLE_start_length +# ADDRSIZE32-NEXT: 0x00000020 34120000 a1860100 4....... +## ^------- operands[0] (4-byte) +## ^----- operands[1] (ULEB128) 0x4321 + +--- !ELF +FileHeader: + Class: ELFCLASS32 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_base_address + Values: [ 0x1234 ] + - Operator: DW_LLE_start_end + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_start_length + Values: [ 0x1234, 0x4321 ] + +## h) Test that the address_size field can be specified manually and the size of +## corresponding operands will be changed accordingly. + +# RUN: yaml2obj --docnum=6 %s -o %t6.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t6.o | \ +# RUN: FileCheck %s --check-prefix=ADDRSIZE32 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - AddressSize: 4 + Lists: + - Entries: + - Operator: DW_LLE_base_address + Values: [ 0x1234 ] + - Operator: DW_LLE_start_end + Values: [ 0x1234, 0x4321 ] + - Operator: DW_LLE_start_length + Values: [ 0x1234, 0x4321 ] + +## i) Test that yaml2obj emits an error message if we try to assign an invalid value to +## 'AddressSize' when there is an entry whose operands contain address. + +# RUN: not yaml2obj -DOPERATOR=base_address -DVALUES=[0x01] --docnum=7 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=base_address %s --check-prefix=INVALID-ADDRSIZE + +# RUN: not yaml2obj -DOPERATOR=start_end -DVALUES=[0x01,0x02] --docnum=7 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=start_end %s --check-prefix=INVALID-ADDRSIZE + +# RUN: not yaml2obj -DOPERATOR=start_length -DVALUES=[0x01,0x02] --docnum=7 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=start_length %s --check-prefix=INVALID-ADDRSIZE + +# INVALID-ADDRSIZE: yaml2obj: error: unable to write address for the operator DW_LLE_[[OPERATOR]]: invalid integer write size: 3 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - AddressSize: 3 + Lists: + - Entries: + - Operator: DW_LLE_[[OPERATOR]] + Values: [[VALUES]] + +## j) Test that an invalid address_size can be used when there are no address-using operators. + +# RUN: yaml2obj --docnum=8 %s -o %t8.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t8.o | \ +# RUN: FileCheck %s --check-prefix=ADDRSIZE-NOERROR + +# ADDRSIZE-NOERROR: Hex dump of section '.debug_loclists': +# ADDRSIZE-NOERROR-NEXT: 0x00000000 0e000000 05000300 01000000 04000000 ................ +## ^- address_size (1-byte) 0x03 +# ADDRSIZE-NOERROR-NEXT: 0x00000010 0101 .. + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - AddressSize: 3 + Lists: + - Entries: + - Operator: DW_LLE_base_addressx + Values: [ 0x01 ] + +## k) Test that yaml2obj emits an error message if we specify invalid numbers of operands +## for a location list encoding. + +# RUN: not yaml2obj -DOPERATOR=end_of_list -DVALUES=[0x01] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=end_of_list -DACTUAL=1 -DEXPECTED=0 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=base_addressx -DVALUES=[] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=base_addressx -DACTUAL=0 -DEXPECTED=1 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=startx_endx -DVALUES=[0x01] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=startx_endx -DACTUAL=1 -DEXPECTED=2 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=startx_length -DVALUES=[0x01] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=startx_length -DACTUAL=1 -DEXPECTED=2 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=offset_pair -DVALUES=[] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=offset_pair -DACTUAL=0 -DEXPECTED=2 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=default_location -DVALUES=[0x01] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=default_location -DACTUAL=1 -DEXPECTED=0 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=base_address -DVALUES=[0x01,0x02] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=base_address -DACTUAL=2 -DEXPECTED=1 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=start_end -DVALUES=[0x01,0x02,0x03] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=start_end -DACTUAL=3 -DEXPECTED=2 %s --check-prefix=INVALID-LLE-OPERANDS + +# RUN: not yaml2obj -DOPERATOR=start_length -DVALUES=[0x01] --docnum=9 %s 2>&1 | \ +# RUN: FileCheck -DOPERATOR=start_length -DACTUAL=1 -DEXPECTED=2 %s --check-prefix=INVALID-LLE-OPERANDS + +# INVALID-LLE-OPERANDS: yaml2obj: error: invalid number ([[ACTUAL]]) of operands for the operator: DW_LLE_[[OPERATOR]], [[EXPECTED]] expected + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_[[OPERATOR]] + Values: [[VALUES]] + +## l) Test that yaml2obj emits an error message if we specify invalid numbers of operands +## for a DWARF expression operator. + +# RUN: not yaml2obj --docnum=10 -DOPERATOR=consts -DVALUES=[0x01,0x02] %s 2>&1 | \ +# RUN: FileCheck -DACTUAL=2 -DEXPECTED=1 -DOPERATOR=consts %s --check-prefix=INVALID-OP-OPERANDS + +# RUN: not yaml2obj --docnum=10 -DOPERATOR=stack_value -DVALUES=[0x01] %s 2>&1 | \ +# RUN: FileCheck -DACTUAL=1 -DEXPECTED=0 -DOPERATOR=stack_value %s --check-prefix=INVALID-OP-OPERANDS + +# INVALID-OP-OPERANDS: yaml2obj: error: invalid number ([[ACTUAL]]) of operands for the operator: DW_OP_[[OPERATOR]], [[EXPECTED]] expected + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_startx_endx + Values: [ 0x01, 0x02 ] + Descriptors: + - Operator: DW_OP_[[OPERATOR]] + Values: [[VALUES]] + +## m) Test that an empty list is allowed for a location list table. + +# RUN: yaml2obj --docnum=11 %s -o %t11.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t11.o | \ +# RUN: FileCheck %s --check-prefix=EMPTY-LIST + +# EMPTY-LIST: Hex dump of section '.debug_loclists': +# EMPTY-LIST-NEXT: 0x00000000 08000000 05000800 00000000 ............ +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- offset_entry_count (4-byte) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: [] + +## n) Generate the .debug_loclists section from raw section content. + +# RUN: yaml2obj --docnum=12 %s -o %t12.o +# RUN: llvm-readobj --sections --section-data %t12.o | \ +# RUN: FileCheck %s -DSIZE=3 -DADDRALIGN=0 --check-prefixes=SHDR,ARBITRARY-CONTENT + +# ARBITRARY-CONTENT: SectionData ( +# ARBITRARY-CONTENT-NEXT: 0000: 112233 +# ARBITRARY-CONTENT-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_PROGBITS + Content: "112233" + +## o) Generate the .debug_loclists section when the "Size" is specified. + +# RUN: yaml2obj --docnum=13 %s -o %t13.o +# RUN: llvm-readelf --hex-dump=.debug_loclists %t13.o | \ +# RUN: FileCheck %s --check-prefix=SIZE + +# SIZE: Hex dump of section '.debug_loclists': +# SIZE-NEXT: 0x00000000 00000000 00000000 00000000 00000000 ................ +# SIZE-EMPTY: + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_PROGBITS + Size: 0x10 + +## p) Test that yaml2obj emits an error message when both the "Size" and the +## "debug_loclists" entry are specified at the same time. + +# RUN: not yaml2obj --docnum=14 %s 2>&1 | FileCheck %s --check-prefix=ERROR + +# ERROR: yaml2obj: error: cannot specify section '.debug_loclists' contents in the 'DWARF' entry and the 'Content' or 'Size' in the 'Sections' entry at the same time + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_PROGBITS + Size: 0x10 +DWARF: + debug_loclists: + - Lists: [] + +## q) Test that yaml2obj emits an error message when both the "Content" and the +## "debug_loclists" entry are specified at the same time. + +# RUN: not yaml2obj --docnum=15 %s 2>&1 | FileCheck %s --check-prefix=ERROR + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_PROGBITS + Content: "00" +DWARF: + debug_loclists: + - Lists: [] + +## r) Test that all the properties can be overridden by the section header when +## the "debug_loclists" entry doesn't exist. + +# RUN: yaml2obj --docnum=16 %s -o %t16.o +# RUN: llvm-readelf --sections %t16.o | FileCheck %s --check-prefix=OVERRIDDEN + +# OVERRIDDEN: [Nr] Name Type Address Off Size ES Flg Lk Inf Al +# OVERRIDDEN: [ 1] .debug_loclists STRTAB 0000000000002020 000050 00000c 01 A 2 1 2 +# OVERRIDDEN-NEXT: [ 2] .sec STRTAB 0000000000000000 00005c 000000 00 0 0 0 + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_STRTAB ## SHT_PROGBITS by default. + Flags: [SHF_ALLOC] ## 0 by default. + Link: .sec ## 0 by default. + EntSize: 1 ## 0 by default. + Info: 1 ## 0 by default. + AddressAlign: 2 ## 0 by default. + Address: 0x2020 ## 0x00 by default. + Offset: 0x50 ## 0x40 for the first section. + Size: 0x0c ## Set the "Size" so that we can reuse the check tag "OVERRIDDEN". + - Name: .sec ## Linked by .debug_rnglists. + Type: SHT_STRTAB + +## s) Test that all the properties can be overridden by the section header when +## the "debug_loclists" entry exists. + +# RUN: yaml2obj --docnum=17 %s -o %t17.o +# RUN: llvm-readelf --sections %t17.o | FileCheck %s --check-prefix=OVERRIDDEN + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +Sections: + - Name: .debug_loclists + Type: SHT_STRTAB ## SHT_PROGBITS by default. + Flags: [SHF_ALLOC] ## 0 by default. + Link: .sec ## 0 by default. + EntSize: 1 ## 0 by default. + Info: 1 ## 0 by default. + AddressAlign: 2 ## 1 by default. + Address: 0x2020 ## 0x00 by default. + Offset: 0x50 ## 0x40 for the first section. + - Name: .sec ## Linked by .debug_rnglists. + Type: SHT_STRTAB +DWARF: + debug_loclists: + - Lists: [] + +## t) Test that the .debug_loclists section header is emitted if the "debug_loclists" +## entry is empty. + +# RUN: yaml2obj --docnum=18 %s -o %t18.o +# RUN: llvm-readobj --sections --section-data %t18.o | \ +# RUN: FileCheck -DSIZE=0 -DADDRALIGN=1 %s --check-prefixes=SHDR,EMPTY-CONTENT + +# EMPTY-CONTENT-NEXT: SectionData ( +# EMPTY-CONTENT-NEXT: ) + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: [] + +## u) Test that yaml2obj emits an error message if we use an unimplemented DWARF expression +## operator. + +# RUN: not yaml2obj --docnum=19 %s -o %t19.o 2>&1 | \ +# RUN: FileCheck %s --check-prefix=UNIMPLEMENTED-OP + +# UNIMPLEMENTED-OP: yaml2obj: error: DWARF expression: DW_OP_reg0 is not supported + +--- !ELF +FileHeader: + Class: ELFCLASS64 + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_loclists: + - Lists: + - Entries: + - Operator: DW_LLE_default_location + Descriptors: + - Operator: DW_OP_reg0