14using namespace dwarf_linker;
15using namespace dwarf_linker::parallel;
20 RefCU(RefCU, (SrcCU !=
nullptr) &&
21 (SrcCU->getUniqueID() == RefCU->getUniqueID())),
22 RefDieIdxOrClonedOffset(RefIdx) {}
29 RefCU(RefCU, SrcCU->getUniqueID() == RefCU->getUniqueID()),
30 RefDieIdxOrClonedOffset(RefIdx) {}
41 RefTypeName(RefTypeName) {}
57 : Die(Die), TypeName(TypeName), Directory(Directory), FilePath(FilePath) {}
62 ListDebugStrPatch.erase();
63 ListDebugLineStrPatch.erase();
64 ListDebugRangePatch.erase();
65 ListDebugLocPatch.erase();
66 ListDebugDieRefPatch.erase();
67 ListDebugULEB128DieRefPatch.erase();
68 ListDebugOffsetPatch.erase();
69 ListDebugType2TypeDieRefPatch.erase();
70 ListDebugTypeDeclFilePatch.erase();
71 ListDebugTypeLineStrPatch.erase();
72 ListDebugTypeStrPatch.erase();
96 if (std::optional<DebugSectionKind> SectKind =
116 const char *StringVal) {
117 assert(StringVal !=
nullptr);
119 switch (StringForm) {
120 case dwarf::DW_FORM_string: {
123 case dwarf::DW_FORM_strp: {
128 case dwarf::DW_FORM_line_strp: {
148 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
154 OS.
write(
reinterpret_cast<const char *
>(&ShortVal),
Size);
159 OS.
write(
reinterpret_cast<const char *
>(&Val),
Size);
173 case dwarf::DW_FORM_strp:
174 case dwarf::DW_FORM_line_strp: {
178 case dwarf::DW_FORM_ref_addr: {
181 case dwarf::DW_FORM_ref1: {
184 case dwarf::DW_FORM_ref2: {
187 case dwarf::DW_FORM_ref4: {
190 case dwarf::DW_FORM_ref8: {
194 case dwarf::DW_FORM_data1: {
197 case dwarf::DW_FORM_data2: {
200 case dwarf::DW_FORM_data4: {
203 case dwarf::DW_FORM_data8: {
206 case dwarf::DW_FORM_udata: {
209 case dwarf::DW_FORM_sdata: {
212 case dwarf::DW_FORM_sec_offset: {
215 case dwarf::DW_FORM_flag: {
229 return *
reinterpret_cast<const uint8_t *
>(
307 Section.ListDebugStrPatch.forEach([&](
DebugStrPatch &Patch) {
312 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
315 assert(TypeUnitPtr !=
nullptr);
318 formatv(
"No data for type {0}", Patch.TypeName->getKey())
322 if (&
TypeEntry->getFinalDie() != Patch.Die)
330 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
332 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_strp, Entry->Offset);
340 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
343 assert(TypeUnitPtr !=
nullptr);
346 formatv(
"No data for type {0}", Patch.TypeName->getKey())
350 if (&
TypeEntry->getFinalDie() != Patch.Die)
358 Patch.Die->getOffset() +
getULEB128Size(Patch.Die->getAbbrevNumber());
360 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_line_strp, Entry->Offset);
363 std::optional<SectionDescriptor *> RangeSection;
373 FinalValue += (*RangeSection)->StartOffset;
375 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
379 std::optional<SectionDescriptor *> LocationSection;
385 if (LocationSection) {
386 Section.ListDebugLocPatch.forEach([&](
DebugLocPatch &Patch) {
389 FinalValue += (*LocationSection)->StartOffset;
391 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
396 uint64_t FinalOffset = Patch.RefDieIdxOrClonedOffset;
400 if (!Patch.RefCU.getInt()) {
401 SectionDescriptor &ReferencedSectionDescriptor =
402 Patch.RefCU.getPointer()->getSectionDescriptor(
403 DebugSectionKind::DebugInfo);
405 FinalForm = dwarf::DW_FORM_ref_addr;
406 FinalOffset += ReferencedSectionDescriptor.StartOffset;
409 Section.apply(Patch.
PatchOffset, FinalForm, FinalOffset);
412 Section.ListDebugULEB128DieRefPatch.forEach(
414 assert(Patch.RefCU.getInt());
415 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_udata,
416 Patch.RefDieIdxOrClonedOffset);
420 assert(TypeUnitPtr !=
nullptr);
421 assert(Patch.RefTypeName !=
nullptr);
425 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
429 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref_addr,
433 Section.ListDebugType2TypeDieRefPatch.forEach(
435 assert(TypeUnitPtr !=
nullptr);
438 formatv(
"No data for type {0}", Patch.TypeName->getKey())
442 if (&
TypeEntry->getFinalDie() != Patch.Die)
448 assert(Patch.RefTypeName !=
nullptr);
449 TypeEntryBody *RefTypeEntry = Patch.RefTypeName->getValue().load();
451 formatv(
"No data for type {0}", Patch.RefTypeName->getKey())
455 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_ref4,
460 uint64_t FinalValue = Patch.SectionPtr.getPointer()->StartOffset;
463 if (Patch.SectionPtr.getInt())
467 Section.apply(Patch.
PatchOffset, dwarf::DW_FORM_sec_offset, FinalValue);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
LLVM_ABI 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(bool Validate, const char *Fmt, Ts &&...Vals)
LLVM_ABI 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.