Skip to content

Commit 18ccfad

Browse files
committed
[DebugInfo] Generate fixups as emitting DWARF .debug_frame/.eh_frame.
It is necessary to generate fixups in .debug_frame or .eh_frame as relaxation is enabled due to the address delta may be changed after relaxation. There is an opcode with 6-bits data in debug frame encoding. So, we also need 6-bits fixup types. Differential Revision: https://reviews.llvm.org/D58335 llvm-svn: 366524
1 parent ccbffef commit 18ccfad

File tree

16 files changed

+234
-88
lines changed

16 files changed

+234
-88
lines changed

llvm/include/llvm/DebugInfo/DWARF/DWARFDebugFrame.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class CFIProgram {
6969
/// starting at *Offset and ending at EndOffset. *Offset is updated
7070
/// to EndOffset upon successful parsing, or indicates the offset
7171
/// where a problem occurred in case an error is returned.
72-
Error parse(DataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
72+
Error parse(DWARFDataExtractor Data, uint32_t *Offset, uint32_t EndOffset);
7373

7474
void dump(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
7575
unsigned IndentLevel = 1) const;

llvm/include/llvm/DebugInfo/DWARF/DWARFObject.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ class DWARFObject {
4040
virtual const DWARFSection &getLocSection() const { return Dummy; }
4141
virtual const DWARFSection &getLoclistsSection() const { return Dummy; }
4242
virtual StringRef getARangeSection() const { return ""; }
43-
virtual StringRef getDebugFrameSection() const { return ""; }
44-
virtual StringRef getEHFrameSection() const { return ""; }
43+
virtual const DWARFSection &getDebugFrameSection() const { return Dummy; }
44+
virtual const DWARFSection &getEHFrameSection() const { return Dummy; }
4545
virtual const DWARFSection &getLineSection() const { return Dummy; }
4646
virtual StringRef getLineStringSection() const { return ""; }
4747
virtual StringRef getStringSection() const { return ""; }

llvm/include/llvm/MC/MCDwarf.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -629,7 +629,8 @@ class MCDwarfFrameEmitter {
629629
static void Emit(MCObjectStreamer &streamer, MCAsmBackend *MAB, bool isEH);
630630
static void EmitAdvanceLoc(MCObjectStreamer &Streamer, uint64_t AddrDelta);
631631
static void EncodeAdvanceLoc(MCContext &Context, uint64_t AddrDelta,
632-
raw_ostream &OS);
632+
raw_ostream &OS, uint32_t *Offset = nullptr,
633+
uint32_t *Size = nullptr);
633634
};
634635

635636
} // end namespace llvm

llvm/include/llvm/MC/MCFixup.h

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,35 +20,38 @@ class MCExpr;
2020

2121
/// Extensible enumeration to represent the type of a fixup.
2222
enum MCFixupKind {
23-
FK_NONE = 0, ///< A no-op fixup.
24-
FK_Data_1, ///< A one-byte fixup.
25-
FK_Data_2, ///< A two-byte fixup.
26-
FK_Data_4, ///< A four-byte fixup.
27-
FK_Data_8, ///< A eight-byte fixup.
28-
FK_PCRel_1, ///< A one-byte pc relative fixup.
29-
FK_PCRel_2, ///< A two-byte pc relative fixup.
30-
FK_PCRel_4, ///< A four-byte pc relative fixup.
31-
FK_PCRel_8, ///< A eight-byte pc relative fixup.
32-
FK_GPRel_1, ///< A one-byte gp relative fixup.
33-
FK_GPRel_2, ///< A two-byte gp relative fixup.
34-
FK_GPRel_4, ///< A four-byte gp relative fixup.
35-
FK_GPRel_8, ///< A eight-byte gp relative fixup.
36-
FK_DTPRel_4, ///< A four-byte dtp relative fixup.
37-
FK_DTPRel_8, ///< A eight-byte dtp relative fixup.
38-
FK_TPRel_4, ///< A four-byte tp relative fixup.
39-
FK_TPRel_8, ///< A eight-byte tp relative fixup.
40-
FK_SecRel_1, ///< A one-byte section relative fixup.
41-
FK_SecRel_2, ///< A two-byte section relative fixup.
42-
FK_SecRel_4, ///< A four-byte section relative fixup.
43-
FK_SecRel_8, ///< A eight-byte section relative fixup.
44-
FK_Data_Add_1, ///< A one-byte add fixup.
45-
FK_Data_Add_2, ///< A two-byte add fixup.
46-
FK_Data_Add_4, ///< A four-byte add fixup.
47-
FK_Data_Add_8, ///< A eight-byte add fixup.
48-
FK_Data_Sub_1, ///< A one-byte sub fixup.
49-
FK_Data_Sub_2, ///< A two-byte sub fixup.
50-
FK_Data_Sub_4, ///< A four-byte sub fixup.
51-
FK_Data_Sub_8, ///< A eight-byte sub fixup.
23+
FK_NONE = 0, ///< A no-op fixup.
24+
FK_Data_1, ///< A one-byte fixup.
25+
FK_Data_2, ///< A two-byte fixup.
26+
FK_Data_4, ///< A four-byte fixup.
27+
FK_Data_8, ///< A eight-byte fixup.
28+
FK_Data_6b, ///< A six-bits fixup.
29+
FK_PCRel_1, ///< A one-byte pc relative fixup.
30+
FK_PCRel_2, ///< A two-byte pc relative fixup.
31+
FK_PCRel_4, ///< A four-byte pc relative fixup.
32+
FK_PCRel_8, ///< A eight-byte pc relative fixup.
33+
FK_GPRel_1, ///< A one-byte gp relative fixup.
34+
FK_GPRel_2, ///< A two-byte gp relative fixup.
35+
FK_GPRel_4, ///< A four-byte gp relative fixup.
36+
FK_GPRel_8, ///< A eight-byte gp relative fixup.
37+
FK_DTPRel_4, ///< A four-byte dtp relative fixup.
38+
FK_DTPRel_8, ///< A eight-byte dtp relative fixup.
39+
FK_TPRel_4, ///< A four-byte tp relative fixup.
40+
FK_TPRel_8, ///< A eight-byte tp relative fixup.
41+
FK_SecRel_1, ///< A one-byte section relative fixup.
42+
FK_SecRel_2, ///< A two-byte section relative fixup.
43+
FK_SecRel_4, ///< A four-byte section relative fixup.
44+
FK_SecRel_8, ///< A eight-byte section relative fixup.
45+
FK_Data_Add_1, ///< A one-byte add fixup.
46+
FK_Data_Add_2, ///< A two-byte add fixup.
47+
FK_Data_Add_4, ///< A four-byte add fixup.
48+
FK_Data_Add_8, ///< A eight-byte add fixup.
49+
FK_Data_Add_6b, ///< A six-bits add fixup.
50+
FK_Data_Sub_1, ///< A one-byte sub fixup.
51+
FK_Data_Sub_2, ///< A two-byte sub fixup.
52+
FK_Data_Sub_4, ///< A four-byte sub fixup.
53+
FK_Data_Sub_8, ///< A eight-byte sub fixup.
54+
FK_Data_Sub_6b, ///< A six-bits sub fixup.
5255

5356
FirstTargetFixupKind = 128,
5457

@@ -129,13 +132,37 @@ class MCFixup {
129132

130133
/// Return the generic fixup kind for a value with the given size. It
131134
/// is an error to pass an unsupported size.
132-
static MCFixupKind getKindForSize(unsigned Size, bool isPCRel) {
135+
static MCFixupKind getKindForSize(unsigned Size, bool IsPCRel) {
133136
switch (Size) {
134137
default: llvm_unreachable("Invalid generic fixup size!");
135-
case 1: return isPCRel ? FK_PCRel_1 : FK_Data_1;
136-
case 2: return isPCRel ? FK_PCRel_2 : FK_Data_2;
137-
case 4: return isPCRel ? FK_PCRel_4 : FK_Data_4;
138-
case 8: return isPCRel ? FK_PCRel_8 : FK_Data_8;
138+
case 1:
139+
return IsPCRel ? FK_PCRel_1 : FK_Data_1;
140+
case 2:
141+
return IsPCRel ? FK_PCRel_2 : FK_Data_2;
142+
case 4:
143+
return IsPCRel ? FK_PCRel_4 : FK_Data_4;
144+
case 8:
145+
return IsPCRel ? FK_PCRel_8 : FK_Data_8;
146+
}
147+
}
148+
149+
/// Return the generic fixup kind for a value with the given size in bits.
150+
/// It is an error to pass an unsupported size.
151+
static MCFixupKind getKindForSizeInBits(unsigned Size, bool IsPCRel) {
152+
switch (Size) {
153+
default:
154+
llvm_unreachable("Invalid generic fixup size!");
155+
case 6:
156+
assert(!IsPCRel && "Invalid pc-relative fixup size!");
157+
return FK_Data_6b;
158+
case 8:
159+
return IsPCRel ? FK_PCRel_1 : FK_Data_1;
160+
case 16:
161+
return IsPCRel ? FK_PCRel_2 : FK_Data_2;
162+
case 32:
163+
return IsPCRel ? FK_PCRel_4 : FK_Data_4;
164+
case 64:
165+
return IsPCRel ? FK_PCRel_8 : FK_Data_8;
139166
}
140167
}
141168

@@ -148,6 +175,7 @@ class MCFixup {
148175
case FK_Data_2: return FK_Data_Add_2;
149176
case FK_Data_4: return FK_Data_Add_4;
150177
case FK_Data_8: return FK_Data_Add_8;
178+
case FK_Data_6b: return FK_Data_Add_6b;
151179
}
152180
}
153181

@@ -160,6 +188,7 @@ class MCFixup {
160188
case FK_Data_2: return FK_Data_Sub_2;
161189
case FK_Data_4: return FK_Data_Sub_4;
162190
case FK_Data_8: return FK_Data_Sub_8;
191+
case FK_Data_6b: return FK_Data_Sub_6b;
163192
}
164193
}
165194

llvm/include/llvm/MC/MCFragment.h

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class MCEncodedFragment : public MCFragment {
149149
case MCFragment::FT_CompactEncodedInst:
150150
case MCFragment::FT_Data:
151151
case MCFragment::FT_Dwarf:
152+
case MCFragment::FT_DwarfFrame:
152153
return true;
153154
}
154155
}
@@ -232,7 +233,8 @@ class MCEncodedFragmentWithFixups :
232233
static bool classof(const MCFragment *F) {
233234
MCFragment::FragmentType Kind = F->getKind();
234235
return Kind == MCFragment::FT_Relaxable || Kind == MCFragment::FT_Data ||
235-
Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf;;
236+
Kind == MCFragment::FT_CVDefRange || Kind == MCFragment::FT_Dwarf ||
237+
Kind == MCFragment::FT_DwarfFrame;
236238
}
237239
};
238240

@@ -543,27 +545,21 @@ class MCDwarfLineAddrFragment : public MCEncodedFragmentWithFixups<8, 1> {
543545
}
544546
};
545547

546-
class MCDwarfCallFrameFragment : public MCFragment {
548+
class MCDwarfCallFrameFragment : public MCEncodedFragmentWithFixups<8, 1> {
547549
/// AddrDelta - The expression for the difference of the two symbols that
548550
/// make up the address delta between two .cfi_* dwarf directives.
549551
const MCExpr *AddrDelta;
550552

551-
SmallString<8> Contents;
552-
553553
public:
554554
MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr)
555-
: MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) {
556-
Contents.push_back(0);
557-
}
555+
: MCEncodedFragmentWithFixups<8, 1>(FT_DwarfFrame, false, Sec),
556+
AddrDelta(&AddrDelta) {}
558557

559558
/// \name Accessors
560559
/// @{
561560

562561
const MCExpr &getAddrDelta() const { return *AddrDelta; }
563562

564-
SmallString<8> &getContents() { return Contents; }
565-
const SmallString<8> &getContents() const { return Contents; }
566-
567563
/// @}
568564

569565
static bool classof(const MCFragment *F) {

llvm/lib/DebugInfo/DWARF/DWARFContext.cpp

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -402,11 +402,11 @@ void DWARFContext::dump(
402402
}
403403

404404
if (const auto *Off = shouldDump(Explicit, ".debug_frame", DIDT_ID_DebugFrame,
405-
DObj->getDebugFrameSection()))
405+
DObj->getDebugFrameSection().Data))
406406
getDebugFrame()->dump(OS, getRegisterInfo(), *Off);
407407

408408
if (const auto *Off = shouldDump(Explicit, ".eh_frame", DIDT_ID_DebugFrame,
409-
DObj->getEHFrameSection()))
409+
DObj->getEHFrameSection().Data))
410410
getEHFrame()->dump(OS, getRegisterInfo(), *Off);
411411

412412
if (DumpType & DIDT_DebugMacro) {
@@ -766,7 +766,7 @@ const DWARFDebugFrame *DWARFContext::getDebugFrame() {
766766
// provides this information). This problem is fixed in DWARFv4
767767
// See this dwarf-discuss discussion for more details:
768768
// http://lists.dwarfstd.org/htdig.cgi/dwarf-discuss-dwarfstd.org/2011-December/001173.html
769-
DWARFDataExtractor debugFrameData(DObj->getDebugFrameSection(),
769+
DWARFDataExtractor debugFrameData(*DObj, DObj->getDebugFrameSection(),
770770
isLittleEndian(), DObj->getAddressSize());
771771
DebugFrame.reset(new DWARFDebugFrame(getArch(), false /* IsEH */));
772772
DebugFrame->parse(debugFrameData);
@@ -777,8 +777,8 @@ const DWARFDebugFrame *DWARFContext::getEHFrame() {
777777
if (EHFrame)
778778
return EHFrame.get();
779779

780-
DWARFDataExtractor debugFrameData(DObj->getEHFrameSection(), isLittleEndian(),
781-
DObj->getAddressSize());
780+
DWARFDataExtractor debugFrameData(*DObj, DObj->getEHFrameSection(),
781+
isLittleEndian(), DObj->getAddressSize());
782782
DebugFrame.reset(new DWARFDebugFrame(getArch(), true /* IsEH */));
783783
DebugFrame->parse(debugFrameData);
784784
return DebugFrame.get();
@@ -1385,6 +1385,8 @@ class DWARFObjInMemory final : public DWARFObject {
13851385
DWARFSectionMap RnglistsSection;
13861386
DWARFSectionMap StringOffsetSection;
13871387
DWARFSectionMap LineDWOSection;
1388+
DWARFSectionMap DebugFrameSection;
1389+
DWARFSectionMap EHFrameSection;
13881390
DWARFSectionMap LocDWOSection;
13891391
DWARFSectionMap StringOffsetDWOSection;
13901392
DWARFSectionMap RangeDWOSection;
@@ -1405,6 +1407,8 @@ class DWARFObjInMemory final : public DWARFObject {
14051407
.Case("debug_loc", &LocSection)
14061408
.Case("debug_loclists", &LocListsSection)
14071409
.Case("debug_line", &LineSection)
1410+
.Case("debug_frame", &DebugFrameSection)
1411+
.Case("eh_frame", &EHFrameSection)
14081412
.Case("debug_str_offsets", &StringOffsetSection)
14091413
.Case("debug_ranges", &RangeSection)
14101414
.Case("debug_rnglists", &RnglistsSection)
@@ -1428,8 +1432,6 @@ class DWARFObjInMemory final : public DWARFObject {
14281432

14291433
StringRef AbbrevSection;
14301434
StringRef ARangeSection;
1431-
StringRef DebugFrameSection;
1432-
StringRef EHFrameSection;
14331435
StringRef StringSection;
14341436
StringRef MacinfoSection;
14351437
StringRef AbbrevDWOSection;
@@ -1449,8 +1451,6 @@ class DWARFObjInMemory final : public DWARFObject {
14491451
return StringSwitch<StringRef *>(Name)
14501452
.Case("debug_abbrev", &AbbrevSection)
14511453
.Case("debug_aranges", &ARangeSection)
1452-
.Case("debug_frame", &DebugFrameSection)
1453-
.Case("eh_frame", &EHFrameSection)
14541454
.Case("debug_str", &StringSection)
14551455
.Case("debug_macinfo", &MacinfoSection)
14561456
.Case("debug_abbrev.dwo", &AbbrevDWOSection)
@@ -1747,8 +1747,12 @@ class DWARFObjInMemory final : public DWARFObject {
17471747
const DWARFSection &getLocSection() const override { return LocSection; }
17481748
const DWARFSection &getLoclistsSection() const override { return LocListsSection; }
17491749
StringRef getARangeSection() const override { return ARangeSection; }
1750-
StringRef getDebugFrameSection() const override { return DebugFrameSection; }
1751-
StringRef getEHFrameSection() const override { return EHFrameSection; }
1750+
const DWARFSection &getDebugFrameSection() const override {
1751+
return DebugFrameSection;
1752+
}
1753+
const DWARFSection &getEHFrameSection() const override {
1754+
return EHFrameSection;
1755+
}
17521756
const DWARFSection &getLineSection() const override { return LineSection; }
17531757
StringRef getStringSection() const override { return StringSection; }
17541758
const DWARFSection &getRangeSection() const override { return RangeSection; }

llvm/lib/DebugInfo/DWARF/DWARFDebugFrame.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ using namespace dwarf;
3434
const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
3535
const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
3636

37-
Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
37+
Error CFIProgram::parse(DWARFDataExtractor Data, uint32_t *Offset,
3838
uint32_t EndOffset) {
3939
while (*Offset < EndOffset) {
40-
uint8_t Opcode = Data.getU8(Offset);
40+
uint8_t Opcode = Data.getRelocatedValue(1, Offset);
4141
// Some instructions have a primary opcode encoded in the top bits.
4242
uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK;
4343

@@ -74,19 +74,19 @@ Error CFIProgram::parse(DataExtractor Data, uint32_t *Offset,
7474
break;
7575
case DW_CFA_set_loc:
7676
// Operands: Address
77-
addInstruction(Opcode, Data.getAddress(Offset));
77+
addInstruction(Opcode, Data.getRelocatedAddress(Offset));
7878
break;
7979
case DW_CFA_advance_loc1:
8080
// Operands: 1-byte delta
81-
addInstruction(Opcode, Data.getU8(Offset));
81+
addInstruction(Opcode, Data.getRelocatedValue(1, Offset));
8282
break;
8383
case DW_CFA_advance_loc2:
8484
// Operands: 2-byte delta
85-
addInstruction(Opcode, Data.getU16(Offset));
85+
addInstruction(Opcode, Data.getRelocatedValue(2, Offset));
8686
break;
8787
case DW_CFA_advance_loc4:
8888
// Operands: 4-byte delta
89-
addInstruction(Opcode, Data.getU32(Offset));
89+
addInstruction(Opcode, Data.getRelocatedValue(4, Offset));
9090
break;
9191
case DW_CFA_restore_extended:
9292
case DW_CFA_undefined:
@@ -361,15 +361,15 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
361361
uint32_t StartOffset = Offset;
362362

363363
bool IsDWARF64 = false;
364-
uint64_t Length = Data.getU32(&Offset);
364+
uint64_t Length = Data.getRelocatedValue(4, &Offset);
365365
uint64_t Id;
366366

367367
if (Length == UINT32_MAX) {
368368
// DWARF-64 is distinguished by the first 32 bits of the initial length
369369
// field being 0xffffffff. Then, the next 64 bits are the actual entry
370370
// length.
371371
IsDWARF64 = true;
372-
Length = Data.getU64(&Offset);
372+
Length = Data.getRelocatedValue(8, &Offset);
373373
}
374374

375375
// At this point, Offset points to the next field after Length.
@@ -512,8 +512,8 @@ void DWARFDebugFrame::parse(DWARFDataExtractor Data) {
512512
ReportError(StartOffset, "Parsing augmentation data at %lx failed");
513513
}
514514
} else {
515-
InitialLocation = Data.getAddress(&Offset);
516-
AddressRange = Data.getAddress(&Offset);
515+
InitialLocation = Data.getRelocatedAddress(&Offset);
516+
AddressRange = Data.getRelocatedAddress(&Offset);
517517
}
518518

519519
Entries.emplace_back(new FDE(StartOffset, Length, CIEPointer,

llvm/lib/MC/MCAsmBackend.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
7373
{"FK_Data_2", 0, 16, 0},
7474
{"FK_Data_4", 0, 32, 0},
7575
{"FK_Data_8", 0, 64, 0},
76+
{"FK_Data_6b", 0, 6, 0},
7677
{"FK_PCRel_1", 0, 8, MCFixupKindInfo::FKF_IsPCRel},
7778
{"FK_PCRel_2", 0, 16, MCFixupKindInfo::FKF_IsPCRel},
7879
{"FK_PCRel_4", 0, 32, MCFixupKindInfo::FKF_IsPCRel},
@@ -93,10 +94,12 @@ const MCFixupKindInfo &MCAsmBackend::getFixupKindInfo(MCFixupKind Kind) const {
9394
{"FK_Data_Add_2", 0, 16, 0},
9495
{"FK_Data_Add_4", 0, 32, 0},
9596
{"FK_Data_Add_8", 0, 64, 0},
97+
{"FK_Data_Add_6b", 0, 6, 0},
9698
{"FK_Data_Sub_1", 0, 8, 0},
9799
{"FK_Data_Sub_2", 0, 16, 0},
98100
{"FK_Data_Sub_4", 0, 32, 0},
99-
{"FK_Data_Sub_8", 0, 64, 0}};
101+
{"FK_Data_Sub_8", 0, 64, 0},
102+
{"FK_Data_Sub_6b", 0, 6, 0}};
100103

101104
assert((size_t)Kind <= array_lengthof(Builtins) && "Unknown fixup kind");
102105
return Builtins[Kind];

0 commit comments

Comments
 (0)