15namespace dwarflinker_parallel {
18 "debug_info",
"debug_line",
"debug_frame",
"debug_ranges",
19 "debug_rnglists",
"debug_loc",
"debug_loclists",
"debug_aranges",
20 "debug_abbrev",
"debug_macinfo",
"debug_macro",
"debug_addr",
21 "debug_str",
"debug_line_str",
"debug_str_offsets",
"debug_pubnames",
22 "debug_pubtypes",
"debug_names",
"apple_names",
"apple_namespac",
23 "apple_objc",
"apple_types"};
84 RefCU(RefCU, (SrcCU !=
nullptr) &&
85 (SrcCU->getUniqueID() == RefCU->getUniqueID())),
86 RefDieIdxOrClonedOffset(RefIdx) {}
93 RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
94 RefDieIdxOrClonedOffset(RefIdx) {}
105 RefTypeName(RefTypeName) {}
121 : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}
126 ListDebugStrPatch.erase();
127 ListDebugLineStrPatch.erase();
128 ListDebugRangePatch.erase();
129 ListDebugLocPatch.erase();
130 ListDebugDieRefPatch.erase();
131 ListDebugULEB128DieRefPatch.erase();
132 ListDebugOffsetPatch.erase();
133 ListDebugType2TypeDieRefPatch.erase();
134 ListDebugTypeDeclFilePatch.erase();
135 ListDebugTypeLineStrPatch.erase();
136 ListDebugTypeStrPatch.erase();
156 if (!SectNameOrErr) {
160 if (std::optional<DebugSectionKind> SectKind =
180 const char *StringVal) {
181 assert(StringVal !=
nullptr);
183 switch (StringForm) {
184 case dwarf::DW_FORM_string: {
187 case dwarf::DW_FORM_strp: {
192 case dwarf::DW_FORM_line_strp: {
206 OS.
write(
static_cast<uint8_t
>(Val));
212 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
218 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
223 OS.
write(
reinterpret_cast<const char *
>(&Val),
Size);
233 case dwarf::DW_FORM_strp:
234 case dwarf::DW_FORM_line_strp: {
238 case dwarf::DW_FORM_ref_addr: {
241 case dwarf::DW_FORM_ref1: {
244 case dwarf::DW_FORM_ref2: {
247 case dwarf::DW_FORM_ref4: {
250 case dwarf::DW_FORM_ref8: {
254 case dwarf::DW_FORM_data1: {
257 case dwarf::DW_FORM_data2: {
260 case dwarf::DW_FORM_data4: {
263 case dwarf::DW_FORM_data8: {
266 case dwarf::DW_FORM_udata: {
269 case dwarf::DW_FORM_sdata: {
272 case dwarf::DW_FORM_sec_offset: {
275 case dwarf::DW_FORM_flag: {
289 return *
reinterpret_cast<const uint8_t *
>(
316 const_cast<char *
>(
getContents().data() + PatchOffset),
321 const_cast<char *
>(
getContents().data() + PatchOffset),
326 const_cast<char *
>(
getContents().data() + PatchOffset),
331 const_cast<char *
>(
getContents().data() + PatchOffset),
346 memcpy(
const_cast<char *
>(
getContents().data() + PatchOffset), ULEB,
358 memcpy(
const_cast<char *
>(
getContents().data() + PatchOffset), SLEB,
367 Section.ListDebugStrPatch.forEach([&](
DebugStrPatch &Patch) {
372 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
375 assert(TypeUnitPtr !=
nullptr);
378 formatv(
"No data for type {0}", Patch.TypeName->getKey())
382 if (&
TypeEntry->getFinalDie() != Patch.Die)
390 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
392 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
400 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
403 assert(TypeUnitPtr !=
nullptr);
406 formatv(
"No data for type {0}", Patch.TypeName->getKey())
410 if (&
TypeEntry->getFinalDie() != Patch.Die)
418 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
420 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
423 std::optional<SectionDescriptor *> RangeSection;
433 FinalValue += (*RangeSection)->StartOffset;
435 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
439 std::optional<SectionDescriptor *> LocationSection;
445 if (LocationSection) {
446 Section.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
449 FinalValue += (*LocationSection)->StartOffset;
451 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
456 uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
460 if (!Patch.RefCU.getInt()) {
461 SectionDescriptor &ReferencedSectionDescriptor =
462 Patch.RefCU.getPointer()->getSectionDescriptor(
463 DebugSectionKind::DebugInfo);
465 FinalForm = dwarf::DW_FORM_ref_addr;
466 FinalOffset += ReferencedSectionDescriptor.StartOffset;
469 Section.apply(Patch.
PatchOffset, FinalForm, FinalOffset);
472 Section.ListDebugULEB128DieRefPatch.forEach(
474 assert(Patch.RefCU.getInt());
475 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_udata,
476 Patch.RefDieIdxOrClonedOffset);
480 assert(TypeUnitPtr !=
nullptr);
481 assert(Patch.RefTypeName !=
nullptr);
485 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
489 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref_addr,
493 Section.ListDebugType2TypeDieRefPatch.forEach(
495 assert(TypeUnitPtr !=
nullptr);
498 formatv(
"No data for type {0}", Patch.TypeName->getKey())
502 if (&
TypeEntry->getFinalDie() != Patch.Die)
508 assert(Patch.RefTypeName !=
nullptr);
509 TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
511 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
515 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref4,
520 uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;
523 if (Patch.SectionPtr.getInt())
527 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
A structured debug information entry.
unsigned getOffset() const
Get the compile/type unit relative offset of this DIE.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
SectionKind - This is a simple POD value that classifies the properties of a section.
pointer data()
Return a pointer to the vector's buffer, even if empty().
A wrapper around a string literal that serves as a proxy for constructing global tables of StringRefs...
StringMapEntry - This is used to represent one value that is inserted into a StringMap.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
size_t find_first_not_of(char C, size_t From=0) const
Find the first character in the string that is not C or npos if not found.
const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
A switch()-like statement whose cases are string literals.
Stores all information related to a compile unit, be it in its original instance of the object file o...
StringPool & getStringPool()
Returns global string pool.
void applyPatches(SectionDescriptor &Section, StringEntryToDwarfStringPoolEntryMap &DebugStrStrings, StringEntryToDwarfStringPoolEntryMap &DebugLineStrStrings, TypeUnit *TypeUnitPtr)
Enumerate all sections, for each section apply all section patches.
dwarf::FormParams Format
Format for sections.
std::optional< const SectionDescriptor * > tryGetSectionDescriptor(DebugSectionKind SectionKind) const
Returns descriptor for the specified section of SectionKind.
This class creates a DwarfStringPoolEntry for the corresponding StringEntry.
DwarfStringPoolEntryWithExtString * getExistingEntry(const StringEntry *String) const
Returns already existed DwarfStringPoolEntry for the specified StringEntry.
Keeps cloned data for the type DIE.
DIE & getFinalDie() const
Returns copy of type DIE which should be emitted into resulting file.
Type Unit is used to represent an artificial compilation unit which keeps all type information.
static Expected< OwningBinary< ObjectFile > > createObjectFile(StringRef ObjectPath)
This is a value type class that represents a single section in the list of sections in the object fil...
uint64_t tell() const
tell - Return the current offset with the file.
raw_ostream & write(unsigned char C)
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
static constexpr StringLiteral SectionNames[SectionKindsNum]
std::optional< DebugSectionKind > parseDebugTableName(llvm::StringRef SecName)
Recognise the table name and match it with the DebugSectionKind.
DebugSectionKind
List of tracked debug tables.
SmallString< 0 > OutSectionDataTy
Type for section data.
static constexpr size_t SectionKindsNum
const StringLiteral & getSectionName(DebugSectionKind SectionKind)
Return the name of the section.
uint32_t read32(const void *P, endianness E)
uint64_t read64(const void *P, endianness E)
void write(void *memory, value_type value, endianness endian)
Write a value to memory with a particular endianness.
uint16_t read16(const void *P, endianness E)
void swapByteOrder(T &Value)
This is an optimization pass for GlobalISel generic memory operations.
auto formatv(const char *Fmt, Ts &&... Vals) -> formatv_object< decltype(std::make_tuple(detail::build_format_adapter(std::forward< Ts >(Vals))...))>
auto size(R &&Range, std::enable_if_t< std::is_base_of< std::random_access_iterator_tag, typename std::iterator_traits< decltype(Range.begin())>::iterator_category >::value, void > *=nullptr)
Get the size of a range.
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
@ Default
The result values are uniform if and only if all operands are uniform.
void consumeError(Error Err)
Consume a Error without doing anything.
DwarfStringPoolEntry with string keeping externally.
This structure is used to update reference to the DIE.
DebugDieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
This structure is used to update reference to the type DIE.
DebugDieTypeRefPatch(uint64_t PatchOffset, TypeEntry *RefTypeName)
This structure is used to update strings offsets into .debug_line_str.
This structure is used to update location list offset into .debug_loc/.debug_loclists.
This structure is used to update range list offset into .debug_ranges/.debug_rnglists.
This structure is used to update strings offsets into .debug_str.
const StringEntry * String
This structure is used to update reference to the type DIE.
DebugType2TypeDieRefPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, TypeEntry *RefTypeName)
DebugTypeDeclFilePatch(DIE *Die, TypeEntry *TypeName, StringEntry *Directory, StringEntry *FilePath)
DebugTypeLineStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, StringEntry *String)
DebugTypeStrPatch(uint64_t PatchOffset, DIE *Die, TypeEntry *TypeName, StringEntry *String)
This structure is used to update reference to the DIE of ULEB128 form.
DebugULEB128DieRefPatch(uint64_t PatchOffset, CompileUnit *SrcCU, CompileUnit *RefCU, uint32_t RefIdx)
This structure is used to keep data of the concrete section.
void clearSectionContent()
Erase only section output data bits.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
void emitInplaceString(StringRef String)
Emit specified inplace string value into the current section contents.
void emitString(dwarf::Form StringForm, const char *StringVal)
void applySLEB128(uint64_t PatchOffset, uint64_t Val)
Writes integer value Val of SLEB128 format by specified PatchOffset.
void applyULEB128(uint64_t PatchOffset, uint64_t Val)
Writes integer value Val of ULEB128 format by specified PatchOffset.
size_t SectionOffsetInsideAsmPrinterOutputEnd
uint64_t StartOffset
When objects(f.e.
OutSectionDataTy Contents
Section data bits.
llvm::endianness Endianess
raw_svector_ostream OS
Stream which stores data to the Contents.
dwarf::FormParams Format
Output format.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
size_t SectionOffsetInsideAsmPrinterOutputStart
Some sections are generated using AsmPrinter.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size)
Writes integer value Val of Size by specified PatchOffset.
LinkingGlobalData & GlobalData
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
StringRef getContents()
Returns section content.
void clearAllSectionData()
Erase whole section contents(data bits, list of patches).
void emitStringPlaceholder()
Emit string placeholder into the current section contents.
There are fields(sizes, offsets) which should be updated after sections are generated.