LLVM API Documentation

ARMELFObjectWriter.cpp
Go to the documentation of this file.
00001 //===-- ARMELFObjectWriter.cpp - ARM ELF Writer ---------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "MCTargetDesc/ARMMCTargetDesc.h"
00011 #include "MCTargetDesc/ARMFixupKinds.h"
00012 #include "llvm/ADT/Statistic.h"
00013 #include "llvm/ADT/StringSwitch.h"
00014 #include "llvm/MC/MCELFObjectWriter.h"
00015 #include "llvm/MC/MCExpr.h"
00016 #include "llvm/MC/MCSectionELF.h"
00017 #include "llvm/MC/MCValue.h"
00018 #include "llvm/Support/Debug.h"
00019 #include "llvm/Support/ErrorHandling.h"
00020 #include "llvm/Support/raw_ostream.h"
00021 
00022 using namespace llvm;
00023 
00024 namespace {
00025   class ARMELFObjectWriter : public MCELFObjectTargetWriter {
00026     enum { DefaultEABIVersion = 0x05000000U };
00027     unsigned GetRelocTypeInner(const MCValue &Target,
00028                                const MCFixup &Fixup,
00029                                bool IsPCRel) const;
00030 
00031 
00032   public:
00033     ARMELFObjectWriter(uint8_t OSABI);
00034 
00035     virtual ~ARMELFObjectWriter();
00036 
00037     unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup,
00038                           bool IsPCRel) const override;
00039 
00040     bool needsRelocateWithSymbol(const MCSymbolData &SD,
00041                                  unsigned Type) const override;
00042   };
00043 }
00044 
00045 ARMELFObjectWriter::ARMELFObjectWriter(uint8_t OSABI)
00046   : MCELFObjectTargetWriter(/*Is64Bit*/ false, OSABI,
00047                             ELF::EM_ARM,
00048                             /*HasRelocationAddend*/ false) {}
00049 
00050 ARMELFObjectWriter::~ARMELFObjectWriter() {}
00051 
00052 bool ARMELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD,
00053                                                  unsigned Type) const {
00054   // FIXME: This is extremelly conservative. This really needs to use a
00055   // whitelist with a clear explanation for why each realocation needs to
00056   // point to the symbol, not to the section.
00057   switch (Type) {
00058   default:
00059     return true;
00060 
00061   case ELF::R_ARM_PREL31:
00062   case ELF::R_ARM_ABS32:
00063     return false;
00064   }
00065 }
00066 
00067 // Need to examine the Fixup when determining whether to 
00068 // emit the relocation as an explicit symbol or as a section relative
00069 // offset
00070 unsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target,
00071                                           const MCFixup &Fixup,
00072                                           bool IsPCRel) const {
00073   return GetRelocTypeInner(Target, Fixup, IsPCRel);
00074 }
00075 
00076 unsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target,
00077                                                const MCFixup &Fixup,
00078                                                bool IsPCRel) const  {
00079   MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant();
00080 
00081   unsigned Type = 0;
00082   if (IsPCRel) {
00083     switch ((unsigned)Fixup.getKind()) {
00084     default: llvm_unreachable("Unimplemented");
00085     case FK_Data_4:
00086       switch (Modifier) {
00087       default: llvm_unreachable("Unsupported Modifier");
00088       case MCSymbolRefExpr::VK_None:
00089         Type = ELF::R_ARM_REL32;
00090         break;
00091       case MCSymbolRefExpr::VK_TLSGD:
00092         llvm_unreachable("unimplemented");
00093       case MCSymbolRefExpr::VK_GOTTPOFF:
00094         Type = ELF::R_ARM_TLS_IE32;
00095         break;
00096       case MCSymbolRefExpr::VK_GOTPCREL:
00097         Type = ELF::R_ARM_GOT_PREL;
00098         break;
00099       }
00100       break;
00101     case ARM::fixup_arm_blx:
00102     case ARM::fixup_arm_uncondbl:
00103       switch (Modifier) {
00104       case MCSymbolRefExpr::VK_PLT:
00105         Type = ELF::R_ARM_PLT32;
00106         break;
00107       case MCSymbolRefExpr::VK_ARM_TLSCALL:
00108         Type = ELF::R_ARM_TLS_CALL;
00109         break;
00110       default:
00111         Type = ELF::R_ARM_CALL;
00112         break;
00113       }
00114       break;
00115     case ARM::fixup_arm_condbl:
00116     case ARM::fixup_arm_condbranch:
00117     case ARM::fixup_arm_uncondbranch:
00118       Type = ELF::R_ARM_JUMP24;
00119       break;
00120     case ARM::fixup_t2_condbranch:
00121     case ARM::fixup_t2_uncondbranch:
00122       Type = ELF::R_ARM_THM_JUMP24;
00123       break;
00124     case ARM::fixup_arm_movt_hi16:
00125       Type = ELF::R_ARM_MOVT_PREL;
00126       break;
00127     case ARM::fixup_arm_movw_lo16:
00128       Type = ELF::R_ARM_MOVW_PREL_NC;
00129       break;
00130     case ARM::fixup_t2_movt_hi16:
00131       Type = ELF::R_ARM_THM_MOVT_PREL;
00132       break;
00133     case ARM::fixup_t2_movw_lo16:
00134       Type = ELF::R_ARM_THM_MOVW_PREL_NC;
00135       break;
00136     case ARM::fixup_arm_thumb_bl:
00137     case ARM::fixup_arm_thumb_blx:
00138       switch (Modifier) {
00139       case MCSymbolRefExpr::VK_ARM_TLSCALL:
00140         Type = ELF::R_ARM_THM_TLS_CALL;
00141         break;
00142       default:
00143         Type = ELF::R_ARM_THM_CALL;
00144         break;
00145       }
00146       break;
00147     }
00148   } else {
00149     switch ((unsigned)Fixup.getKind()) {
00150     default: llvm_unreachable("invalid fixup kind!");
00151     case FK_Data_4:
00152       switch (Modifier) {
00153       default: llvm_unreachable("Unsupported Modifier");
00154       case MCSymbolRefExpr::VK_ARM_NONE:
00155         Type = ELF::R_ARM_NONE;
00156         break;
00157       case MCSymbolRefExpr::VK_GOT:
00158         Type = ELF::R_ARM_GOT_BREL;
00159         break;
00160       case MCSymbolRefExpr::VK_TLSGD:
00161         Type = ELF::R_ARM_TLS_GD32;
00162         break;
00163       case MCSymbolRefExpr::VK_TPOFF:
00164         Type = ELF::R_ARM_TLS_LE32;
00165         break;
00166       case MCSymbolRefExpr::VK_GOTTPOFF:
00167         Type = ELF::R_ARM_TLS_IE32;
00168         break;
00169       case MCSymbolRefExpr::VK_None:
00170         Type = ELF::R_ARM_ABS32;
00171         break;
00172       case MCSymbolRefExpr::VK_GOTOFF:
00173         Type = ELF::R_ARM_GOTOFF32;
00174         break;
00175       case MCSymbolRefExpr::VK_GOTPCREL:
00176         Type = ELF::R_ARM_GOT_PREL;
00177         break;
00178       case MCSymbolRefExpr::VK_ARM_TARGET1:
00179         Type = ELF::R_ARM_TARGET1;
00180         break;
00181       case MCSymbolRefExpr::VK_ARM_TARGET2:
00182         Type = ELF::R_ARM_TARGET2;
00183         break;
00184       case MCSymbolRefExpr::VK_ARM_PREL31:
00185         Type = ELF::R_ARM_PREL31;
00186         break;
00187       case MCSymbolRefExpr::VK_ARM_TLSLDO:
00188         Type = ELF::R_ARM_TLS_LDO32;
00189         break;
00190       case MCSymbolRefExpr::VK_ARM_TLSCALL:
00191         Type = ELF::R_ARM_TLS_CALL;
00192         break;
00193       case MCSymbolRefExpr::VK_ARM_TLSDESC:
00194         Type = ELF::R_ARM_TLS_GOTDESC;
00195         break;
00196       case MCSymbolRefExpr::VK_ARM_TLSDESCSEQ:
00197         Type = ELF::R_ARM_TLS_DESCSEQ;
00198         break;
00199       }
00200       break;
00201     case ARM::fixup_arm_ldst_pcrel_12:
00202     case ARM::fixup_arm_pcrel_10:
00203     case ARM::fixup_arm_adr_pcrel_12:
00204     case ARM::fixup_arm_thumb_bl:
00205     case ARM::fixup_arm_thumb_cb:
00206     case ARM::fixup_arm_thumb_cp:
00207     case ARM::fixup_arm_thumb_br:
00208       llvm_unreachable("Unimplemented");
00209     case ARM::fixup_arm_condbranch:
00210     case ARM::fixup_arm_uncondbranch:
00211       Type = ELF::R_ARM_JUMP24;
00212       break;
00213     case ARM::fixup_arm_movt_hi16:
00214       Type = ELF::R_ARM_MOVT_ABS;
00215       break;
00216     case ARM::fixup_arm_movw_lo16:
00217       Type = ELF::R_ARM_MOVW_ABS_NC;
00218       break;
00219     case ARM::fixup_t2_movt_hi16:
00220       Type = ELF::R_ARM_THM_MOVT_ABS;
00221       break;
00222     case ARM::fixup_t2_movw_lo16:
00223       Type = ELF::R_ARM_THM_MOVW_ABS_NC;
00224       break;
00225     }
00226   }
00227 
00228   return Type;
00229 }
00230 
00231 MCObjectWriter *llvm::createARMELFObjectWriter(raw_ostream &OS,
00232                                                uint8_t OSABI,
00233                                                bool IsLittleEndian) {
00234   MCELFObjectTargetWriter *MOTW = new ARMELFObjectWriter(OSABI);
00235   return createELFObjectWriter(MOTW, OS, IsLittleEndian);
00236 }