LLVM API Documentation
00001 //===-- PPCELFObjectWriter.cpp - PPC 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/PPCMCTargetDesc.h" 00011 #include "MCTargetDesc/PPCFixupKinds.h" 00012 #include "MCTargetDesc/PPCMCExpr.h" 00013 #include "llvm/ADT/STLExtras.h" 00014 #include "llvm/MC/MCELF.h" 00015 #include "llvm/MC/MCELFObjectWriter.h" 00016 #include "llvm/MC/MCExpr.h" 00017 #include "llvm/MC/MCValue.h" 00018 #include "llvm/Support/ErrorHandling.h" 00019 00020 using namespace llvm; 00021 00022 namespace { 00023 class PPCELFObjectWriter : public MCELFObjectTargetWriter { 00024 public: 00025 PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI); 00026 00027 protected: 00028 unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 00029 bool IsPCRel) const override; 00030 00031 bool needsRelocateWithSymbol(const MCSymbolData &SD, 00032 unsigned Type) const override; 00033 }; 00034 } 00035 00036 PPCELFObjectWriter::PPCELFObjectWriter(bool Is64Bit, uint8_t OSABI) 00037 : MCELFObjectTargetWriter(Is64Bit, OSABI, 00038 Is64Bit ? ELF::EM_PPC64 : ELF::EM_PPC, 00039 /*HasRelocationAddend*/ true) {} 00040 00041 static MCSymbolRefExpr::VariantKind getAccessVariant(const MCValue &Target, 00042 const MCFixup &Fixup) { 00043 const MCExpr *Expr = Fixup.getValue(); 00044 00045 if (Expr->getKind() != MCExpr::Target) 00046 return Target.getAccessVariant(); 00047 00048 switch (cast<PPCMCExpr>(Expr)->getKind()) { 00049 case PPCMCExpr::VK_PPC_None: 00050 return MCSymbolRefExpr::VK_None; 00051 case PPCMCExpr::VK_PPC_LO: 00052 return MCSymbolRefExpr::VK_PPC_LO; 00053 case PPCMCExpr::VK_PPC_HI: 00054 return MCSymbolRefExpr::VK_PPC_HI; 00055 case PPCMCExpr::VK_PPC_HA: 00056 return MCSymbolRefExpr::VK_PPC_HA; 00057 case PPCMCExpr::VK_PPC_HIGHERA: 00058 return MCSymbolRefExpr::VK_PPC_HIGHERA; 00059 case PPCMCExpr::VK_PPC_HIGHER: 00060 return MCSymbolRefExpr::VK_PPC_HIGHER; 00061 case PPCMCExpr::VK_PPC_HIGHEST: 00062 return MCSymbolRefExpr::VK_PPC_HIGHEST; 00063 case PPCMCExpr::VK_PPC_HIGHESTA: 00064 return MCSymbolRefExpr::VK_PPC_HIGHESTA; 00065 } 00066 llvm_unreachable("unknown PPCMCExpr kind"); 00067 } 00068 00069 unsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 00070 const MCFixup &Fixup, 00071 bool IsPCRel) const { 00072 MCSymbolRefExpr::VariantKind Modifier = getAccessVariant(Target, Fixup); 00073 00074 // determine the type of the relocation 00075 unsigned Type; 00076 if (IsPCRel) { 00077 switch ((unsigned)Fixup.getKind()) { 00078 default: 00079 llvm_unreachable("Unimplemented"); 00080 case PPC::fixup_ppc_br24: 00081 case PPC::fixup_ppc_br24abs: 00082 switch (Modifier) { 00083 default: llvm_unreachable("Unsupported Modifier"); 00084 case MCSymbolRefExpr::VK_None: 00085 Type = ELF::R_PPC_REL24; 00086 break; 00087 case MCSymbolRefExpr::VK_PLT: 00088 Type = ELF::R_PPC_PLTREL24; 00089 break; 00090 } 00091 break; 00092 case PPC::fixup_ppc_brcond14: 00093 case PPC::fixup_ppc_brcond14abs: 00094 Type = ELF::R_PPC_REL14; 00095 break; 00096 case PPC::fixup_ppc_half16: 00097 switch (Modifier) { 00098 default: llvm_unreachable("Unsupported Modifier"); 00099 case MCSymbolRefExpr::VK_None: 00100 Type = ELF::R_PPC_REL16; 00101 break; 00102 case MCSymbolRefExpr::VK_PPC_LO: 00103 Type = ELF::R_PPC_REL16_LO; 00104 break; 00105 case MCSymbolRefExpr::VK_PPC_HI: 00106 Type = ELF::R_PPC_REL16_HI; 00107 break; 00108 case MCSymbolRefExpr::VK_PPC_HA: 00109 Type = ELF::R_PPC_REL16_HA; 00110 break; 00111 } 00112 break; 00113 case FK_Data_4: 00114 case FK_PCRel_4: 00115 Type = ELF::R_PPC_REL32; 00116 break; 00117 case FK_Data_8: 00118 case FK_PCRel_8: 00119 Type = ELF::R_PPC64_REL64; 00120 break; 00121 } 00122 } else { 00123 switch ((unsigned)Fixup.getKind()) { 00124 default: llvm_unreachable("invalid fixup kind!"); 00125 case PPC::fixup_ppc_br24abs: 00126 Type = ELF::R_PPC_ADDR24; 00127 break; 00128 case PPC::fixup_ppc_brcond14abs: 00129 Type = ELF::R_PPC_ADDR14; // XXX: or BRNTAKEN?_ 00130 break; 00131 case PPC::fixup_ppc_half16: 00132 switch (Modifier) { 00133 default: llvm_unreachable("Unsupported Modifier"); 00134 case MCSymbolRefExpr::VK_None: 00135 Type = ELF::R_PPC_ADDR16; 00136 break; 00137 case MCSymbolRefExpr::VK_PPC_LO: 00138 Type = ELF::R_PPC_ADDR16_LO; 00139 break; 00140 case MCSymbolRefExpr::VK_PPC_HI: 00141 Type = ELF::R_PPC_ADDR16_HI; 00142 break; 00143 case MCSymbolRefExpr::VK_PPC_HA: 00144 Type = ELF::R_PPC_ADDR16_HA; 00145 break; 00146 case MCSymbolRefExpr::VK_PPC_HIGHER: 00147 Type = ELF::R_PPC64_ADDR16_HIGHER; 00148 break; 00149 case MCSymbolRefExpr::VK_PPC_HIGHERA: 00150 Type = ELF::R_PPC64_ADDR16_HIGHERA; 00151 break; 00152 case MCSymbolRefExpr::VK_PPC_HIGHEST: 00153 Type = ELF::R_PPC64_ADDR16_HIGHEST; 00154 break; 00155 case MCSymbolRefExpr::VK_PPC_HIGHESTA: 00156 Type = ELF::R_PPC64_ADDR16_HIGHESTA; 00157 break; 00158 case MCSymbolRefExpr::VK_GOT: 00159 Type = ELF::R_PPC_GOT16; 00160 break; 00161 case MCSymbolRefExpr::VK_PPC_GOT_LO: 00162 Type = ELF::R_PPC_GOT16_LO; 00163 break; 00164 case MCSymbolRefExpr::VK_PPC_GOT_HI: 00165 Type = ELF::R_PPC_GOT16_HI; 00166 break; 00167 case MCSymbolRefExpr::VK_PPC_GOT_HA: 00168 Type = ELF::R_PPC_GOT16_HA; 00169 break; 00170 case MCSymbolRefExpr::VK_PPC_TOC: 00171 Type = ELF::R_PPC64_TOC16; 00172 break; 00173 case MCSymbolRefExpr::VK_PPC_TOC_LO: 00174 Type = ELF::R_PPC64_TOC16_LO; 00175 break; 00176 case MCSymbolRefExpr::VK_PPC_TOC_HI: 00177 Type = ELF::R_PPC64_TOC16_HI; 00178 break; 00179 case MCSymbolRefExpr::VK_PPC_TOC_HA: 00180 Type = ELF::R_PPC64_TOC16_HA; 00181 break; 00182 case MCSymbolRefExpr::VK_PPC_TPREL: 00183 Type = ELF::R_PPC_TPREL16; 00184 break; 00185 case MCSymbolRefExpr::VK_PPC_TPREL_LO: 00186 Type = ELF::R_PPC_TPREL16_LO; 00187 break; 00188 case MCSymbolRefExpr::VK_PPC_TPREL_HI: 00189 Type = ELF::R_PPC_TPREL16_HI; 00190 break; 00191 case MCSymbolRefExpr::VK_PPC_TPREL_HA: 00192 Type = ELF::R_PPC_TPREL16_HA; 00193 break; 00194 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHER: 00195 Type = ELF::R_PPC64_TPREL16_HIGHER; 00196 break; 00197 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHERA: 00198 Type = ELF::R_PPC64_TPREL16_HIGHERA; 00199 break; 00200 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHEST: 00201 Type = ELF::R_PPC64_TPREL16_HIGHEST; 00202 break; 00203 case MCSymbolRefExpr::VK_PPC_TPREL_HIGHESTA: 00204 Type = ELF::R_PPC64_TPREL16_HIGHESTA; 00205 break; 00206 case MCSymbolRefExpr::VK_PPC_DTPREL: 00207 Type = ELF::R_PPC64_DTPREL16; 00208 break; 00209 case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 00210 Type = ELF::R_PPC64_DTPREL16_LO; 00211 break; 00212 case MCSymbolRefExpr::VK_PPC_DTPREL_HI: 00213 Type = ELF::R_PPC64_DTPREL16_HI; 00214 break; 00215 case MCSymbolRefExpr::VK_PPC_DTPREL_HA: 00216 Type = ELF::R_PPC64_DTPREL16_HA; 00217 break; 00218 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHER: 00219 Type = ELF::R_PPC64_DTPREL16_HIGHER; 00220 break; 00221 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHERA: 00222 Type = ELF::R_PPC64_DTPREL16_HIGHERA; 00223 break; 00224 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHEST: 00225 Type = ELF::R_PPC64_DTPREL16_HIGHEST; 00226 break; 00227 case MCSymbolRefExpr::VK_PPC_DTPREL_HIGHESTA: 00228 Type = ELF::R_PPC64_DTPREL16_HIGHESTA; 00229 break; 00230 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD: 00231 if (is64Bit()) 00232 Type = ELF::R_PPC64_GOT_TLSGD16; 00233 else 00234 Type = ELF::R_PPC_GOT_TLSGD16; 00235 break; 00236 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_LO: 00237 Type = ELF::R_PPC64_GOT_TLSGD16_LO; 00238 break; 00239 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HI: 00240 Type = ELF::R_PPC64_GOT_TLSGD16_HI; 00241 break; 00242 case MCSymbolRefExpr::VK_PPC_GOT_TLSGD_HA: 00243 Type = ELF::R_PPC64_GOT_TLSGD16_HA; 00244 break; 00245 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD: 00246 if (is64Bit()) 00247 Type = ELF::R_PPC64_GOT_TLSLD16; 00248 else 00249 Type = ELF::R_PPC_GOT_TLSLD16; 00250 break; 00251 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_LO: 00252 Type = ELF::R_PPC64_GOT_TLSLD16_LO; 00253 break; 00254 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HI: 00255 Type = ELF::R_PPC64_GOT_TLSLD16_HI; 00256 break; 00257 case MCSymbolRefExpr::VK_PPC_GOT_TLSLD_HA: 00258 Type = ELF::R_PPC64_GOT_TLSLD16_HA; 00259 break; 00260 case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 00261 /* We don't have R_PPC64_GOT_TPREL16, but since GOT offsets 00262 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_DS. */ 00263 Type = ELF::R_PPC64_GOT_TPREL16_DS; 00264 break; 00265 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 00266 /* We don't have R_PPC64_GOT_TPREL16_LO, but since GOT offsets 00267 are always 4-aligned, we can use R_PPC64_GOT_TPREL16_LO_DS. */ 00268 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 00269 break; 00270 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HI: 00271 Type = ELF::R_PPC64_GOT_TPREL16_HI; 00272 break; 00273 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 00274 /* We don't have R_PPC64_GOT_DTPREL16, but since GOT offsets 00275 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_DS. */ 00276 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 00277 break; 00278 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 00279 /* We don't have R_PPC64_GOT_DTPREL16_LO, but since GOT offsets 00280 are always 4-aligned, we can use R_PPC64_GOT_DTPREL16_LO_DS. */ 00281 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 00282 break; 00283 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_HA: 00284 Type = ELF::R_PPC64_GOT_TPREL16_HA; 00285 break; 00286 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HI: 00287 Type = ELF::R_PPC64_GOT_DTPREL16_HI; 00288 break; 00289 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_HA: 00290 Type = ELF::R_PPC64_GOT_DTPREL16_HA; 00291 break; 00292 } 00293 break; 00294 case PPC::fixup_ppc_half16ds: 00295 switch (Modifier) { 00296 default: llvm_unreachable("Unsupported Modifier"); 00297 case MCSymbolRefExpr::VK_None: 00298 Type = ELF::R_PPC64_ADDR16_DS; 00299 break; 00300 case MCSymbolRefExpr::VK_PPC_LO: 00301 Type = ELF::R_PPC64_ADDR16_LO_DS; 00302 break; 00303 case MCSymbolRefExpr::VK_GOT: 00304 Type = ELF::R_PPC64_GOT16_DS; 00305 break; 00306 case MCSymbolRefExpr::VK_PPC_GOT_LO: 00307 Type = ELF::R_PPC64_GOT16_LO_DS; 00308 break; 00309 case MCSymbolRefExpr::VK_PPC_TOC: 00310 Type = ELF::R_PPC64_TOC16_DS; 00311 break; 00312 case MCSymbolRefExpr::VK_PPC_TOC_LO: 00313 Type = ELF::R_PPC64_TOC16_LO_DS; 00314 break; 00315 case MCSymbolRefExpr::VK_PPC_TPREL: 00316 Type = ELF::R_PPC64_TPREL16_DS; 00317 break; 00318 case MCSymbolRefExpr::VK_PPC_TPREL_LO: 00319 Type = ELF::R_PPC64_TPREL16_LO_DS; 00320 break; 00321 case MCSymbolRefExpr::VK_PPC_DTPREL: 00322 Type = ELF::R_PPC64_DTPREL16_DS; 00323 break; 00324 case MCSymbolRefExpr::VK_PPC_DTPREL_LO: 00325 Type = ELF::R_PPC64_DTPREL16_LO_DS; 00326 break; 00327 case MCSymbolRefExpr::VK_PPC_GOT_TPREL: 00328 Type = ELF::R_PPC64_GOT_TPREL16_DS; 00329 break; 00330 case MCSymbolRefExpr::VK_PPC_GOT_TPREL_LO: 00331 Type = ELF::R_PPC64_GOT_TPREL16_LO_DS; 00332 break; 00333 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL: 00334 Type = ELF::R_PPC64_GOT_DTPREL16_DS; 00335 break; 00336 case MCSymbolRefExpr::VK_PPC_GOT_DTPREL_LO: 00337 Type = ELF::R_PPC64_GOT_DTPREL16_LO_DS; 00338 break; 00339 } 00340 break; 00341 case PPC::fixup_ppc_nofixup: 00342 switch (Modifier) { 00343 default: llvm_unreachable("Unsupported Modifier"); 00344 case MCSymbolRefExpr::VK_PPC_TLSGD: 00345 if (is64Bit()) 00346 Type = ELF::R_PPC64_TLSGD; 00347 else 00348 Type = ELF::R_PPC_TLSGD; 00349 break; 00350 case MCSymbolRefExpr::VK_PPC_TLSLD: 00351 if (is64Bit()) 00352 Type = ELF::R_PPC64_TLSLD; 00353 else 00354 Type = ELF::R_PPC_TLSLD; 00355 break; 00356 case MCSymbolRefExpr::VK_PPC_TLS: 00357 if (is64Bit()) 00358 Type = ELF::R_PPC64_TLS; 00359 else 00360 Type = ELF::R_PPC_TLS; 00361 break; 00362 } 00363 break; 00364 case FK_Data_8: 00365 switch (Modifier) { 00366 default: llvm_unreachable("Unsupported Modifier"); 00367 case MCSymbolRefExpr::VK_PPC_TOCBASE: 00368 Type = ELF::R_PPC64_TOC; 00369 break; 00370 case MCSymbolRefExpr::VK_None: 00371 Type = ELF::R_PPC64_ADDR64; 00372 break; 00373 case MCSymbolRefExpr::VK_PPC_DTPMOD: 00374 Type = ELF::R_PPC64_DTPMOD64; 00375 break; 00376 case MCSymbolRefExpr::VK_PPC_TPREL: 00377 Type = ELF::R_PPC64_TPREL64; 00378 break; 00379 case MCSymbolRefExpr::VK_PPC_DTPREL: 00380 Type = ELF::R_PPC64_DTPREL64; 00381 break; 00382 } 00383 break; 00384 case FK_Data_4: 00385 Type = ELF::R_PPC_ADDR32; 00386 break; 00387 case FK_Data_2: 00388 Type = ELF::R_PPC_ADDR16; 00389 break; 00390 } 00391 } 00392 return Type; 00393 } 00394 00395 bool PPCELFObjectWriter::needsRelocateWithSymbol(const MCSymbolData &SD, 00396 unsigned Type) const { 00397 switch (Type) { 00398 default: 00399 return false; 00400 00401 case ELF::R_PPC_REL24: 00402 // If the target symbol has a local entry point, we must keep the 00403 // target symbol to preserve that information for the linker. 00404 // The "other" values are stored in the last 6 bits of the second byte. 00405 // The traditional defines for STO values assume the full byte and thus 00406 // the shift to pack it. 00407 unsigned Other = MCELF::getOther(SD) << 2; 00408 return (Other & ELF::STO_PPC64_LOCAL_MASK) != 0; 00409 } 00410 } 00411 00412 MCObjectWriter *llvm::createPPCELFObjectWriter(raw_ostream &OS, 00413 bool Is64Bit, 00414 bool IsLittleEndian, 00415 uint8_t OSABI) { 00416 MCELFObjectTargetWriter *MOTW = new PPCELFObjectWriter(Is64Bit, OSABI); 00417 return createELFObjectWriter(MOTW, OS, IsLittleEndian); 00418 }