1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[DWARFYAML] Make the 'Length' field of the address range table optional.

This patch makes the 'Length' field of the address range table optional.

Reviewed By: jhenderson

Differential Revision: https://reviews.llvm.org/D84911
This commit is contained in:
Xing GUO 2020-07-30 17:42:18 +08:00
parent 495386e223
commit 75e53e4e5b
4 changed files with 107 additions and 9 deletions

View File

@ -66,7 +66,7 @@ struct ARangeDescriptor {
struct ARange {
dwarf::DwarfFormat Format;
yaml::Hex64 Length;
Optional<yaml::Hex64> Length;
uint16_t Version;
yaml::Hex64 CuOffset;
Optional<yaml::Hex8> AddrSize;

View File

@ -126,23 +126,36 @@ Error DWARFYAML::emitDebugAbbrev(raw_ostream &OS, const DWARFYAML::Data &DI) {
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,

View File

@ -103,7 +103,7 @@ void MappingTraits<DWARFYAML::ARangeDescriptor>::mapping(
void MappingTraits<DWARFYAML::ARange>::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);

View File

@ -510,3 +510,88 @@ DWARF:
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