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 @@ -66,7 +66,7 @@ struct ARange { dwarf::DwarfFormat Format; - yaml::Hex64 Length; + Optional Length; uint16_t Version; yaml::Hex64 CuOffset; Optional AddrSize; 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 @@ -126,23 +126,36 @@ Error DWARFYAML::emitDebugAranges(raw_ostream &OS, const DWARFYAML::Data &DI) { for (auto Range : DI.ARanges) { - auto HeaderStart = OS.tell(); - uint8_t AddrSize; if (Range.AddrSize) AddrSize = *Range.AddrSize; else AddrSize = DI.Is64BitAddrSize ? 8 : 4; - writeInitialLength(Range.Format, Range.Length, OS, DI.IsLittleEndian); + uint64_t Length = 4; // sizeof(version) 2 + sizeof(address_size) 1 + + // sizeof(segment_selector_size) 1 + Length += + Range.Format == dwarf::DWARF64 ? 8 : 4; // sizeof(debug_info_offset) + + const uint64_t HeaderLength = + Length + (Range.Format == dwarf::DWARF64 + ? 12 + : 4); // sizeof(unit_header) = 12 (DWARF64) or 4 (DWARF32) + const uint64_t PaddedHeaderLength = alignTo(HeaderLength, AddrSize * 2); + + if (Range.Length) { + Length = *Range.Length; + } else { + Length += PaddedHeaderLength - HeaderLength; + Length += AddrSize * 2 * (Range.Descriptors.size() + 1); + } + + writeInitialLength(Range.Format, Length, OS, DI.IsLittleEndian); writeInteger((uint16_t)Range.Version, OS, DI.IsLittleEndian); writeDWARFOffset(Range.CuOffset, Range.Format, OS, DI.IsLittleEndian); writeInteger((uint8_t)AddrSize, OS, DI.IsLittleEndian); writeInteger((uint8_t)Range.SegSize, OS, DI.IsLittleEndian); - - auto HeaderSize = OS.tell() - HeaderStart; - auto FirstDescriptor = alignTo(HeaderSize, AddrSize * 2); - ZeroFillBytes(OS, FirstDescriptor - HeaderSize); + ZeroFillBytes(OS, PaddedHeaderLength - HeaderLength); for (auto Descriptor : Range.Descriptors) { if (Error Err = writeVariableSizedInteger(Descriptor.Address, AddrSize, 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 @@ -103,7 +103,7 @@ void MappingTraits::mapping(IO &IO, DWARFYAML::ARange &ARange) { IO.mapOptional("Format", ARange.Format, dwarf::DWARF32); - IO.mapRequired("Length", ARange.Length); + IO.mapOptional("Length", ARange.Length); IO.mapRequired("Version", ARange.Version); IO.mapRequired("CuOffset", ARange.CuOffset); IO.mapOptional("AddressSize", ARange.AddrSize); diff --git a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-aranges.yaml b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-aranges.yaml --- a/llvm/test/tools/yaml2obj/ELF/DWARF/debug-aranges.yaml +++ b/llvm/test/tools/yaml2obj/ELF/DWARF/debug-aranges.yaml @@ -510,3 +510,88 @@ Descriptors: - Address: 0x1234 Length: 0x1000 + +## k) Test that yaml2obj is able to determine the correct length for the address range table +## if the 'Length' field isn't specified. + +# RUN: yaml2obj --docnum=11 -DCLASS=ELFCLASS64 -DADDRSIZE=4 %s -o %t11.64-bit.o +# RUN: llvm-readelf --hex-dump=.debug_aranges %t11.64-bit.o | \ +# RUN: FileCheck %s --check-prefix=LENGTH64 + +# LENGTH64: Hex dump of section '.debug_aranges': +# LENGTH64-NEXT: 0x00000000 2c000000 02000000 00000800 00000000 ,............... +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_info_offset (4-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- padding (4-byte) +# LENGTH64-NEXT: 0x00000010 34120000 00000000 00100000 00000000 4............... +## ^---------------- address (8-byte) +## ^---------------- length (8-byte) +# LENGTH64-NEXT: 0x00000020 00000000 00000000 00000000 00000000 ................ +## ^---------------------------------- terminating entry (16-byte) +# LENGTH64-NEXT: 0x00000030 ffffffff 1c000000 00000000 02000000 ................ +## ^------------------------- unit_length (12-byte) +## ^--- version (2-byte) +## ^--- debug_info_offset (8-byte) +# LENGTH64-NEXT: 0x00000040 00000000 00000400 34120000 21430000 ........4...!C.. +## ------------- +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- address (4-byte) +## ^------- length (4-byte) +# LENGTH64-NEXT: 0x00000050 00000000 00000000 ........ +## ^---------------- terminating entry (8-byte) + +# RUN: yaml2obj --docnum=11 -DCLASS=ELFCLASS32 -DADDRSIZE=8 %s -o %t11.32-bit.o +# RUN: llvm-readelf --hex-dump=.debug_aranges %t11.32-bit.o | \ +# RUN: FileCheck %s --check-prefix=LENGTH32 + +# LENGTH32: Hex dump of section '.debug_aranges': +# LENGTH32-NEXT: 0x00000000 1c000000 02000000 00000400 00000000 ................ +## ^------- unit_length (4-byte) +## ^--- version (2-byte) +## ^-------- debug_info_offset (4-byte) +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^------- padding (4-byte) +# LENGTH32-NEXT: 0x00000010 34120000 00100000 00000000 00000000 4............... +## ^------- address (4-byte) +## ^------- length (4-byte) +## ^---------------- terminating entry (8-byte) +# LENGTH32-NEXT: 0x00000020 ffffffff 34000000 00000000 02000000 ....4........... +## ^------------------------- unit_length (12-byte) +## ^--- version (2-byte) +## ^--- debug_info_offset (8-byte) +# LENGTH32-NEXT: 0x00000030 00000000 00000800 00000000 00000000 ................ +## ------------- +## ^- address_size (1-byte) +## ^- segment_selector_size (1-byte) +## ^---------------- padding (8-byte) +# LENGTH32-NEXT: 0x00000040 34120000 00000000 21430000 00000000 4.......!C...... +## ^---------------- address (8-byte) +## ^---------------- length (8-byte) +# LENGTH32-NEXT: 0x00000050 00000000 00000000 00000000 00000000 ................ +## ^---------------------------------- terminating entry (16-byte) + +--- !ELF +FileHeader: + Class: [[CLASS]] + Data: ELFDATA2LSB + Type: ET_EXEC + Machine: EM_X86_64 +DWARF: + debug_aranges: + - Version: 2 + CuOffset: 0 + Descriptors: + - Address: 0x1234 + Length: 0x1000 + - Format: DWARF64 + Version: 2 + AddressSize: [[ADDRSIZE]] + CuOffset: 0 + Descriptors: + - Address: 0x1234 + Length: 0x4321