diff --git a/llvm/include/llvm/CodeGen/DIE.h b/llvm/include/llvm/CodeGen/DIE.h --- a/llvm/include/llvm/CodeGen/DIE.h +++ b/llvm/include/llvm/CodeGen/DIE.h @@ -267,6 +267,22 @@ }; //===--------------------------------------------------------------------===// +/// A simple label plus offset DIE. +/// +class DIELabelPlusOffset { + const MCSymbol *Label; + int64_t Offset; + +public: + DIELabelPlusOffset(const MCSymbol *L, int64_t O) : Label(L), Offset(O) {} + + void emitValue(const AsmPrinter *AP, dwarf::Form Form) const; + unsigned SizeOf(const AsmPrinter *AP, dwarf::Form Form) const; + + void print(raw_ostream &O) const; +}; + +//===--------------------------------------------------------------------===// /// A container for string pool string values. /// /// This class is used with the DW_FORM_strp and DW_FORM_GNU_str_index forms. @@ -368,9 +384,10 @@ /// /// All values that aren't standard layout (or are larger than 8 bytes) /// should be stored by reference instead of by value. - using ValTy = AlignedCharArrayUnion; + using ValTy = + AlignedCharArrayUnion; static_assert(sizeof(ValTy) <= sizeof(uint64_t) || sizeof(ValTy) <= sizeof(void *), diff --git a/llvm/include/llvm/CodeGen/DIEValue.def b/llvm/include/llvm/CodeGen/DIEValue.def --- a/llvm/include/llvm/CodeGen/DIEValue.def +++ b/llvm/include/llvm/CodeGen/DIEValue.def @@ -41,6 +41,7 @@ HANDLE_DIEVALUE_LARGE(Loc) HANDLE_DIEVALUE_SMALL(LocList) HANDLE_DIEVALUE_LARGE(InlineString) +HANDLE_DIEVALUE_LARGE(LabelPlusOffset) #undef HANDLE_DIEVALUE #undef HANDLE_DIEVALUE_SMALL diff --git a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DIE.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIE.cpp @@ -565,6 +565,38 @@ } //===----------------------------------------------------------------------===// +// DIELabelPlusOffset Implementation +//===----------------------------------------------------------------------===// + +/// EmitValue - Emit lable plus offset value. +/// +void DIELabelPlusOffset::emitValue(const AsmPrinter *AP, + dwarf::Form Form) const { + AP->emitLabelPlusOffset(Label, Offset, SizeOf(AP, Form)); +} + +/// SizeOf - Determine size of delta value in bytes. +/// +unsigned DIELabelPlusOffset::SizeOf(const AsmPrinter *AP, + dwarf::Form Form) const { + switch (Form) { + case dwarf::DW_FORM_data4: + return 4; + case dwarf::DW_FORM_data8: + return 8; + case dwarf::DW_FORM_sec_offset: + return AP->getDwarfOffsetByteSize(); + default: + llvm_unreachable("DIE Value form not supported yet"); + } +} + +LLVM_DUMP_METHOD +void DIELabelPlusOffset::print(raw_ostream &O) const { + O << "Del: " << Label->getName() << "-" << Offset; +} + +//===----------------------------------------------------------------------===// // DIEString Implementation //===----------------------------------------------------------------------===// diff --git a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DIEHash.cpp @@ -319,6 +319,7 @@ case DIEValue::isLabel: case DIEValue::isBaseTypeRef: case DIEValue::isDelta: + case DIEValue::isLabelPlusOffset: llvm_unreachable("Add support for additional value types."); } } diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.h @@ -277,6 +277,10 @@ const MCSymbol *Label, const MCSymbol *Sec); + /// Add a label plus some offset. + DIE::value_iterator addLabelPlusOffset(DIE &Die, dwarf::Attribute Attribute, + const MCSymbol *Label, int64_t Offset); + /// Get context owner's DIE. DIE *createTypeDIE(const DICompositeType *Ty); diff --git a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp --- a/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp @@ -1733,9 +1733,19 @@ new (DIEValueAllocator) DIEDelta(Hi, Lo)); } -DIE::value_iterator -DwarfUnit::addSectionLabel(DIE &Die, dwarf::Attribute Attribute, - const MCSymbol *Label, const MCSymbol *Sec) { +DIE::value_iterator DwarfUnit::addLabelPlusOffset(DIE &Die, + dwarf::Attribute Attribute, + const MCSymbol *Label, + int64_t Offset) { + return Die.addValue( + DIEValueAllocator, Attribute, DD->getDwarfSectionOffsetForm(), + new (DIEValueAllocator) DIELabelPlusOffset(Label, Offset)); +} + +DIE::value_iterator DwarfUnit::addSectionLabel(DIE &Die, + dwarf::Attribute Attribute, + const MCSymbol *Label, + const MCSymbol *Sec) { if (Asm->MAI->doesDwarfUseRelocationsAcrossSections()) return addLabel(Die, Attribute, DD->getDwarfSectionOffsetForm(), Label); return addSectionDelta(Die, Attribute, Label, Sec);