[llvm-dwp] Fix endianness issues (#203424)

llvm-dwp fails on SystemZ, which is big-endian, as follows:

    $ cat min.c
    int main() {}
    $ clang -g -O0 -gsplit-dwarf min.c -o min
    $ llvm-dwp -e min -o min.dwp
error: compile unit exceeds .debug_info section range: 905969668 >= 58

This is because it hardcodes IsLittleEndian=true in multiple places. Fix
by forwarding endianness of the current object file.

Add a SystemZ-specific test.

Add proper big-endian support to X86/compress.test and add an
explanation regarding what the hardcoded blobs are and how they are
generated.
This commit is contained in:
Ilya Leoshkevich 2026-07-16 22:11:24 +02:00 committed by GitHub
parent b74a97cae9
commit 5b46dcf593
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 329 additions and 36 deletions

View file

@ -102,6 +102,7 @@ class LLVM_ABI DWPWriter {
uint16_t ELFMachine = 0;
uint8_t ELFOSABI = 0;
bool IsWASM = false;
bool IsLittleEndian = true;
public:
DWPWriter() = default;
@ -109,6 +110,7 @@ public:
void setMachine(uint16_t Machine) { ELFMachine = Machine; }
void setOSABI(uint8_t OSABI) { ELFOSABI = OSABI; }
void setIsWASM(bool V) { IsWASM = V; }
void setIsLittleEndian(bool V) { IsLittleEndian = V; }
SmallVectorImpl<char> &getSectionBuffer(DWPSectionId Id) {
return Sections[Id].Buffer;
@ -128,9 +130,16 @@ public:
void emitIntValue(uint64_t Value, unsigned Size) {
auto &Buf = Sections[CurrentSection].Buffer;
for (unsigned I = 0; I < Size; ++I) {
Buf.push_back(static_cast<char>(Value & 0xff));
Value >>= 8;
if (IsLittleEndian) {
for (unsigned I = 0; I < Size; ++I) {
Buf.push_back(static_cast<char>(Value & 0xff));
Value >>= 8;
}
} else {
for (unsigned I = 0; I < Size; ++I) {
Buf.push_back(
static_cast<char>((Value >> (8 * (Size - 1 - I))) & 0xff));
}
}
}
@ -216,7 +225,7 @@ LLVM_ABI Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
typedef std::vector<std::pair<DWARFSectionKind, uint32_t>> SectionLengths;
LLVM_ABI Expected<InfoSectionUnitHeader>
parseInfoSectionUnitHeader(StringRef Info);
parseInfoSectionUnitHeader(StringRef Info, bool IsLittleEndian);
} // namespace llvm
#endif // LLVM_DWP_DWP_H

View file

@ -41,9 +41,10 @@ static uint64_t debugStrOffsetsHeaderSize(DataExtractor StrOffsetsData,
return 8; // unit length: 4 bytes, version: 2 bytes, padding: 2 bytes.
}
static Expected<uint64_t> getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode) {
static Expected<uint64_t> getCUAbbrev(StringRef Abbrev, uint64_t AbbrCode,
bool IsLittleEndian) {
uint64_t Offset = 0;
DataExtractor AbbrevData(Abbrev, true);
DataExtractor AbbrevData(Abbrev, IsLittleEndian);
while (AbbrevData.isValidOffset(Offset)) {
uint64_t Code = AbbrevData.getULEB128(&Offset);
if (Code == AbbrCode)
@ -95,19 +96,20 @@ getIndexedString(dwarf::Form Form, DataExtractor InfoData, uint64_t &InfoOffset,
"DW_FORM_string, DW_FORM_strx, DW_FORM_strx1, DW_FORM_strx2, "
"DW_FORM_strx3, DW_FORM_strx4, or DW_FORM_GNU_str_index.");
}
DataExtractor StrOffsetsData(StrOffsets, true);
DataExtractor StrOffsetsData(StrOffsets, InfoData.isLittleEndian());
uint64_t StrOffsetsOffset = 4 * StrIndex;
StrOffsetsOffset += debugStrOffsetsHeaderSize(StrOffsetsData, Version);
uint64_t StrOffset = StrOffsetsData.getU32(&StrOffsetsOffset);
DataExtractor StrData(Str, true);
DataExtractor StrData(Str, InfoData.isLittleEndian());
return StrData.getCStr(&StrOffset);
}
static Expected<CompileUnitIdentifiers>
getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
StringRef Info, StringRef StrOffsets, StringRef Str) {
DataExtractor InfoData(Info, true);
StringRef Info, StringRef StrOffsets, StringRef Str,
bool IsLittleEndian) {
DataExtractor InfoData(Info, IsLittleEndian);
uint64_t Offset = Header.HeaderSize;
if (Header.Version >= 5 && Header.UnitType != dwarf::DW_UT_split_compile)
return make_error<DWPError>(
@ -118,8 +120,9 @@ getCUIdentifiers(InfoSectionUnitHeader &Header, StringRef Abbrev,
CompileUnitIdentifiers ID;
uint32_t AbbrCode = InfoData.getULEB128(&Offset);
DataExtractor AbbrevData(Abbrev, true);
Expected<uint64_t> AbbrevOffsetOrErr = getCUAbbrev(Abbrev, AbbrCode);
DataExtractor AbbrevData(Abbrev, IsLittleEndian);
Expected<uint64_t> AbbrevOffsetOrErr =
getCUAbbrev(Abbrev, AbbrCode, IsLittleEndian);
if (!AbbrevOffsetOrErr)
return AbbrevOffsetOrErr.takeError();
uint64_t AbbrevOffset = *AbbrevOffsetOrErr;
@ -269,11 +272,12 @@ static Error addAllTypesFromTypesSection(
DWPWriter &Out, MapVector<uint64_t, UnitIndexEntry> &TypeIndexEntries,
DWPSectionId OutputSection, const std::vector<StringRef> &TypesSections,
const UnitIndexEntry &CUEntry, uint32_t &TypesOffset,
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow) {
OnCuIndexOverflow OverflowOptValue, bool &AnySectionOverflow,
bool IsLittleEndian) {
for (StringRef Types : TypesSections) {
Out.switchSection(OutputSection);
uint64_t Offset = 0;
DataExtractor Data(Types, true);
DataExtractor Data(Types, IsLittleEndian);
while (Data.isValidOffset(Offset)) {
UnitIndexEntry Entry = CUEntry;
// Zero out the debug_info contribution
@ -396,11 +400,12 @@ static void writeNewOffsetsTo(DWPWriter &Out, DataExtractor &Data,
namespace llvm {
// Parse and return the header of an info section compile/type unit.
Expected<InfoSectionUnitHeader> parseInfoSectionUnitHeader(StringRef Info) {
Expected<InfoSectionUnitHeader>
parseInfoSectionUnitHeader(StringRef Info, bool IsLittleEndian) {
InfoSectionUnitHeader Header;
Error Err = Error::success();
uint64_t Offset = 0;
DWARFDataExtractor InfoData(Info, true, 0);
DWARFDataExtractor InfoData(Info, IsLittleEndian, 0);
std::tie(Header.Length, Header.Format) =
InfoData.getInitialLength(&Offset, &Err);
if (Err)
@ -460,7 +465,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
StringRef CurStrSection, StringRef CurStrOffsetSection,
uint16_t Version, SectionLengths &SectionLength,
const Dwarf64StrOffsetsPromotion StrOffsetsOptValue,
bool SingleInput) {
bool SingleInput, bool IsLittleEndian) {
// Could possibly produce an error or warning if one of these was non-null but
// the other was null.
if (CurStrSection.empty() || CurStrOffsetSection.empty())
@ -480,7 +485,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
// Pre-reserve based on estimated string count to avoid rehashing.
OffsetRemapping.reserve(CurStrSection.size() / 20);
DataExtractor Data(CurStrSection, true);
DataExtractor Data(CurStrSection, IsLittleEndian);
uint64_t LocalOffset = 0;
uint64_t PrevOffset = 0;
@ -503,7 +508,7 @@ writeStringsAndOffsets(DWPWriter &Out, DWPStringPool &Strings,
PrevOffset = LocalOffset;
}
Data = DataExtractor(CurStrOffsetSection, true);
Data = DataExtractor(CurStrOffsetSection, IsLittleEndian);
Out.switchSection(DS_StrOffsets);
@ -614,7 +619,13 @@ static void writeIndex(DWPWriter &Out, DWPSectionId Section,
}
Out.switchSection(Section);
Out.emitIntValue(IndexVersion, 4); // Version
// Header layout differs between v2 and v5; see DWARFUnitIndex::Header::parse.
if (IndexVersion >= 5) {
Out.emitIntValue(IndexVersion, 2); // Version
Out.emitIntValue(0, 2); // Padding
} else {
Out.emitIntValue(IndexVersion, 4); // Version
}
Out.emitIntValue(Columns, 4); // Columns
Out.emitIntValue(IndexEntries.size(), 4); // Num Units
Out.emitIntValue(Buckets.size(), 4); // Num Buckets
@ -777,6 +788,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
} else if (Obj.isWasm()) {
Out.setIsWASM(true);
}
Out.setIsLittleEndian(Obj.isLittleEndian());
MachineSet = true;
}
@ -806,8 +818,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
if (CurInfoSection.empty())
continue;
Expected<InfoSectionUnitHeader> HeaderOrErr =
parseInfoSectionUnitHeader(CurInfoSection.front());
Expected<InfoSectionUnitHeader> HeaderOrErr = parseInfoSectionUnitHeader(
CurInfoSection.front(), Obj.isLittleEndian());
if (!HeaderOrErr)
return HeaderOrErr.takeError();
InfoSectionUnitHeader &Header = *HeaderOrErr;
@ -825,7 +837,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
writeStringsAndOffsets(Out, Strings, CurStrSection, CurStrOffsetSection,
Header.Version, SectionLength, StrOffsetsOptValue,
Inputs.size() == 1);
Inputs.size() == 1, Obj.isLittleEndian());
for (auto Pair : SectionLength) {
auto Index = getContributionIndex(Pair.first, IndexVersion);
@ -858,7 +870,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
uint64_t UnitOffset = 0;
while (Info.size() > UnitOffset) {
Expected<InfoSectionUnitHeader> HeaderOrError =
parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()));
parseInfoSectionUnitHeader(Info.substr(UnitOffset, Info.size()),
Obj.isLittleEndian());
if (!HeaderOrError)
return HeaderOrError.takeError();
InfoSectionUnitHeader &Header = *HeaderOrError;
@ -887,7 +900,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
Expected<CompileUnitIdentifiers> EID = getCUIdentifiers(
Header, AbbrevSection,
Info.substr(UnitOffset - C.getLength32(), C.getLength32()),
CurStrOffsetSection, CurStrSection);
CurStrOffsetSection, CurStrSection, Obj.isLittleEndian());
if (!EID)
return createFileError(Input, EID.takeError());
@ -921,7 +934,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
if (Error Err = addAllTypesFromTypesSection(
Out, TypeIndexEntries, DS_Types, CurTypesSection, CurEntry,
ContributionOffsets[getContributionIndex(DW_SECT_EXT_TYPES, 2)],
OverflowOptValue, AnySectionOverflow))
OverflowOptValue, AnySectionOverflow, Obj.isLittleEndian()))
return Err;
}
if (AnySectionOverflow)
@ -952,7 +965,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
StringRef CUInfoSection =
getSubsection(DwpSingleInfoSection, E, DW_SECT_INFO);
Expected<InfoSectionUnitHeader> HeaderOrError =
parseInfoSectionUnitHeader(CUInfoSection);
parseInfoSectionUnitHeader(CUInfoSection, Obj.isLittleEndian());
if (!HeaderOrError)
return HeaderOrError.takeError();
InfoSectionUnitHeader &Header = *HeaderOrError;
@ -961,7 +974,7 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
Header, getSubsection(AbbrevSection, E, DW_SECT_ABBREV),
CUInfoSection,
getSubsection(CurStrOffsetSection, E, DW_SECT_STR_OFFSETS),
CurStrSection);
CurStrSection, Obj.isLittleEndian());
if (!EID)
return createFileError(Input, EID.takeError());
const auto &ID = *EID;
@ -1060,7 +1073,8 @@ Error write(DWPWriter &Out, ArrayRef<std::string> Inputs,
//===----------------------------------------------------------------------===//
Error DWPWriter::writeELF(raw_pwrite_stream &OS) {
support::endian::Writer Wr(OS, llvm::endianness::little);
support::endian::Writer Wr(OS, IsLittleEndian ? llvm::endianness::little
: llvm::endianness::big);
// Section metadata table.
struct SectionMeta {

View file

@ -0,0 +1,206 @@
# REQUIRES: systemz-registered-target
## This assembly was produced by:
## echo 'int integer;' > int.c
## clang -target s390x-ibm-linux -gdwarf-5 -gsplit-dwarf -O0 -S int.c -o -
# RUN: llvm-mc --triple=s390x-ibm-linux --filetype=obj --split-dwarf-file=%t.dwo -dwarf-version=5 %s -o %t.o
# RUN: llvm-dwp %t.dwo -o %t.dwp
# RUN: llvm-dwarfdump -v %t.dwp | FileCheck %s
# CHECK-DAG: .debug_info.dwo contents:
# CHECK: 0x00000000: Compile Unit: length = 0x00000026, format = DWARF32, version = 0x0005, unit_type = DW_UT_split_compile, abbr_offset = 0x0000, addr_size = 0x08, DWO_id = [[DWOID:.*]] (next unit at 0x0000002a)
# CHECK-DAG: .debug_cu_index contents:
# CHECK: version = 5, units = 1, slots = 2
# CHECK: Index Signature INFO ABBREV STR_OFFSETS
# CHECK: 1 [[DWOID]] [0x0000000000000000, 0x000000000000002a) [0x00000000, 0x0000002a) [0x00000000, 0x0000001c)
.text
.file "int.c"
.file 0 "/tmp" "int.c" md5 0xdb9c8bb799b289960d8139be0d914773
.type integer,@object # @integer
.section .bss,"aw",@nobits
.globl integer
.p2align 2, 0x0
integer:
.long 0 # 0x0
.size integer, 4
.section .debug_abbrev,"",@progbits
.byte 1 # Abbreviation Code
.byte 74 # DW_TAG_skeleton_unit
.byte 0 # DW_CHILDREN_no
.byte 16 # DW_AT_stmt_list
.byte 23 # DW_FORM_sec_offset
.byte 114 # DW_AT_str_offsets_base
.byte 23 # DW_FORM_sec_offset
.byte 27 # DW_AT_comp_dir
.byte 37 # DW_FORM_strx1
.ascii "\264B" # DW_AT_GNU_pubnames
.byte 25 # DW_FORM_flag_present
.byte 118 # DW_AT_dwo_name
.byte 37 # DW_FORM_strx1
.byte 115 # DW_AT_addr_base
.byte 23 # DW_FORM_sec_offset
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_info,"",@progbits
.Lcu_begin0:
.long .Ldebug_info_end0-.Ldebug_info_start0 # Length of Unit
.Ldebug_info_start0:
.short 5 # DWARF version number
.byte 4 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long .debug_abbrev # Offset Into Abbrev. Section
.quad -1173350285159172090
.byte 1 # Abbrev [1] 0x14:0xf DW_TAG_skeleton_unit
.long .Lline_table_start0 # DW_AT_stmt_list
.long .Lstr_offsets_base0 # DW_AT_str_offsets_base
.byte 0 # DW_AT_comp_dir
# DW_AT_GNU_pubnames
.byte 1 # DW_AT_dwo_name
.long .Laddr_table_base0 # DW_AT_addr_base
.Ldebug_info_end0:
.section .debug_str_offsets,"",@progbits
.long 12 # Length of String Offsets Set
.short 5
.short 0
.Lstr_offsets_base0:
.section .debug_str,"MS",@progbits,1
.Lskel_string0:
.asciz "/tmp" # string offset=0
.Lskel_string1:
.asciz "int.dwo" # string offset=5
.section .debug_str_offsets,"",@progbits
.long .Lskel_string0
.long .Lskel_string1
.section .debug_str_offsets.dwo,"e",@progbits
.long 24 # Length of String Offsets Set
.short 5
.short 0
.section .debug_str.dwo,"eMS",@progbits,1
.Linfo_string0:
.asciz "integer" # string offset=0
.Linfo_string1:
.asciz "int" # string offset=8
.Linfo_string2:
.asciz "Ubuntu clang version 19.1.1 (1ubuntu1~24.04.2)" # string offset=12
.Linfo_string3:
.asciz "int.c" # string offset=59
.Linfo_string4:
.asciz "int.dwo" # string offset=65
.section .debug_str_offsets.dwo,"e",@progbits
.long 0
.long 8
.long 12
.long 59
.long 65
.section .debug_info.dwo,"e",@progbits
.long .Ldebug_info_dwo_end0-.Ldebug_info_dwo_start0 # Length of Unit
.Ldebug_info_dwo_start0:
.short 5 # DWARF version number
.byte 5 # DWARF Unit Type
.byte 8 # Address Size (in bytes)
.long 0 # Offset Into Abbrev. Section
.quad -1173350285159172090
.byte 1 # Abbrev [1] 0x14:0x16 DW_TAG_compile_unit
.byte 2 # DW_AT_producer
.short 29 # DW_AT_language
.byte 3 # DW_AT_name
.byte 4 # DW_AT_dwo_name
.byte 2 # Abbrev [2] 0x1a:0xb DW_TAG_variable
.byte 0 # DW_AT_name
.long 37 # DW_AT_type
# DW_AT_external
.byte 0 # DW_AT_decl_file
.byte 1 # DW_AT_decl_line
.byte 2 # DW_AT_location
.byte 161
.byte 0
.byte 3 # Abbrev [3] 0x25:0x4 DW_TAG_base_type
.byte 1 # DW_AT_name
.byte 5 # DW_AT_encoding
.byte 4 # DW_AT_byte_size
.byte 0 # End Of Children Mark
.Ldebug_info_dwo_end0:
.section .debug_abbrev.dwo,"e",@progbits
.byte 1 # Abbreviation Code
.byte 17 # DW_TAG_compile_unit
.byte 1 # DW_CHILDREN_yes
.byte 37 # DW_AT_producer
.byte 37 # DW_FORM_strx1
.byte 19 # DW_AT_language
.byte 5 # DW_FORM_data2
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 118 # DW_AT_dwo_name
.byte 37 # DW_FORM_strx1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 2 # Abbreviation Code
.byte 52 # DW_TAG_variable
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 73 # DW_AT_type
.byte 19 # DW_FORM_ref4
.byte 63 # DW_AT_external
.byte 25 # DW_FORM_flag_present
.byte 58 # DW_AT_decl_file
.byte 11 # DW_FORM_data1
.byte 59 # DW_AT_decl_line
.byte 11 # DW_FORM_data1
.byte 2 # DW_AT_location
.byte 24 # DW_FORM_exprloc
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 3 # Abbreviation Code
.byte 36 # DW_TAG_base_type
.byte 0 # DW_CHILDREN_no
.byte 3 # DW_AT_name
.byte 37 # DW_FORM_strx1
.byte 62 # DW_AT_encoding
.byte 11 # DW_FORM_data1
.byte 11 # DW_AT_byte_size
.byte 11 # DW_FORM_data1
.byte 0 # EOM(1)
.byte 0 # EOM(2)
.byte 0 # EOM(3)
.section .debug_addr,"",@progbits
.long .Ldebug_addr_end0-.Ldebug_addr_start0 # Length of contribution
.Ldebug_addr_start0:
.short 5 # DWARF version number
.byte 8 # Address size
.byte 0 # Segment selector size
.Laddr_table_base0:
.quad integer
.Ldebug_addr_end0:
.section .debug_gnu_pubnames,"",@progbits
.long .LpubNames_end0-.LpubNames_start0 # Length of Public Names Info
.LpubNames_start0:
.short 2 # DWARF Version
.long .Lcu_begin0 # Offset of Compilation Unit Info
.long 35 # Compilation Unit Length
.long 26 # DIE offset
.byte 32 # Attributes: VARIABLE, EXTERNAL
.asciz "integer" # External Name
.long 0 # End Mark
.LpubNames_end0:
.section .debug_gnu_pubtypes,"",@progbits
.long .LpubTypes_end0-.LpubTypes_start0 # Length of Public Types Info
.LpubTypes_start0:
.short 2 # DWARF Version
.long .Lcu_begin0 # Offset of Compilation Unit Info
.long 35 # Compilation Unit Length
.long 37 # DIE offset
.byte 144 # Attributes: TYPE, STATIC
.asciz "int" # External Name
.long 0 # End Mark
.LpubTypes_end0:
.ident "Ubuntu clang version 19.1.1 (1ubuntu1~24.04.2)"
.section ".note.GNU-stack","",@progbits
.addrsig
.section .debug_line,"",@progbits
.Lline_table_start0:

View file

@ -1,17 +1,81 @@
# REQUIRES: zlib
# RUN: yaml2obj -DCLASS=32 -DENDIAN=LSB -DINFO_CHDR=010000005600000001000000 %s -o %t.o
## INFO_DATA / STR_OFFSETS / LINE in the DEFINE lines below are reproduced by
## this snippet.
##
## import struct, zlib
## for end in ('<', '>'):
## # .debug_info.dwo DIE stream. Each abbrev code selects an entry in
## # .debug_abbrev.dwo below; that entry dictates which DW_AT_* values
## # follow and in what order.
## die = b'\x01' # .debug_abbrev code (DW_TAG_compile_unit)
## die += b'\x00' # DW_AT_producer="clang version 3.9.0 ..."
## die += struct.pack(end+'H', 4) # DW_AT_language=DW_LANG_C_plus_plus
## die += b'\x01' # DW_AT_name="a.cpp"
## die += struct.pack(end+'Q', 0x5d2ca3800efeebd9) # DW_AT_GNU_dwo_id
## die += b'\x02' # .debug_abbrev code (DW_TAG_subprogram)
## die += b'\x00' # DW_AT_low_pc (addr idx)
## die += struct.pack(end+'I', 0x12) # DW_AT_high_pc
## die += b'\x01\x56' # DW_AT_frame_base (exprloc: DW_OP_reg6)
## die += b'\x02' # DW_AT_linkage_name="_Z1fiiii"
## die += b'\x03' # DW_AT_name="f"
## die += b'\x01' # DW_AT_decl_file
## die += b'\x01' # DW_AT_decl_line
## for name, off in [(4, 0x7c), (6, 0x78), (7, 0x74), (8, 0x70)]: # params a,b,c,d
## die += b'\x03' # .debug_abbrev code (DW_TAG_formal_parameter)
## die += b'\x02\x91' + bytes([off]) # DW_AT_location (exprloc: DW_OP_breg6, sleb)
## die += bytes([name]) # DW_AT_name="a"/"b"/"c"/"d"
## die += b'\x01' # DW_AT_decl_file
## die += b'\x01' # DW_AT_decl_line
## die += struct.pack(end+'I', 0x51) # DW_AT_type (ref4)
## die += b'\x00' # end of DW_TAG_subprogram children
## die += b'\x04' # .debug_abbrev code (DW_TAG_base_type)
## die += b'\x05' # DW_AT_name="int"
## die += b'\x05' # DW_AT_encoding=DW_ATE_signed
## die += b'\x04' # DW_AT_byte_size
## die += b'\x00' # end of DW_TAG_compile_unit children
## # CU header (unit_length excludes itself) + DIE stream, zlib-compressed
## info = struct.pack(end+'IHIB',
## 7 + len(die), # unit_length
## 4, # version
## 0, # debug_abbrev_offset
## 8) # address_size
## info += die
## print(end, 'INFO_DATA ', zlib.compress(info).hex())
## # .debug_str_offsets.dwo: u32 offsets into .debug_str.dwo
## str_off = b''
## for o in (0, 0x37, 0x3D, 0x46, 0x48, 0x4A, 0x4E, 0x50, 0x52):
## str_off += struct.pack(end+'I', o)
## print(end, 'STR_OFFSETS', str_off.hex())
## # .debug_line.dwo: minimal v2 line-table header, empty dirs + files
## line = struct.pack(end+'IHIBBbBB',
## 13, # unit_length
## 2, # version
## 7, # header_length
## 1, # minimum_instruction_length
## 1, # default_is_stmt
## -5, # line_base
## 14, # line_range
## 1) # opcode_base
## line += b'\x00\x00' # empty include_directories, file_names
## print(end, 'LINE ', line.hex())
# DEFINE: %{LE_OPTS} = -DINFO_DATA=789c0b626060606100010e462083f1e6eb7f7c0d8b756299188480628c614ccc8c8ccc4c136b5818190381024066051b9c59c20e67167040980c2cacac2c0c00109a0afa -DSTR_OFFSETS=00000000370000003D00000046000000480000004A0000004E0000005000000052000000 -DLINE=0D0000000200070000000101FB0E010000
# DEFINE: %{BE_OPTS} = -DINFO_DATA=789c6360600862606100020e46060616c6589dc50d7cff5edf6402090931863131333232334dac6161044a33040299156c7066093b9c59c0016132b0b0b2b230000003dc0afa -DSTR_OFFSETS=00000000000000370000003D00000046000000480000004A0000004E0000005000000052 -DLINE=0000000D0002000000070101FB0E010000
# RUN: yaml2obj -DCLASS=32 -DENDIAN=LSB -DINFO_CHDR=010000005600000001000000 %{LE_OPTS} %s -o %t.o
# RUN: llvm-dwp %t.o -o %t
# RUN: llvm-dwarfdump -v %t | FileCheck %s
# RUN: yaml2obj -DCLASS=32 -DENDIAN=MSB -DINFO_CHDR=000000010000005600000001 %s -o %t.o
# RUN: yaml2obj -DCLASS=32 -DENDIAN=MSB -DINFO_CHDR=000000010000005600000001 %{BE_OPTS} %s -o %t.o
# RUN: llvm-dwp %t.o -o %t
# RUN: llvm-dwarfdump -v %t | FileCheck %s
# RUN: yaml2obj -DCLASS=64 -DENDIAN=LSB -DINFO_CHDR=01000000fd7f000056000000000000000100000000000000 %s -o %t.o
# RUN: yaml2obj -DCLASS=64 -DENDIAN=LSB -DINFO_CHDR=01000000fd7f000056000000000000000100000000000000 %{LE_OPTS} %s -o %t.o
# RUN: llvm-dwp %t.o -o %t
# RUN: llvm-dwarfdump -v %t | FileCheck %s
# RUN: yaml2obj -DCLASS=64 -DENDIAN=MSB -DINFO_CHDR=0000000100007ffd00000000000000560000000000000001 %s -o %t.o
# RUN: yaml2obj -DCLASS=64 -DENDIAN=MSB -DINFO_CHDR=0000000100007ffd00000000000000560000000000000001 %{BE_OPTS} %s -o %t.o
# RUN: llvm-dwp %t.o -o %t
# RUN: llvm-dwarfdump -v %t | FileCheck %s
@ -49,12 +113,12 @@ Sections:
- Name: .debug_str_offsets.dwo
Type: SHT_PROGBITS
AddressAlign: 0x1
Content: 00000000370000003D00000046000000480000004A0000004E0000005000000052000000
Content: [[STR_OFFSETS]]
- Name: .debug_info.dwo
Type: SHT_PROGBITS
Flags: [ SHF_COMPRESSED ]
AddressAlign: 0x8
Content: [[INFO_CHDR]]789c0b626060606100010e462083f1e6eb7f7c0d8b756299188480628c614ccc8c8ccc4c136b5818190381024066051b9c59c20e67167040980c2cacac2c0c00109a0afa
Content: [[INFO_CHDR]][[INFO_DATA]]
- Name: .debug_abbrev.dwo
Type: SHT_PROGBITS
AddressAlign: 0x1
@ -62,4 +126,4 @@ Sections:
- Name: .debug_line.dwo
Type: SHT_PROGBITS
AddressAlign: 0x1
Content: 0D0000000200070000000101FB0E010000
Content: [[LINE]]