LLVM API Documentation
00001 //===-- X86ELFObjectWriter.cpp - X86 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/X86FixupKinds.h" 00011 #include "MCTargetDesc/X86MCTargetDesc.h" 00012 #include "llvm/MC/MCELFObjectWriter.h" 00013 #include "llvm/MC/MCExpr.h" 00014 #include "llvm/MC/MCValue.h" 00015 #include "llvm/Support/ELF.h" 00016 #include "llvm/Support/ErrorHandling.h" 00017 00018 using namespace llvm; 00019 00020 namespace { 00021 class X86ELFObjectWriter : public MCELFObjectTargetWriter { 00022 public: 00023 X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, uint16_t EMachine); 00024 00025 virtual ~X86ELFObjectWriter(); 00026 protected: 00027 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 00028 bool IsPCRel) const override; 00029 }; 00030 } 00031 00032 X86ELFObjectWriter::X86ELFObjectWriter(bool IsELF64, uint8_t OSABI, 00033 uint16_t EMachine) 00034 : MCELFObjectTargetWriter(IsELF64, OSABI, EMachine, 00035 // Only i386 uses Rel instead of RelA. 00036 /*HasRelocationAddend*/ EMachine != ELF::EM_386) {} 00037 00038 X86ELFObjectWriter::~X86ELFObjectWriter() 00039 {} 00040 00041 unsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 00042 const MCFixup &Fixup, 00043 bool IsPCRel) const { 00044 // determine the type of the relocation 00045 00046 MCSymbolRefExpr::VariantKind Modifier = Target.getAccessVariant(); 00047 unsigned Type; 00048 if (getEMachine() == ELF::EM_X86_64) { 00049 if (IsPCRel) { 00050 switch ((unsigned)Fixup.getKind()) { 00051 default: llvm_unreachable("invalid fixup kind!"); 00052 00053 case FK_Data_8: Type = ELF::R_X86_64_PC64; break; 00054 case FK_Data_4: Type = ELF::R_X86_64_PC32; break; 00055 case FK_Data_2: Type = ELF::R_X86_64_PC16; break; 00056 case FK_Data_1: Type = ELF::R_X86_64_PC8; break; 00057 00058 case FK_PCRel_8: 00059 assert(Modifier == MCSymbolRefExpr::VK_None); 00060 Type = ELF::R_X86_64_PC64; 00061 break; 00062 case X86::reloc_signed_4byte: 00063 case X86::reloc_riprel_4byte_movq_load: 00064 case X86::reloc_riprel_4byte: 00065 case FK_PCRel_4: 00066 switch (Modifier) { 00067 default: 00068 llvm_unreachable("Unimplemented"); 00069 case MCSymbolRefExpr::VK_None: 00070 Type = ELF::R_X86_64_PC32; 00071 break; 00072 case MCSymbolRefExpr::VK_PLT: 00073 Type = ELF::R_X86_64_PLT32; 00074 break; 00075 case MCSymbolRefExpr::VK_GOTPCREL: 00076 Type = ELF::R_X86_64_GOTPCREL; 00077 break; 00078 case MCSymbolRefExpr::VK_GOTTPOFF: 00079 Type = ELF::R_X86_64_GOTTPOFF; 00080 break; 00081 case MCSymbolRefExpr::VK_TLSGD: 00082 Type = ELF::R_X86_64_TLSGD; 00083 break; 00084 case MCSymbolRefExpr::VK_TLSLD: 00085 Type = ELF::R_X86_64_TLSLD; 00086 break; 00087 } 00088 break; 00089 case FK_PCRel_2: 00090 assert(Modifier == MCSymbolRefExpr::VK_None); 00091 Type = ELF::R_X86_64_PC16; 00092 break; 00093 case FK_PCRel_1: 00094 assert(Modifier == MCSymbolRefExpr::VK_None); 00095 Type = ELF::R_X86_64_PC8; 00096 break; 00097 } 00098 } else { 00099 switch ((unsigned)Fixup.getKind()) { 00100 default: llvm_unreachable("invalid fixup kind!"); 00101 case X86::reloc_global_offset_table8: 00102 Type = ELF::R_X86_64_GOTPC64; 00103 break; 00104 case X86::reloc_global_offset_table: 00105 Type = ELF::R_X86_64_GOTPC32; 00106 break; 00107 case FK_Data_8: 00108 switch (Modifier) { 00109 default: 00110 llvm_unreachable("Unimplemented"); 00111 case MCSymbolRefExpr::VK_None: 00112 Type = ELF::R_X86_64_64; 00113 break; 00114 case MCSymbolRefExpr::VK_GOT: 00115 Type = ELF::R_X86_64_GOT64; 00116 break; 00117 case MCSymbolRefExpr::VK_GOTOFF: 00118 Type = ELF::R_X86_64_GOTOFF64; 00119 break; 00120 case MCSymbolRefExpr::VK_TPOFF: 00121 Type = ELF::R_X86_64_TPOFF64; 00122 break; 00123 case MCSymbolRefExpr::VK_DTPOFF: 00124 Type = ELF::R_X86_64_DTPOFF64; 00125 break; 00126 } 00127 break; 00128 case X86::reloc_signed_4byte: 00129 switch (Modifier) { 00130 default: 00131 llvm_unreachable("Unimplemented"); 00132 case MCSymbolRefExpr::VK_None: 00133 Type = ELF::R_X86_64_32S; 00134 break; 00135 case MCSymbolRefExpr::VK_GOT: 00136 Type = ELF::R_X86_64_GOT32; 00137 break; 00138 case MCSymbolRefExpr::VK_GOTPCREL: 00139 Type = ELF::R_X86_64_GOTPCREL; 00140 break; 00141 case MCSymbolRefExpr::VK_TPOFF: 00142 Type = ELF::R_X86_64_TPOFF32; 00143 break; 00144 case MCSymbolRefExpr::VK_DTPOFF: 00145 Type = ELF::R_X86_64_DTPOFF32; 00146 break; 00147 } 00148 break; 00149 case FK_Data_4: 00150 Type = ELF::R_X86_64_32; 00151 break; 00152 case FK_Data_2: Type = ELF::R_X86_64_16; break; 00153 case FK_PCRel_1: 00154 case FK_Data_1: Type = ELF::R_X86_64_8; break; 00155 } 00156 } 00157 } else if (getEMachine() == ELF::EM_386) { 00158 if (IsPCRel) { 00159 switch ((unsigned)Fixup.getKind()) { 00160 default: llvm_unreachable("invalid fixup kind!"); 00161 00162 case X86::reloc_global_offset_table: 00163 Type = ELF::R_386_GOTPC; 00164 break; 00165 00166 case FK_PCRel_1: 00167 case FK_Data_1: 00168 switch (Modifier) { 00169 default: 00170 llvm_unreachable("Unimplemented"); 00171 case MCSymbolRefExpr::VK_None: 00172 Type = ELF::R_386_PC8; 00173 break; 00174 } 00175 break; 00176 00177 case FK_PCRel_2: 00178 case FK_Data_2: 00179 switch (Modifier) { 00180 default: 00181 llvm_unreachable("Unimplemented"); 00182 case MCSymbolRefExpr::VK_None: 00183 Type = ELF::R_386_PC16; 00184 break; 00185 } 00186 break; 00187 00188 case X86::reloc_signed_4byte: 00189 case FK_PCRel_4: 00190 case FK_Data_4: 00191 switch (Modifier) { 00192 default: 00193 llvm_unreachable("Unimplemented"); 00194 case MCSymbolRefExpr::VK_None: 00195 Type = ELF::R_386_PC32; 00196 break; 00197 case MCSymbolRefExpr::VK_PLT: 00198 Type = ELF::R_386_PLT32; 00199 break; 00200 } 00201 break; 00202 } 00203 } else { 00204 switch ((unsigned)Fixup.getKind()) { 00205 default: llvm_unreachable("invalid fixup kind!"); 00206 00207 case X86::reloc_global_offset_table: 00208 Type = ELF::R_386_GOTPC; 00209 break; 00210 00211 // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 00212 // instead? 00213 case X86::reloc_signed_4byte: 00214 case FK_PCRel_4: 00215 case FK_Data_4: 00216 switch (Modifier) { 00217 default: 00218 llvm_unreachable("Unimplemented"); 00219 case MCSymbolRefExpr::VK_None: 00220 Type = ELF::R_386_32; 00221 break; 00222 case MCSymbolRefExpr::VK_GOT: 00223 Type = ELF::R_386_GOT32; 00224 break; 00225 case MCSymbolRefExpr::VK_GOTOFF: 00226 Type = ELF::R_386_GOTOFF; 00227 break; 00228 case MCSymbolRefExpr::VK_TLSGD: 00229 Type = ELF::R_386_TLS_GD; 00230 break; 00231 case MCSymbolRefExpr::VK_TPOFF: 00232 Type = ELF::R_386_TLS_LE_32; 00233 break; 00234 case MCSymbolRefExpr::VK_INDNTPOFF: 00235 Type = ELF::R_386_TLS_IE; 00236 break; 00237 case MCSymbolRefExpr::VK_NTPOFF: 00238 Type = ELF::R_386_TLS_LE; 00239 break; 00240 case MCSymbolRefExpr::VK_GOTNTPOFF: 00241 Type = ELF::R_386_TLS_GOTIE; 00242 break; 00243 case MCSymbolRefExpr::VK_TLSLDM: 00244 Type = ELF::R_386_TLS_LDM; 00245 break; 00246 case MCSymbolRefExpr::VK_DTPOFF: 00247 Type = ELF::R_386_TLS_LDO_32; 00248 break; 00249 case MCSymbolRefExpr::VK_GOTTPOFF: 00250 Type = ELF::R_386_TLS_IE_32; 00251 break; 00252 } 00253 break; 00254 case FK_Data_2: Type = ELF::R_386_16; break; 00255 case FK_PCRel_1: 00256 case FK_Data_1: Type = ELF::R_386_8; break; 00257 } 00258 } 00259 } else 00260 llvm_unreachable("Unsupported ELF machine type."); 00261 00262 return Type; 00263 } 00264 00265 MCObjectWriter *llvm::createX86ELFObjectWriter(raw_ostream &OS, 00266 bool IsELF64, 00267 uint8_t OSABI, 00268 uint16_t EMachine) { 00269 MCELFObjectTargetWriter *MOTW = 00270 new X86ELFObjectWriter(IsELF64, OSABI, EMachine); 00271 return createELFObjectWriter(MOTW, OS, /*IsLittleEndian=*/true); 00272 }