mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-29 10:25:12 +00:00
Add support for producing .deubg_frame sections.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@131121 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -281,7 +281,8 @@ namespace llvm {
|
|||||||
//
|
//
|
||||||
// This emits the frame info section.
|
// This emits the frame info section.
|
||||||
//
|
//
|
||||||
static void Emit(MCStreamer &streamer, bool usingCFI);
|
static void Emit(MCStreamer &streamer, bool usingCFI,
|
||||||
|
bool isEH);
|
||||||
static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
|
static void EmitAdvanceLoc(MCStreamer &Streamer, uint64_t AddrDelta);
|
||||||
static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
|
static void EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
|
||||||
};
|
};
|
||||||
|
@@ -58,6 +58,10 @@ public:
|
|||||||
return TLOF->getEHFrameSection();
|
return TLOF->getEHFrameSection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const MCSection *getDwarfFrameSection() const {
|
||||||
|
return TLOF->getDwarfFrameSection();
|
||||||
|
}
|
||||||
|
|
||||||
unsigned getFDEEncoding(bool CFI) const {
|
unsigned getFDEEncoding(bool CFI) const {
|
||||||
return TLOF->getFDEEncoding(CFI);
|
return TLOF->getFDEEncoding(CFI);
|
||||||
}
|
}
|
||||||
|
@@ -501,10 +501,12 @@ namespace {
|
|||||||
int CFAOffset;
|
int CFAOffset;
|
||||||
int CIENum;
|
int CIENum;
|
||||||
bool UsingCFI;
|
bool UsingCFI;
|
||||||
|
bool IsEH;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FrameEmitterImpl(bool usingCFI) : CFAOffset(0), CIENum(0),
|
FrameEmitterImpl(bool usingCFI, bool isEH) : CFAOffset(0), CIENum(0),
|
||||||
UsingCFI(usingCFI) {
|
UsingCFI(usingCFI),
|
||||||
|
IsEH(isEH) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const MCSymbol &EmitCIE(MCStreamer &streamer,
|
const MCSymbol &EmitCIE(MCStreamer &streamer,
|
||||||
@@ -647,13 +649,15 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
|||||||
streamer.EmitAbsValue(Length, 4);
|
streamer.EmitAbsValue(Length, 4);
|
||||||
|
|
||||||
// CIE ID
|
// CIE ID
|
||||||
streamer.EmitIntValue(0, 4);
|
unsigned CIE_ID = IsEH ? 0 : -1;
|
||||||
|
streamer.EmitIntValue(CIE_ID, 4);
|
||||||
|
|
||||||
// Version
|
// Version
|
||||||
streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
|
streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
|
||||||
|
|
||||||
// Augmentation String
|
// Augmentation String
|
||||||
SmallString<8> Augmentation;
|
SmallString<8> Augmentation;
|
||||||
|
if (IsEH) {
|
||||||
Augmentation += "z";
|
Augmentation += "z";
|
||||||
if (personality)
|
if (personality)
|
||||||
Augmentation += "P";
|
Augmentation += "P";
|
||||||
@@ -661,6 +665,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
|||||||
Augmentation += "L";
|
Augmentation += "L";
|
||||||
Augmentation += "R";
|
Augmentation += "R";
|
||||||
streamer.EmitBytes(Augmentation.str(), 0);
|
streamer.EmitBytes(Augmentation.str(), 0);
|
||||||
|
}
|
||||||
streamer.EmitIntValue(0, 1);
|
streamer.EmitIntValue(0, 1);
|
||||||
|
|
||||||
// Code Alignment Factor
|
// Code Alignment Factor
|
||||||
@@ -675,6 +680,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
|||||||
// Augmentation Data Length (optional)
|
// Augmentation Data Length (optional)
|
||||||
|
|
||||||
unsigned augmentationLength = 0;
|
unsigned augmentationLength = 0;
|
||||||
|
if (IsEH) {
|
||||||
if (personality) {
|
if (personality) {
|
||||||
// Personality Encoding
|
// Personality Encoding
|
||||||
augmentationLength += 1;
|
augmentationLength += 1;
|
||||||
@@ -699,6 +705,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
|||||||
streamer.EmitIntValue(lsdaEncoding, 1); // LSDA Encoding
|
streamer.EmitIntValue(lsdaEncoding, 1); // LSDA Encoding
|
||||||
// Encoding of the FDE pointers
|
// Encoding of the FDE pointers
|
||||||
streamer.EmitIntValue(asmInfo.getFDEEncoding(UsingCFI), 1);
|
streamer.EmitIntValue(asmInfo.getFDEEncoding(UsingCFI), 1);
|
||||||
|
}
|
||||||
|
|
||||||
// Initial Instructions
|
// Initial Instructions
|
||||||
|
|
||||||
@@ -718,7 +725,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
|||||||
EmitCFIInstructions(streamer, Instructions, NULL);
|
EmitCFIInstructions(streamer, Instructions, NULL);
|
||||||
|
|
||||||
// Padding
|
// Padding
|
||||||
streamer.EmitValueToAlignment(4);
|
streamer.EmitValueToAlignment(IsEH ? 4 : asmInfo.getPointerSize());
|
||||||
|
|
||||||
streamer.EmitLabel(sectionEnd);
|
streamer.EmitLabel(sectionEnd);
|
||||||
return *sectionStart;
|
return *sectionStart;
|
||||||
@@ -752,13 +759,16 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
|
|||||||
unsigned size = getSizeForEncoding(streamer, fdeEncoding);
|
unsigned size = getSizeForEncoding(streamer, fdeEncoding);
|
||||||
|
|
||||||
// PC Begin
|
// PC Begin
|
||||||
EmitSymbol(streamer, *frame.Begin, fdeEncoding);
|
unsigned PCBeginEncoding = IsEH ? fdeEncoding : dwarf::DW_EH_PE_absptr;
|
||||||
|
unsigned PCBeginSize = getSizeForEncoding(streamer, PCBeginEncoding);
|
||||||
|
EmitSymbol(streamer, *frame.Begin, PCBeginEncoding);
|
||||||
|
|
||||||
// PC Range
|
// PC Range
|
||||||
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
|
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
|
||||||
*frame.End, 0);
|
*frame.End, 0);
|
||||||
streamer.EmitAbsValue(Range, size);
|
streamer.EmitAbsValue(Range, size);
|
||||||
|
|
||||||
|
if (IsEH) {
|
||||||
// Augmentation Data Length
|
// Augmentation Data Length
|
||||||
unsigned augmentationLength = 0;
|
unsigned augmentationLength = 0;
|
||||||
|
|
||||||
@@ -770,13 +780,14 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
|
|||||||
// Augmentation Data
|
// Augmentation Data
|
||||||
if (frame.Lsda)
|
if (frame.Lsda)
|
||||||
EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding);
|
EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding);
|
||||||
|
}
|
||||||
|
|
||||||
// Call Frame Instructions
|
// Call Frame Instructions
|
||||||
|
|
||||||
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
|
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
|
||||||
|
|
||||||
// Padding
|
// Padding
|
||||||
streamer.EmitValueToAlignment(size);
|
streamer.EmitValueToAlignment(PCBeginSize);
|
||||||
|
|
||||||
return fdeEnd;
|
return fdeEnd;
|
||||||
}
|
}
|
||||||
@@ -823,21 +834,24 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MCDwarfFrameEmitter::Emit(MCStreamer &streamer,
|
void MCDwarfFrameEmitter::Emit(MCStreamer &streamer,
|
||||||
bool usingCFI) {
|
bool usingCFI,
|
||||||
|
bool isEH) {
|
||||||
const MCContext &context = streamer.getContext();
|
const MCContext &context = streamer.getContext();
|
||||||
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
|
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
|
||||||
const MCSection §ion = *asmInfo.getEHFrameSection();
|
const MCSection §ion = isEH ?
|
||||||
|
*asmInfo.getEHFrameSection() : *asmInfo.getDwarfFrameSection();
|
||||||
streamer.SwitchSection(§ion);
|
streamer.SwitchSection(§ion);
|
||||||
|
|
||||||
MCSymbol *fdeEnd = NULL;
|
MCSymbol *fdeEnd = NULL;
|
||||||
DenseMap<CIEKey, const MCSymbol*> CIEStarts;
|
DenseMap<CIEKey, const MCSymbol*> CIEStarts;
|
||||||
FrameEmitterImpl Emitter(usingCFI);
|
FrameEmitterImpl Emitter(usingCFI, isEH);
|
||||||
|
|
||||||
|
const MCSymbol *DummyDebugKey = NULL;
|
||||||
for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
|
for (unsigned i = 0, n = streamer.getNumFrameInfos(); i < n; ++i) {
|
||||||
const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
|
const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
|
||||||
CIEKey key(frame.Personality, frame.PersonalityEncoding,
|
CIEKey key(frame.Personality, frame.PersonalityEncoding,
|
||||||
frame.LsdaEncoding);
|
frame.LsdaEncoding);
|
||||||
const MCSymbol *&cieStart = CIEStarts[key];
|
const MCSymbol *&cieStart = isEH ? CIEStarts[key] : DummyDebugKey;
|
||||||
if (!cieStart)
|
if (!cieStart)
|
||||||
cieStart = &Emitter.EmitCIE(streamer, frame.Personality,
|
cieStart = &Emitter.EmitCIE(streamer, frame.Personality,
|
||||||
frame.PersonalityEncoding, frame.Lsda,
|
frame.PersonalityEncoding, frame.Lsda,
|
||||||
|
@@ -369,5 +369,8 @@ void MCStreamer::EmitFrames(bool usingCFI) {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (EmitEHFrame)
|
if (EmitEHFrame)
|
||||||
MCDwarfFrameEmitter::Emit(*this, usingCFI);
|
MCDwarfFrameEmitter::Emit(*this, usingCFI, true);
|
||||||
|
|
||||||
|
if (EmitDebugFrame)
|
||||||
|
MCDwarfFrameEmitter::Emit(*this, usingCFI, false);
|
||||||
}
|
}
|
||||||
|
42
test/MC/ELF/cfi-sections.s
Normal file
42
test/MC/ELF/cfi-sections.s
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_64 %s
|
||||||
|
// RUN: llvm-mc -filetype=obj -triple i686-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck -check-prefix=ELF_32 %s
|
||||||
|
|
||||||
|
|
||||||
|
// The only difference in gas' output in this test is that we don't produce
|
||||||
|
// the relocations to .debug_frame (we know their values).
|
||||||
|
|
||||||
|
.cfi_sections .debug_frame
|
||||||
|
|
||||||
|
f1:
|
||||||
|
.cfi_startproc
|
||||||
|
nop
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
f2:
|
||||||
|
.cfi_startproc
|
||||||
|
nop
|
||||||
|
.cfi_endproc
|
||||||
|
|
||||||
|
// ELF_64: (('sh_name', 0x00000011) # '.debug_frame'
|
||||||
|
// ELF_64-NEXT: ('sh_type', 0x00000001)
|
||||||
|
// ELF_64-NEXT: ('sh_flags', 0x00000000)
|
||||||
|
// ELF_64-NEXT: ('sh_addr', 0x00000000)
|
||||||
|
// ELF_64-NEXT: ('sh_offset', 0x00000048)
|
||||||
|
// ELF_64-NEXT: ('sh_size', 0x00000048)
|
||||||
|
// ELF_64-NEXT: ('sh_link', 0x00000000)
|
||||||
|
// ELF_64-NEXT: ('sh_info', 0x00000000)
|
||||||
|
// ELF_64-NEXT: ('sh_addralign', 0x00000008)
|
||||||
|
// ELF_64-NEXT: ('sh_entsize', 0x00000000)
|
||||||
|
// ELF_64-NEXT: ('_section_data', '14000000 ffffffff 01000178 100c0708 90010000 00000000 14000000 1c000000 00000000 00000000 01000000 00000000 14000000 34000000 00000000 00000000 01000000 00000000')
|
||||||
|
|
||||||
|
// ELF_32: (('sh_name', 0x00000010) # '.debug_frame'
|
||||||
|
// ELF_32-NEXT: ('sh_type', 0x00000001)
|
||||||
|
// ELF_32-NEXT: ('sh_flags', 0x00000000)
|
||||||
|
// ELF_32-NEXT: ('sh_addr', 0x00000000)
|
||||||
|
// ELF_32-NEXT: ('sh_offset', 0x00000038)
|
||||||
|
// ELF_32-NEXT: ('sh_size', 0x00000034)
|
||||||
|
// ELF_32-NEXT: ('sh_link', 0x00000000)
|
||||||
|
// ELF_32-NEXT: ('sh_info', 0x00000000)
|
||||||
|
// ELF_32-NEXT: ('sh_addralign', 0x00000004)
|
||||||
|
// ELF_32-NEXT: ('sh_entsize', 0x00000000)
|
||||||
|
// ELF_32-NEXT: ('_section_data', '10000000 ffffffff 0100017c 080c0404 88010000 0c000000 18000000 00000000 01000000 0c000000 28000000 01000000 01000000')
|
Reference in New Issue
Block a user