Home | History | Annotate | Download | only in MCTargetDesc
      1 //===-- HexagonELFObjectWriter.cpp - Hexagon Target Descriptions ----------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 
     10 #include "Hexagon.h"
     11 #include "MCTargetDesc/HexagonFixupKinds.h"
     12 #include "llvm/MC/MCAssembler.h"
     13 #include "llvm/MC/MCELFObjectWriter.h"
     14 #include "llvm/MC/MCValue.h"
     15 #include "llvm/Support/Debug.h"
     16 #include "llvm/Support/raw_ostream.h"
     17 
     18 #define DEBUG_TYPE "hexagon-elf-writer"
     19 
     20 using namespace llvm;
     21 using namespace Hexagon;
     22 
     23 namespace {
     24 
     25 class HexagonELFObjectWriter : public MCELFObjectTargetWriter {
     26 private:
     27   StringRef CPU;
     28 
     29 public:
     30   HexagonELFObjectWriter(uint8_t OSABI, StringRef C);
     31 
     32   unsigned getRelocType(MCContext &Ctx, MCValue const &Target,
     33                         MCFixup const &Fixup, bool IsPCRel) const override;
     34 };
     35 }
     36 
     37 HexagonELFObjectWriter::HexagonELFObjectWriter(uint8_t OSABI, StringRef C)
     38     : MCELFObjectTargetWriter(/*Is64bit*/ false, OSABI, ELF::EM_HEXAGON,
     39                               /*HasRelocationAddend*/ true),
     40       CPU(C) {}
     41 
     42 unsigned HexagonELFObjectWriter::getRelocType(MCContext &Ctx,
     43                                               MCValue const &Target,
     44                                               MCFixup const &Fixup,
     45                                               bool IsPCRel) const {
     46   MCSymbolRefExpr::VariantKind Variant = Target.getAccessVariant();
     47   switch ((unsigned)Fixup.getKind()) {
     48   default:
     49     report_fatal_error("Unrecognized relocation type");
     50     break;
     51   case FK_Data_4:
     52     switch(Variant) {
     53     case MCSymbolRefExpr::VariantKind::VK_DTPREL:
     54       return ELF::R_HEX_DTPREL_32;
     55     case MCSymbolRefExpr::VariantKind::VK_GOT:
     56       return ELF::R_HEX_GOT_32;
     57     case MCSymbolRefExpr::VariantKind::VK_GOTREL:
     58       return ELF::R_HEX_GOTREL_32;
     59     case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT:
     60       return ELF::R_HEX_GD_GOT_32;
     61     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE:
     62       return ELF::R_HEX_IE_32;
     63     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT:
     64       return ELF::R_HEX_IE_GOT_32;
     65     case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT:
     66       return ELF::R_HEX_LD_GOT_32;
     67     case MCSymbolRefExpr::VariantKind::VK_Hexagon_PCREL:
     68       return ELF::R_HEX_32_PCREL;
     69     case MCSymbolRefExpr::VariantKind::VK_TPREL:
     70       return ELF::R_HEX_TPREL_32;
     71     case MCSymbolRefExpr::VariantKind::VK_None:
     72       return IsPCRel ? ELF::R_HEX_32_PCREL : ELF::R_HEX_32;
     73     default:
     74       report_fatal_error("Unrecognized variant type");
     75     };
     76   case FK_PCRel_4:
     77     return ELF::R_HEX_32_PCREL;
     78   case FK_Data_2:
     79     switch(Variant) {
     80     case MCSymbolRefExpr::VariantKind::VK_DTPREL:
     81       return ELF::R_HEX_DTPREL_16;
     82     case MCSymbolRefExpr::VariantKind::VK_GOT:
     83       return ELF::R_HEX_GOT_16;
     84     case MCSymbolRefExpr::VariantKind::VK_Hexagon_GD_GOT:
     85       return ELF::R_HEX_GD_GOT_16;
     86     case MCSymbolRefExpr::VariantKind::VK_Hexagon_IE_GOT:
     87       return ELF::R_HEX_IE_GOT_16;
     88     case MCSymbolRefExpr::VariantKind::VK_Hexagon_LD_GOT:
     89       return ELF::R_HEX_LD_GOT_16;
     90     case MCSymbolRefExpr::VariantKind::VK_TPREL:
     91       return ELF::R_HEX_TPREL_16;
     92     case MCSymbolRefExpr::VariantKind::VK_None:
     93       return ELF::R_HEX_16;
     94     default:
     95       report_fatal_error("Unrecognized variant type");
     96     };
     97   case FK_Data_1:
     98     return ELF::R_HEX_8;
     99   case fixup_Hexagon_B22_PCREL:
    100     return ELF::R_HEX_B22_PCREL;
    101   case fixup_Hexagon_B15_PCREL:
    102     return ELF::R_HEX_B15_PCREL;
    103   case fixup_Hexagon_B7_PCREL:
    104     return ELF::R_HEX_B7_PCREL;
    105   case fixup_Hexagon_LO16:
    106     return ELF::R_HEX_LO16;
    107   case fixup_Hexagon_HI16:
    108     return ELF::R_HEX_HI16;
    109   case fixup_Hexagon_32:
    110     return ELF::R_HEX_32;
    111   case fixup_Hexagon_16:
    112     return ELF::R_HEX_16;
    113   case fixup_Hexagon_8:
    114     return ELF::R_HEX_8;
    115   case fixup_Hexagon_GPREL16_0:
    116     return ELF::R_HEX_GPREL16_0;
    117   case fixup_Hexagon_GPREL16_1:
    118     return ELF::R_HEX_GPREL16_1;
    119   case fixup_Hexagon_GPREL16_2:
    120     return ELF::R_HEX_GPREL16_2;
    121   case fixup_Hexagon_GPREL16_3:
    122     return ELF::R_HEX_GPREL16_3;
    123   case fixup_Hexagon_HL16:
    124     return ELF::R_HEX_HL16;
    125   case fixup_Hexagon_B13_PCREL:
    126     return ELF::R_HEX_B13_PCREL;
    127   case fixup_Hexagon_B9_PCREL:
    128     return ELF::R_HEX_B9_PCREL;
    129   case fixup_Hexagon_B32_PCREL_X:
    130     return ELF::R_HEX_B32_PCREL_X;
    131   case fixup_Hexagon_32_6_X:
    132     return ELF::R_HEX_32_6_X;
    133   case fixup_Hexagon_B22_PCREL_X:
    134     return ELF::R_HEX_B22_PCREL_X;
    135   case fixup_Hexagon_B15_PCREL_X:
    136     return ELF::R_HEX_B15_PCREL_X;
    137   case fixup_Hexagon_B13_PCREL_X:
    138     return ELF::R_HEX_B13_PCREL_X;
    139   case fixup_Hexagon_B9_PCREL_X:
    140     return ELF::R_HEX_B9_PCREL_X;
    141   case fixup_Hexagon_B7_PCREL_X:
    142     return ELF::R_HEX_B7_PCREL_X;
    143   case fixup_Hexagon_16_X:
    144     return ELF::R_HEX_16_X;
    145   case fixup_Hexagon_12_X:
    146     return ELF::R_HEX_12_X;
    147   case fixup_Hexagon_11_X:
    148     return ELF::R_HEX_11_X;
    149   case fixup_Hexagon_10_X:
    150     return ELF::R_HEX_10_X;
    151   case fixup_Hexagon_9_X:
    152     return ELF::R_HEX_9_X;
    153   case fixup_Hexagon_8_X:
    154     return ELF::R_HEX_8_X;
    155   case fixup_Hexagon_7_X:
    156     return ELF::R_HEX_7_X;
    157   case fixup_Hexagon_6_X:
    158     return ELF::R_HEX_6_X;
    159   case fixup_Hexagon_32_PCREL:
    160     return ELF::R_HEX_32_PCREL;
    161   case fixup_Hexagon_COPY:
    162     return ELF::R_HEX_COPY;
    163   case fixup_Hexagon_GLOB_DAT:
    164     return ELF::R_HEX_GLOB_DAT;
    165   case fixup_Hexagon_JMP_SLOT:
    166     return ELF::R_HEX_JMP_SLOT;
    167   case fixup_Hexagon_RELATIVE:
    168     return ELF::R_HEX_RELATIVE;
    169   case fixup_Hexagon_PLT_B22_PCREL:
    170     return ELF::R_HEX_PLT_B22_PCREL;
    171   case fixup_Hexagon_GOTREL_LO16:
    172     return ELF::R_HEX_GOTREL_LO16;
    173   case fixup_Hexagon_GOTREL_HI16:
    174     return ELF::R_HEX_GOTREL_HI16;
    175   case fixup_Hexagon_GOTREL_32:
    176     return ELF::R_HEX_GOTREL_32;
    177   case fixup_Hexagon_GOT_LO16:
    178     return ELF::R_HEX_GOT_LO16;
    179   case fixup_Hexagon_GOT_HI16:
    180     return ELF::R_HEX_GOT_HI16;
    181   case fixup_Hexagon_GOT_32:
    182     return ELF::R_HEX_GOT_32;
    183   case fixup_Hexagon_GOT_16:
    184     return ELF::R_HEX_GOT_16;
    185   case fixup_Hexagon_DTPMOD_32:
    186     return ELF::R_HEX_DTPMOD_32;
    187   case fixup_Hexagon_DTPREL_LO16:
    188     return ELF::R_HEX_DTPREL_LO16;
    189   case fixup_Hexagon_DTPREL_HI16:
    190     return ELF::R_HEX_DTPREL_HI16;
    191   case fixup_Hexagon_DTPREL_32:
    192     return ELF::R_HEX_DTPREL_32;
    193   case fixup_Hexagon_DTPREL_16:
    194     return ELF::R_HEX_DTPREL_16;
    195   case fixup_Hexagon_GD_PLT_B22_PCREL:
    196     return ELF::R_HEX_GD_PLT_B22_PCREL;
    197   case fixup_Hexagon_LD_PLT_B22_PCREL:
    198     return ELF::R_HEX_LD_PLT_B22_PCREL;
    199   case fixup_Hexagon_GD_GOT_LO16:
    200     return ELF::R_HEX_GD_GOT_LO16;
    201   case fixup_Hexagon_GD_GOT_HI16:
    202     return ELF::R_HEX_GD_GOT_HI16;
    203   case fixup_Hexagon_GD_GOT_32:
    204     return ELF::R_HEX_GD_GOT_32;
    205   case fixup_Hexagon_GD_GOT_16:
    206     return ELF::R_HEX_GD_GOT_16;
    207   case fixup_Hexagon_LD_GOT_LO16:
    208     return ELF::R_HEX_LD_GOT_LO16;
    209   case fixup_Hexagon_LD_GOT_HI16:
    210     return ELF::R_HEX_LD_GOT_HI16;
    211   case fixup_Hexagon_LD_GOT_32:
    212     return ELF::R_HEX_LD_GOT_32;
    213   case fixup_Hexagon_LD_GOT_16:
    214     return ELF::R_HEX_LD_GOT_16;
    215   case fixup_Hexagon_IE_LO16:
    216     return ELF::R_HEX_IE_LO16;
    217   case fixup_Hexagon_IE_HI16:
    218     return ELF::R_HEX_IE_HI16;
    219   case fixup_Hexagon_IE_32:
    220     return ELF::R_HEX_IE_32;
    221   case fixup_Hexagon_IE_GOT_LO16:
    222     return ELF::R_HEX_IE_GOT_LO16;
    223   case fixup_Hexagon_IE_GOT_HI16:
    224     return ELF::R_HEX_IE_GOT_HI16;
    225   case fixup_Hexagon_IE_GOT_32:
    226     return ELF::R_HEX_IE_GOT_32;
    227   case fixup_Hexagon_IE_GOT_16:
    228     return ELF::R_HEX_IE_GOT_16;
    229   case fixup_Hexagon_TPREL_LO16:
    230     return ELF::R_HEX_TPREL_LO16;
    231   case fixup_Hexagon_TPREL_HI16:
    232     return ELF::R_HEX_TPREL_HI16;
    233   case fixup_Hexagon_TPREL_32:
    234     return ELF::R_HEX_TPREL_32;
    235   case fixup_Hexagon_TPREL_16:
    236     return ELF::R_HEX_TPREL_16;
    237   case fixup_Hexagon_6_PCREL_X:
    238     return ELF::R_HEX_6_PCREL_X;
    239   case fixup_Hexagon_GOTREL_32_6_X:
    240     return ELF::R_HEX_GOTREL_32_6_X;
    241   case fixup_Hexagon_GOTREL_16_X:
    242     return ELF::R_HEX_GOTREL_16_X;
    243   case fixup_Hexagon_GOTREL_11_X:
    244     return ELF::R_HEX_GOTREL_11_X;
    245   case fixup_Hexagon_GOT_32_6_X:
    246     return ELF::R_HEX_GOT_32_6_X;
    247   case fixup_Hexagon_GOT_16_X:
    248     return ELF::R_HEX_GOT_16_X;
    249   case fixup_Hexagon_GOT_11_X:
    250     return ELF::R_HEX_GOT_11_X;
    251   case fixup_Hexagon_DTPREL_32_6_X:
    252     return ELF::R_HEX_DTPREL_32_6_X;
    253   case fixup_Hexagon_DTPREL_16_X:
    254     return ELF::R_HEX_DTPREL_16_X;
    255   case fixup_Hexagon_DTPREL_11_X:
    256     return ELF::R_HEX_DTPREL_11_X;
    257   case fixup_Hexagon_GD_GOT_32_6_X:
    258     return ELF::R_HEX_GD_GOT_32_6_X;
    259   case fixup_Hexagon_GD_GOT_16_X:
    260     return ELF::R_HEX_GD_GOT_16_X;
    261   case fixup_Hexagon_GD_GOT_11_X:
    262     return ELF::R_HEX_GD_GOT_11_X;
    263   case fixup_Hexagon_LD_GOT_32_6_X:
    264     return ELF::R_HEX_LD_GOT_32_6_X;
    265   case fixup_Hexagon_LD_GOT_16_X:
    266     return ELF::R_HEX_LD_GOT_16_X;
    267   case fixup_Hexagon_LD_GOT_11_X:
    268     return ELF::R_HEX_LD_GOT_11_X;
    269   case fixup_Hexagon_IE_32_6_X:
    270     return ELF::R_HEX_IE_32_6_X;
    271   case fixup_Hexagon_IE_16_X:
    272     return ELF::R_HEX_IE_16_X;
    273   case fixup_Hexagon_IE_GOT_32_6_X:
    274     return ELF::R_HEX_IE_GOT_32_6_X;
    275   case fixup_Hexagon_IE_GOT_16_X:
    276     return ELF::R_HEX_IE_GOT_16_X;
    277   case fixup_Hexagon_IE_GOT_11_X:
    278     return ELF::R_HEX_IE_GOT_11_X;
    279   case fixup_Hexagon_TPREL_32_6_X:
    280     return ELF::R_HEX_TPREL_32_6_X;
    281   case fixup_Hexagon_TPREL_16_X:
    282     return ELF::R_HEX_TPREL_16_X;
    283   case fixup_Hexagon_TPREL_11_X:
    284     return ELF::R_HEX_TPREL_11_X;
    285   case fixup_Hexagon_23_REG:
    286     return ELF::R_HEX_23_REG;
    287   }
    288 }
    289 
    290 MCObjectWriter *llvm::createHexagonELFObjectWriter(raw_pwrite_stream &OS,
    291                                                    uint8_t OSABI,
    292                                                    StringRef CPU) {
    293   MCELFObjectTargetWriter *MOTW = new HexagonELFObjectWriter(OSABI, CPU);
    294   return createELFObjectWriter(MOTW, OS, /*IsLittleEndian*/ true);
    295 }
    296