mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-28 19:31:58 +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:
parent
774466a8a5
commit
40a7dbbeff
@ -281,7 +281,8 @@ namespace llvm {
|
||||
//
|
||||
// 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 EncodeAdvanceLoc(uint64_t AddrDelta, raw_ostream &OS);
|
||||
};
|
||||
|
@ -58,6 +58,10 @@ public:
|
||||
return TLOF->getEHFrameSection();
|
||||
}
|
||||
|
||||
const MCSection *getDwarfFrameSection() const {
|
||||
return TLOF->getDwarfFrameSection();
|
||||
}
|
||||
|
||||
unsigned getFDEEncoding(bool CFI) const {
|
||||
return TLOF->getFDEEncoding(CFI);
|
||||
}
|
||||
|
@ -501,10 +501,12 @@ namespace {
|
||||
int CFAOffset;
|
||||
int CIENum;
|
||||
bool UsingCFI;
|
||||
bool IsEH;
|
||||
|
||||
public:
|
||||
FrameEmitterImpl(bool usingCFI) : CFAOffset(0), CIENum(0),
|
||||
UsingCFI(usingCFI) {
|
||||
FrameEmitterImpl(bool usingCFI, bool isEH) : CFAOffset(0), CIENum(0),
|
||||
UsingCFI(usingCFI),
|
||||
IsEH(isEH) {
|
||||
}
|
||||
|
||||
const MCSymbol &EmitCIE(MCStreamer &streamer,
|
||||
@ -647,20 +649,23 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
streamer.EmitAbsValue(Length, 4);
|
||||
|
||||
// CIE ID
|
||||
streamer.EmitIntValue(0, 4);
|
||||
unsigned CIE_ID = IsEH ? 0 : -1;
|
||||
streamer.EmitIntValue(CIE_ID, 4);
|
||||
|
||||
// Version
|
||||
streamer.EmitIntValue(dwarf::DW_CIE_VERSION, 1);
|
||||
|
||||
// Augmentation String
|
||||
SmallString<8> Augmentation;
|
||||
Augmentation += "z";
|
||||
if (personality)
|
||||
Augmentation += "P";
|
||||
if (lsda)
|
||||
Augmentation += "L";
|
||||
Augmentation += "R";
|
||||
streamer.EmitBytes(Augmentation.str(), 0);
|
||||
if (IsEH) {
|
||||
Augmentation += "z";
|
||||
if (personality)
|
||||
Augmentation += "P";
|
||||
if (lsda)
|
||||
Augmentation += "L";
|
||||
Augmentation += "R";
|
||||
streamer.EmitBytes(Augmentation.str(), 0);
|
||||
}
|
||||
streamer.EmitIntValue(0, 1);
|
||||
|
||||
// Code Alignment Factor
|
||||
@ -675,30 +680,32 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
// Augmentation Data Length (optional)
|
||||
|
||||
unsigned augmentationLength = 0;
|
||||
if (personality) {
|
||||
// Personality Encoding
|
||||
if (IsEH) {
|
||||
if (personality) {
|
||||
// Personality Encoding
|
||||
augmentationLength += 1;
|
||||
// Personality
|
||||
augmentationLength += getSizeForEncoding(streamer, personalityEncoding);
|
||||
}
|
||||
if (lsda)
|
||||
augmentationLength += 1;
|
||||
// Encoding of the FDE pointers
|
||||
augmentationLength += 1;
|
||||
// Personality
|
||||
augmentationLength += getSizeForEncoding(streamer, personalityEncoding);
|
||||
}
|
||||
if (lsda)
|
||||
augmentationLength += 1;
|
||||
// Encoding of the FDE pointers
|
||||
augmentationLength += 1;
|
||||
|
||||
streamer.EmitULEB128IntValue(augmentationLength);
|
||||
streamer.EmitULEB128IntValue(augmentationLength);
|
||||
|
||||
// Augmentation Data (optional)
|
||||
if (personality) {
|
||||
// Personality Encoding
|
||||
streamer.EmitIntValue(personalityEncoding, 1);
|
||||
// Personality
|
||||
EmitPersonality(streamer, *personality, personalityEncoding);
|
||||
// Augmentation Data (optional)
|
||||
if (personality) {
|
||||
// Personality Encoding
|
||||
streamer.EmitIntValue(personalityEncoding, 1);
|
||||
// Personality
|
||||
EmitPersonality(streamer, *personality, personalityEncoding);
|
||||
}
|
||||
if (lsda)
|
||||
streamer.EmitIntValue(lsdaEncoding, 1); // LSDA Encoding
|
||||
// Encoding of the FDE pointers
|
||||
streamer.EmitIntValue(asmInfo.getFDEEncoding(UsingCFI), 1);
|
||||
}
|
||||
if (lsda)
|
||||
streamer.EmitIntValue(lsdaEncoding, 1); // LSDA Encoding
|
||||
// Encoding of the FDE pointers
|
||||
streamer.EmitIntValue(asmInfo.getFDEEncoding(UsingCFI), 1);
|
||||
|
||||
// Initial Instructions
|
||||
|
||||
@ -718,7 +725,7 @@ const MCSymbol &FrameEmitterImpl::EmitCIE(MCStreamer &streamer,
|
||||
EmitCFIInstructions(streamer, Instructions, NULL);
|
||||
|
||||
// Padding
|
||||
streamer.EmitValueToAlignment(4);
|
||||
streamer.EmitValueToAlignment(IsEH ? 4 : asmInfo.getPointerSize());
|
||||
|
||||
streamer.EmitLabel(sectionEnd);
|
||||
return *sectionStart;
|
||||
@ -752,31 +759,35 @@ MCSymbol *FrameEmitterImpl::EmitFDE(MCStreamer &streamer,
|
||||
unsigned size = getSizeForEncoding(streamer, fdeEncoding);
|
||||
|
||||
// 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
|
||||
const MCExpr *Range = MakeStartMinusEndExpr(streamer, *frame.Begin,
|
||||
*frame.End, 0);
|
||||
streamer.EmitAbsValue(Range, size);
|
||||
|
||||
// Augmentation Data Length
|
||||
unsigned augmentationLength = 0;
|
||||
if (IsEH) {
|
||||
// Augmentation Data Length
|
||||
unsigned augmentationLength = 0;
|
||||
|
||||
if (frame.Lsda)
|
||||
augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);
|
||||
if (frame.Lsda)
|
||||
augmentationLength += getSizeForEncoding(streamer, frame.LsdaEncoding);
|
||||
|
||||
streamer.EmitULEB128IntValue(augmentationLength);
|
||||
streamer.EmitULEB128IntValue(augmentationLength);
|
||||
|
||||
// Augmentation Data
|
||||
if (frame.Lsda)
|
||||
EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding);
|
||||
// Augmentation Data
|
||||
if (frame.Lsda)
|
||||
EmitSymbol(streamer, *frame.Lsda, frame.LsdaEncoding);
|
||||
}
|
||||
|
||||
// Call Frame Instructions
|
||||
|
||||
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
|
||||
|
||||
// Padding
|
||||
streamer.EmitValueToAlignment(size);
|
||||
streamer.EmitValueToAlignment(PCBeginSize);
|
||||
|
||||
return fdeEnd;
|
||||
}
|
||||
@ -823,21 +834,24 @@ namespace llvm {
|
||||
}
|
||||
|
||||
void MCDwarfFrameEmitter::Emit(MCStreamer &streamer,
|
||||
bool usingCFI) {
|
||||
bool usingCFI,
|
||||
bool isEH) {
|
||||
const MCContext &context = streamer.getContext();
|
||||
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
|
||||
const MCSection §ion = *asmInfo.getEHFrameSection();
|
||||
const MCSection §ion = isEH ?
|
||||
*asmInfo.getEHFrameSection() : *asmInfo.getDwarfFrameSection();
|
||||
streamer.SwitchSection(§ion);
|
||||
|
||||
MCSymbol *fdeEnd = NULL;
|
||||
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) {
|
||||
const MCDwarfFrameInfo &frame = streamer.getFrameInfo(i);
|
||||
CIEKey key(frame.Personality, frame.PersonalityEncoding,
|
||||
frame.LsdaEncoding);
|
||||
const MCSymbol *&cieStart = CIEStarts[key];
|
||||
const MCSymbol *&cieStart = isEH ? CIEStarts[key] : DummyDebugKey;
|
||||
if (!cieStart)
|
||||
cieStart = &Emitter.EmitCIE(streamer, frame.Personality,
|
||||
frame.PersonalityEncoding, frame.Lsda,
|
||||
|
@ -369,5 +369,8 @@ void MCStreamer::EmitFrames(bool usingCFI) {
|
||||
return;
|
||||
|
||||
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')
|
Loading…
Reference in New Issue
Block a user