diff options
| -rw-r--r-- | llvm/include/llvm/MC/MCStreamer.h | 1 | ||||
| -rw-r--r-- | llvm/lib/MC/MCDwarf.cpp | 39 | ||||
| -rw-r--r-- | llvm/lib/MC/MCParser/AsmParser.cpp | 22 | ||||
| -rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 12 | ||||
| -rw-r--r-- | llvm/test/MC/ELF/cfi-def-cfa.s | 42 | 
5 files changed, 102 insertions, 14 deletions
diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index f75e9100d77..7c2de30649f 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -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); diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index f3ba2bbb82f..e11da3737ec 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -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); diff --git a/llvm/lib/MC/MCParser/AsmParser.cpp b/llvm/lib/MC/MCParser/AsmParser.cpp index 76c309e0276..d8a166cc713 100644 --- a/llvm/lib/MC/MCParser/AsmParser.cpp +++ b/llvm/lib/MC/MCParser/AsmParser.cpp @@ -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, diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 4d7d486ea91..c5dc1c7ff36 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -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(); diff --git a/llvm/test/MC/ELF/cfi-def-cfa.s b/llvm/test/MC/ELF/cfi-def-cfa.s new file mode 100644 index 00000000000..1ad427b310c --- /dev/null +++ b/llvm/test/MC/ELF/cfi-def-cfa.s @@ -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: ),  | 

