forked from OSchip/llvm-project
Implement cfi_def_cfa. Also don't convert to dwarf reg numbers twice. Looks
like 6 is a fixed point of that and so the previous tests were OK :-) llvm-svn: 122614
This commit is contained in:
parent
1be1fe033c
commit
290d71671e
|
@ -395,6 +395,7 @@ namespace llvm {
|
|||
|
||||
virtual bool EmitCFIStartProc();
|
||||
virtual bool EmitCFIEndProc();
|
||||
virtual bool EmitCFIDefCfa(int64_t Register, int64_t Offset);
|
||||
virtual bool EmitCFIDefCfaOffset(int64_t Offset);
|
||||
virtual bool EmitCFIDefCfaRegister(int64_t Register);
|
||||
virtual bool EmitCFIOffset(int64_t Register, int64_t Offset);
|
||||
|
|
|
@ -440,10 +440,7 @@ static int getDataAlignmentFactor(MCStreamer &streamer) {
|
|||
}
|
||||
|
||||
static void EmitCFIInstruction(MCStreamer &Streamer,
|
||||
const MCCFIInstruction &Instr,
|
||||
bool isEH) {
|
||||
MCContext &context = Streamer.getContext();
|
||||
const TargetAsmInfo &asmInfo = context.getTargetAsmInfo();
|
||||
const MCCFIInstruction &Instr) {
|
||||
int dataAlignmentFactor = getDataAlignmentFactor(Streamer);
|
||||
|
||||
switch (Instr.getOperation()) {
|
||||
|
@ -459,8 +456,7 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
|
|||
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_offset, 1);
|
||||
} else {
|
||||
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa, 1);
|
||||
Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Src.getReg(),
|
||||
isEH));
|
||||
Streamer.EmitULEB128IntValue(Src.getReg());
|
||||
}
|
||||
|
||||
Streamer.EmitULEB128IntValue(-Src.getOffset(), 1);
|
||||
|
@ -470,11 +466,11 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
|
|||
if (Src.isReg() && Src.getReg() == MachineLocation::VirtualFP) {
|
||||
assert(Dst.isReg() && "Machine move not supported yet.");
|
||||
Streamer.EmitIntValue(dwarf::DW_CFA_def_cfa_register, 1);
|
||||
Streamer.EmitULEB128IntValue(asmInfo.getDwarfRegNum(Dst.getReg(), isEH));
|
||||
Streamer.EmitULEB128IntValue(Dst.getReg());
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned Reg = asmInfo.getDwarfRegNum(Src.getReg(), isEH);
|
||||
unsigned Reg = Src.getReg();
|
||||
int Offset = Dst.getOffset() / dataAlignmentFactor;
|
||||
|
||||
if (Offset < 0) {
|
||||
|
@ -505,7 +501,7 @@ static void EmitCFIInstruction(MCStreamer &Streamer,
|
|||
/// frame.
|
||||
static void EmitCFIInstructions(MCStreamer &streamer,
|
||||
const std::vector<MCCFIInstruction> &Instrs,
|
||||
MCSymbol *BaseLabel, bool isEH) {
|
||||
MCSymbol *BaseLabel) {
|
||||
for (unsigned i = 0, N = Instrs.size(); i < N; ++i) {
|
||||
const MCCFIInstruction &Instr = Instrs[i];
|
||||
MCSymbol *Label = Instr.getLabel();
|
||||
|
@ -521,7 +517,7 @@ static void EmitCFIInstructions(MCStreamer &streamer,
|
|||
}
|
||||
}
|
||||
|
||||
EmitCFIInstruction(streamer, Instr, isEH);
|
||||
EmitCFIInstruction(streamer, Instr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,6 +562,17 @@ static void EmitSymbol(MCStreamer &streamer, const MCSymbol &symbol,
|
|||
}
|
||||
}
|
||||
|
||||
static const MachineLocation TranslateMachineLocation(
|
||||
const TargetAsmInfo &AsmInfo,
|
||||
const MachineLocation &Loc) {
|
||||
unsigned Reg = Loc.getReg() == MachineLocation::VirtualFP ?
|
||||
MachineLocation::VirtualFP :
|
||||
unsigned(AsmInfo.getDwarfRegNum(Loc.getReg(), true));
|
||||
const MachineLocation &NewLoc = Loc.isReg() ?
|
||||
MachineLocation(Reg) : MachineLocation(Reg, Loc.getOffset());
|
||||
return NewLoc;
|
||||
}
|
||||
|
||||
static const MCSymbol &EmitCIE(MCStreamer &streamer,
|
||||
const MCSymbol *personality,
|
||||
unsigned personalityEncoding,
|
||||
|
@ -640,12 +647,16 @@ static const MCSymbol &EmitCIE(MCStreamer &streamer,
|
|||
std::vector<MCCFIInstruction> Instructions;
|
||||
|
||||
for (int i = 0, n = Moves.size(); i != n; ++i) {
|
||||
MCCFIInstruction Inst(Moves[i].getLabel(), Moves[i].getDestination(),
|
||||
Moves[i].getSource());
|
||||
MCSymbol *Label = Moves[i].getLabel();
|
||||
const MachineLocation &Dst =
|
||||
TranslateMachineLocation(asmInfo, Moves[i].getDestination());
|
||||
const MachineLocation &Src =
|
||||
TranslateMachineLocation(asmInfo, Moves[i].getSource());
|
||||
MCCFIInstruction Inst(Label, Dst, Src);
|
||||
Instructions.push_back(Inst);
|
||||
}
|
||||
|
||||
EmitCFIInstructions(streamer, Instructions, NULL, true);
|
||||
EmitCFIInstructions(streamer, Instructions, NULL);
|
||||
|
||||
// Padding
|
||||
streamer.EmitValueToAlignment(4);
|
||||
|
@ -694,7 +705,7 @@ static MCSymbol *EmitFDE(MCStreamer &streamer,
|
|||
streamer.EmitLabel(augmentationEnd);
|
||||
// Call Frame Instructions
|
||||
|
||||
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin, true);
|
||||
EmitCFIInstructions(streamer, frame.Instructions, frame.Begin);
|
||||
|
||||
// Padding
|
||||
streamer.EmitValueToAlignment(4);
|
||||
|
|
|
@ -244,6 +244,8 @@ public:
|
|||
".cfi_startproc");
|
||||
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIEndProc>(
|
||||
".cfi_endproc");
|
||||
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfa>(
|
||||
".cfi_def_cfa");
|
||||
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaOffset>(
|
||||
".cfi_def_cfa_offset");
|
||||
AddDirectiveHandler<&GenericAsmParser::ParseDirectiveCFIDefCfaRegister>(
|
||||
|
@ -278,6 +280,7 @@ public:
|
|||
bool ParseDirectiveStabs(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIStartProc(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIDefCfa(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIDefCfaOffset(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIDefCfaRegister(StringRef, SMLoc DirectiveLoc);
|
||||
bool ParseDirectiveCFIOffset(StringRef, SMLoc DirectiveLoc);
|
||||
|
@ -2172,6 +2175,25 @@ bool GenericAsmParser::ParseDirectiveCFIEndProc(StringRef, SMLoc DirectiveLoc) {
|
|||
return getStreamer().EmitCFIEndProc();
|
||||
}
|
||||
|
||||
/// ParseDirectiveCFIDefCfa
|
||||
/// ::= .cfi_def_cfa register, offset
|
||||
bool GenericAsmParser::ParseDirectiveCFIDefCfa(StringRef,
|
||||
SMLoc DirectiveLoc) {
|
||||
int64_t Register = 0;
|
||||
if (getParser().ParseAbsoluteExpression(Register))
|
||||
return true;
|
||||
|
||||
if (getLexer().isNot(AsmToken::Comma))
|
||||
return TokError("unexpected token in directive");
|
||||
Lex();
|
||||
|
||||
int64_t Offset = 0;
|
||||
if (getParser().ParseAbsoluteExpression(Offset))
|
||||
return true;
|
||||
|
||||
return getStreamer().EmitCFIDefCfa(Register, Offset);
|
||||
}
|
||||
|
||||
/// ParseDirectiveCFIDefCfaOffset
|
||||
/// ::= .cfi_def_cfa_offset offset
|
||||
bool GenericAsmParser::ParseDirectiveCFIDefCfaOffset(StringRef,
|
||||
|
|
|
@ -172,6 +172,18 @@ bool MCStreamer::EmitCFIEndProc() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool MCStreamer::EmitCFIDefCfa(int64_t Register, int64_t Offset) {
|
||||
EnsureValidFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
|
||||
MCSymbol *Label = getContext().CreateTempSymbol();
|
||||
EmitLabel(Label);
|
||||
MachineLocation Dest(MachineLocation::VirtualFP);
|
||||
MachineLocation Source(Register, -Offset);
|
||||
MCCFIInstruction Instruction(Label, Dest, Source);
|
||||
CurFrame->Instructions.push_back(Instruction);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MCStreamer::EmitCFIDefCfaOffset(int64_t Offset) {
|
||||
EnsureValidFrame();
|
||||
MCDwarfFrameInfo *CurFrame = getCurrentFrameInfo();
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// RUN: llvm-mc -filetype=obj -triple x86_64-pc-linux-gnu %s -o - | elf-dump --dump-section-data | FileCheck %s
|
||||
|
||||
f:
|
||||
.cfi_startproc
|
||||
nop
|
||||
.cfi_def_cfa 7, 8
|
||||
nop
|
||||
.cfi_endproc
|
||||
|
||||
// CHECK: (('sh_name', 0x00000012) # '.eh_frame'
|
||||
// CHECK-NEXT: ('sh_type', 0x00000001)
|
||||
// CHECK-NEXT: ('sh_flags', 0x00000002)
|
||||
// CHECK-NEXT: ('sh_addr', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_offset', 0x00000048)
|
||||
// CHECK-NEXT: ('sh_size', 0x00000030)
|
||||
// CHECK-NEXT: ('sh_link', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_info', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_addralign', 0x00000008)
|
||||
// CHECK-NEXT: ('sh_entsize', 0x00000000)
|
||||
// CHECK-NEXT: ('_section_data', '14000000 00000000 017a5200 01781001 1b0c0708 90010000 14000000 1c000000 00000000 02000000 00410c07 08000000')
|
||||
// CHECK-NEXT: ),
|
||||
|
||||
|
||||
// CHECK: (('sh_name', 0x00000036) # '.rela.eh_frame'
|
||||
// CHECK-NEXT: ('sh_type', 0x00000004)
|
||||
// CHECK-NEXT: ('sh_flags', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_addr', 0x00000000)
|
||||
// CHECK-NEXT: ('sh_offset', 0x00000158)
|
||||
// CHECK-NEXT: ('sh_size', 0x00000018)
|
||||
// CHECK-NEXT: ('sh_link', 0x00000006)
|
||||
// CHECK-NEXT: ('sh_info', 0x00000004)
|
||||
// CHECK-NEXT: ('sh_addralign', 0x00000008)
|
||||
// CHECK-NEXT: ('sh_entsize', 0x00000018)
|
||||
// CHECK-NEXT: ('_relocations', [
|
||||
// CHECK-NEXT: # Relocation 0x00000000
|
||||
// CHECK-NEXT: (('r_offset', 0x00000020)
|
||||
// CHECK-NEXT: ('r_sym', 0x00000002)
|
||||
// CHECK-NEXT: ('r_type', 0x00000002)
|
||||
// CHECK-NEXT: ('r_addend', 0x00000000)
|
||||
// CHECK-NEXT: ),
|
||||
// CHECK-NEXT: ])
|
||||
// CHECK-NEXT: ),
|
Loading…
Reference in New Issue