15using namespace dwarf_linker;
16using namespace dwarf_linker::parallel;
21 RefCU(RefCU, (SrcCU !=
nullptr) &&
22 (SrcCU->getUniqueID() == RefCU->getUniqueID())),
23 RefDieIdxOrClonedOffset(RefIdx) {}
30 RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
31 RefDieIdxOrClonedOffset(RefIdx) {}
42 RefTypeName(RefTypeName) {}
58 : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}
63 ListDebugStrPatch.erase();
64 ListDebugLineStrPatch.erase();
65 ListDebugRangePatch.erase();
66 ListDebugLocPatch.erase();
67 ListDebugDieRefPatch.erase();
68 ListDebugULEB128DieRefPatch.erase();
69 ListDebugOffsetPatch.erase();
70 ListDebugType2TypeDieRefPatch.erase();
71 ListDebugTypeDeclFilePatch.erase();
72 ListDebugTypeLineStrPatch.erase();
73 ListDebugTypeStrPatch.erase();
97 if (std::optional<DebugSectionKind> SectKind =
117 const char *StringVal) {
118 assert(StringVal !=
nullptr);
120 switch (StringForm) {
121 case dwarf::DW_FORM_string: {
124 case dwarf::DW_FORM_strp: {
129 case dwarf::DW_FORM_line_strp: {
143 OS.
write(
static_cast<uint8_t
>(Val));
149 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
155 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
160 OS.
write(
reinterpret_cast<const char *
>(&Val),
Size);
174 case dwarf::DW_FORM_strp:
175 case dwarf::DW_FORM_line_strp: {
179 case dwarf::DW_FORM_ref_addr: {
182 case dwarf::DW_FORM_ref1: {
185 case dwarf::DW_FORM_ref2: {
188 case dwarf::DW_FORM_ref4: {
191 case dwarf::DW_FORM_ref8: {
195 case dwarf::DW_FORM_data1: {
198 case dwarf::DW_FORM_data2: {
201 case dwarf::DW_FORM_data4: {
204 case dwarf::DW_FORM_data8: {
207 case dwarf::DW_FORM_udata: {
210 case dwarf::DW_FORM_sdata: {
213 case dwarf::DW_FORM_sec_offset: {
216 case dwarf::DW_FORM_flag: {
230 return *
reinterpret_cast<const uint8_t *
>(
257 const_cast<char *
>(
getContents().data() + PatchOffset),
262 const_cast<char *
>(
getContents().data() + PatchOffset),
267 const_cast<char *
>(
getContents().data() + PatchOffset),
272 const_cast<char *
>(
getContents().data() + PatchOffset),
287 memcpy(
const_cast<char *
>(
getContents().data() + PatchOffset), ULEB,
299 memcpy(
const_cast<char *
>(
getContents().data() + PatchOffset), SLEB,
308 Section.ListDebugStrPatch.forEach([&](
DebugStrPatch &Patch) {
313 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
316 assert(TypeUnitPtr !=
nullptr);
319 formatv(
"No data for type {0}", Patch.TypeName->getKey())
323 if (&
TypeEntry->getFinalDie() != Patch.Die)
331 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
333 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
341 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
344 assert(TypeUnitPtr !=
nullptr);
347 formatv(
"No data for type {0}", Patch.TypeName->getKey())
351 if (&
TypeEntry->getFinalDie() != Patch.Die)
359 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
361 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
364 std::optional<SectionDescriptor *> RangeSection;
374 FinalValue += (*RangeSection)->StartOffset;
376 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
380 std::optional<SectionDescriptor *> LocationSection;
386 if (LocationSection) {
387 Section.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
390 FinalValue += (*LocationSection)->StartOffset;
392 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
397 uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
401 if (!Patch.RefCU.getInt()) {
402 SectionDescriptor &ReferencedSectionDescriptor =
403 Patch.RefCU.getPointer()->getSectionDescriptor(
404 DebugSectionKind::DebugInfo);
406 FinalForm = dwarf::DW_FORM_ref_addr;
407 FinalOffset += ReferencedSectionDescriptor.StartOffset;
410 Section.apply(Patch.
PatchOffset, FinalForm, FinalOffset);
413 Section.ListDebugULEB128DieRefPatch.forEach(
415 assert(Patch.RefCU.getInt());
416 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_udata,
417 Patch.RefDieIdxOrClonedOffset);
421 assert(TypeUnitPtr !=
nullptr);
422 assert(Patch.RefTypeName !=
nullptr);
426 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
430 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref_addr,
434 Section.ListDebugType2TypeDieRefPatch.forEach(
436 assert(TypeUnitPtr !=
nullptr);
439 formatv(
"No data for type {0}", Patch.TypeName->getKey())
443 if (&
TypeEntry->getFinalDie() != Patch.Die)
449 assert(Patch.RefTypeName !=
nullptr);
450 TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
452 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
456 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref4,
461 uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;
464 if (Patch.SectionPtr.getInt())
468 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().
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 const char * data() const
data - Get a pointer to the start of the string (which may not be null terminated).
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.
SmallString< 0 > OutSectionDataTy
Type for section data.
std::optional< DebugSectionKind > parseDebugTableName(StringRef Name)
Recognise the table name and match it with the DebugSectionKind.
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 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.
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
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.
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)
llvm::endianness Endianess
dwarf::FormParams Format
Output format.
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void setSizesForSectionCreatedByAsmPrinter()
Some sections are emitted using AsmPrinter.
OutSectionDataTy Contents
Section data bits.
void emitString(dwarf::Form StringForm, const char *StringVal)
void applyIntVal(uint64_t PatchOffset, uint64_t Val, unsigned Size)
Writes integer value Val of Size by specified PatchOffset.
void emitIntVal(uint64_t Val, unsigned Size)
Emit specified integer value into the current section contents.
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.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.
void emitInplaceString(StringRef String)
Emit specified inplace string value into the current section contents.
uint64_t getIntVal(uint64_t PatchOffset, unsigned Size)
Returns integer value of Size located by specified PatchOffset.
void clearSectionContent()
Erase only section output data bits.
void emitBinaryData(llvm::StringRef Data)
StringRef getContents() override
Returns section content.
size_t SectionOffsetInsideAsmPrinterOutputStart
Some sections are generated using AsmPrinter.
void clearAllSectionData()
Erase whole section content(data bits, list of patches).
size_t SectionOffsetInsideAsmPrinterOutputEnd
void emitStringPlaceholder()
Emit string placeholder into the current section contents.
LinkingGlobalData & GlobalData
uint64_t StartOffset
When objects(f.e.
There are fields(sizes, offsets) which should be updated after sections are generated.