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) {}
 
 
   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: {
 
  125        {
OS.tell()}, 
GlobalData.getStringPool().insert(StringVal).first});
 
  128  case dwarf::DW_FORM_line_strp: {
 
  130        {
OS.tell()}, 
GlobalData.getStringPool().insert(StringVal).first});
 
 
  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()) {
 
  402          Patch.RefCU.getPointer()->getSectionDescriptor(
 
  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.
 
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...
 
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...
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
SmallString< 0 > OutSectionDataTy
Type for section data.
 
StringMapEntry< std::atomic< TypeEntryBody * > > TypeEntry
 
LLVM_ABI std::optional< DebugSectionKind > parseDebugTableName(StringRef Name)
Recognise the table name and match it with the DebugSectionKind.
 
StringMapEntry< EmptyStringSetTag > StringEntry
StringEntry keeps data of the string: the length, external offset and a string body which is placed r...
 
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.
 
FunctionAddr VTableAddr uintptr_t uintptr_t Data
 
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.
 
PointerIntPair< CompileUnit *, 1 > RefCU
 
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)
 
PointerIntPair< CompileUnit *, 1 > RefCU
 
DebugSectionKind SectionKind
The section kind.
 
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.