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:
Rafael Espindola 2010-12-29 01:42:56 +00:00
parent 1be1fe033c
commit 290d71671e
5 changed files with 102 additions and 14 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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,

View File

@ -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();

View File

@ -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: ),