Home | History | Annotate | Download | only in llvm
      1 From eeba593364290ec3ea51e191211e1150ac551b24 Mon Sep 17 00:00:00 2001
      2 From: Logan Chien <loganchien (a] google.com>
      3 Date: Thu, 20 Sep 2012 10:55:34 +0800
      4 Subject: [PATCH] Fix MIPS exception personality relocation.
      5 
      6 Some MIPS executable loaders prohibit the relocation
      7 in the read-only section.  Thus, we have to use
      8 DW_EH_PE_indirect instead.
      9 ---
     10  .../lib/CodeGen/AsmPrinter/DwarfCFIException.cpp   |    3 +-
     11  .../lib/CodeGen/TargetLoweringObjectFileImpl.cpp   |   13 +++----
     12  llvm-3.1/lib/MC/MCObjectFileInfo.cpp               |   16 ++++++++-
     13  llvm-3.1/test/CodeGen/Mips/ehframe-indirect.ll     |   33 ++++++++++++++++++++
     14  4 files changed, 55 insertions(+), 10 deletions(-)
     15  create mode 100644 llvm-3.1/test/CodeGen/Mips/ehframe-indirect.ll
     16 
     17 diff --git a/llvm-3.1/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp b/llvm-3.1/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
     18 index d975f1f..a9d4774 100644
     19 --- a/llvm-3.1/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
     20 +++ b/llvm-3.1/lib/CodeGen/AsmPrinter/DwarfCFIException.cpp
     21 @@ -59,7 +59,8 @@ void DwarfCFIException::EndModule() {
     22  
     23    unsigned PerEncoding = TLOF.getPersonalityEncoding();
     24  
     25 -  if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel)
     26 +  if ((PerEncoding & 0x70) != dwarf::DW_EH_PE_pcrel &&
     27 +      (PerEncoding & 0x80) != dwarf::DW_EH_PE_indirect)
     28      return;
     29  
     30    // Emit references to all used personality functions
     31 diff --git a/llvm-3.1/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm-3.1/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
     32 index 3660cf7..840d233 100644
     33 --- a/llvm-3.1/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
     34 +++ b/llvm-3.1/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
     35 @@ -49,15 +49,14 @@ TargetLoweringObjectFileELF::getCFIPersonalitySymbol(const GlobalValue *GV,
     36                                                       Mangler *Mang,
     37                                                  MachineModuleInfo *MMI) const {
     38    unsigned Encoding = getPersonalityEncoding();
     39 -  switch (Encoding & 0x70) {
     40 -  default:
     41 -    report_fatal_error("We do not support this DWARF encoding yet!");
     42 -  case dwarf::DW_EH_PE_absptr:
     43 -    return  Mang->getSymbol(GV);
     44 -  case dwarf::DW_EH_PE_pcrel: {
     45 +  if ((Encoding & 0x70) == dwarf::DW_EH_PE_pcrel ||
     46 +      (Encoding & 0x80) == dwarf::DW_EH_PE_indirect) {
     47      return getContext().GetOrCreateSymbol(StringRef("DW.ref.") +
     48                                            Mang->getSymbol(GV)->getName());
     49 -  }
     50 +  } else if ((Encoding & 0x70) == dwarf::DW_EH_PE_absptr) {
     51 +    return  Mang->getSymbol(GV);
     52 +  } else {
     53 +    report_fatal_error("We do not support this DWARF encoding yet!");
     54    }
     55  }
     56  
     57 diff --git a/llvm-3.1/lib/MC/MCObjectFileInfo.cpp b/llvm-3.1/lib/MC/MCObjectFileInfo.cpp
     58 index b22ae33..8b2ed03 100644
     59 --- a/llvm-3.1/lib/MC/MCObjectFileInfo.cpp
     60 +++ b/llvm-3.1/lib/MC/MCObjectFileInfo.cpp
     61 @@ -219,7 +219,8 @@ void MCObjectFileInfo::InitMachOMCObjectFileInfo(Triple T) {
     62  }
     63  
     64  void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
     65 -  if (T.getArch() == Triple::x86) {
     66 +  switch (T.getArch()) {
     67 +  case Triple::x86:
     68      PersonalityEncoding = (RelocM == Reloc::PIC_)
     69       ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     70       : dwarf::DW_EH_PE_absptr;
     71 @@ -232,7 +233,9 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
     72      TTypeEncoding = (RelocM == Reloc::PIC_)
     73       ? dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4
     74       : dwarf::DW_EH_PE_absptr;
     75 -  } else if (T.getArch() == Triple::x86_64) {
     76 +    break;
     77 +
     78 +  case Triple::x86_64:
     79      FDECFIEncoding = dwarf::DW_EH_PE_pcrel | dwarf::DW_EH_PE_sdata4;
     80  
     81      if (RelocM == Reloc::PIC_) {
     82 @@ -256,6 +259,15 @@ void MCObjectFileInfo::InitELFMCObjectFileInfo(Triple T) {
     83        TTypeEncoding = (CMModel == CodeModel::Small)
     84          ? dwarf::DW_EH_PE_udata4 : dwarf::DW_EH_PE_absptr;
     85      }
     86 +    break;
     87 +
     88 +  case Triple::mips:
     89 +  case Triple::mipsel:
     90 +    PersonalityEncoding = dwarf::DW_EH_PE_indirect;
     91 +    break;
     92 +
     93 +  default:
     94 +    break;
     95    }
     96  
     97    // Solaris requires different flags for .eh_frame to seemingly every other
     98 diff --git a/llvm-3.1/test/CodeGen/Mips/ehframe-indirect.ll b/llvm-3.1/test/CodeGen/Mips/ehframe-indirect.ll
     99 new file mode 100644
    100 index 0000000..db422a7
    101 --- /dev/null
    102 +++ b/llvm-3.1/test/CodeGen/Mips/ehframe-indirect.ll
    103 @@ -0,0 +1,33 @@
    104 +; RUN: llc -march=mipsel < %s | FileCheck %s
    105 +
    106 +define i32 @main() {
    107 +; CHECK: .cfi_startproc
    108 +; CHECK: .cfi_personality 128, DW.ref.__gxx_personality_v0
    109 +
    110 +entry:
    111 +  invoke void @foo() to label %cont unwind label %lpad
    112 +; CHECK: foo
    113 +; CHECK: jalr
    114 +
    115 +lpad:
    116 +  %0 = landingpad { i8*, i32 } personality i8*
    117 +    bitcast (i32 (...)* @__gxx_personality_v0 to i8*) catch i8* null
    118 +  ret i32 0
    119 +
    120 +cont:
    121 +  ret i32 0
    122 +}
    123 +; CHECK: .cfi_endproc
    124 +
    125 +declare i32 @__gxx_personality_v0(...)
    126 +
    127 +declare void @foo()
    128 +
    129 +; CHECK: .hidden DW.ref.__gxx_personality_v0
    130 +; CHECK: .weak DW.ref.__gxx_personality_v0
    131 +; CHECK: .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat
    132 +; CHECK: .align 2
    133 +; CHECK: .type DW.ref.__gxx_personality_v0,@object
    134 +; CHECK: .size DW.ref.__gxx_personality_v0, 4
    135 +; CHECK: DW.ref.__gxx_personality_v0:
    136 +; CHECK: .4byte __gxx_personality_v0
    137 -- 
    138 1.7.7.3
    139 
    140