ELFObjectWriter.cpp revision 2c0d69fad0e658117922f3d96d9b732bedf9fd47
13565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -------------------===// 23565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// 33565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// The LLVM Compiler Infrastructure 43565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// 53565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file is distributed under the University of Illinois Open Source 63565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// License. See LICENSE.TXT for details. 73565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// 83565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===// 93565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// 103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// This file implements ELF object file writer information. 113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// 123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming//===----------------------------------------------------------------------===// 133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1424b17c673076af1bb77dd24096c8d17c734c94bcJan Sjödin#include "ELFObjectWriter.h" 153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.h" 163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h" 173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/Twine.h" 1878c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h" 193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h" 203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h" 213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h" 223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h" 233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h" 243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h" 253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h" 263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h" 27e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#include "llvm/Support/CommandLine.h" 28e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#include "llvm/ADT/Statistic.h" 29a7cfc08ebe737062917b442830eb5321b0f79e89Evan Cheng#include "llvm/ADT/StringSwitch.h" 303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 318c3fee59038d8fd98db2a01b6a309a8941a16a3fEvan Cheng#include "../Target/X86/MCTargetDesc/X86FixupKinds.h" 32be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h" 332c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" 343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 363565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 38e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef DEBUG_TYPE 39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info" 40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 55378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola case MCSymbolRefExpr::VK_GOTOFF: 562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 69d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 70d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 71d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 73115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 74115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 88bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 91115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 945baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 95bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (TargetObjectWriter->getOSType()) { 965baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; 975baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; 985baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky default: Write8(ELF::ELFOSABI_NONE); break; 995baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky } 1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 106bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 111bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 112eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1142d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 1152d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim WriteEFlags(); 1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 118bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 1213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 124bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 1277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 1287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(0); 1297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 1337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 1347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 1357be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 1373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 139115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 140115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 141115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 142115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 143115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 144115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 145115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 1467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 1477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 148af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 1497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 150af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 1517be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 1527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 153af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 154af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 1553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 156bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 157af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 158af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 159af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 160af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 161af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 162af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 164af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 165af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 166af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 167af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 168af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 169af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 1703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 1713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 1742ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 1752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 1762c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 1772c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1782c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 179d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 180d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 181d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 182d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 183d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 184d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky return (uint64_t)IntValue; 185d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 186d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 187d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 1882c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 1892c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 1902c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 1926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFragment()) { 1936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFlags() & ELF_Other_ThumbFunc) 1946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data)+1; 1956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola else 1966469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data); 1976469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 1982c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1992c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 2002c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 2012c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 20285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 20385f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 20488182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 20588182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 20688182132470527e27231f09b25a885893e528c66Rafael Espindola 20788182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 20888182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 20988182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 21094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 211f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 212f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 213f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 214f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 215f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 216f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 21707ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 21888182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 21988182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 22088182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 22188182132470527e27231f09b25a885893e528c66Rafael Espindola 222f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 223f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 224f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 2252ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 226f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 22707ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 22888182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 22988182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 23088182132470527e27231f09b25a885893e528c66Rafael Espindola 23183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 23283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 23383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 23483ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 23583ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 23607ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 23788182132470527e27231f09b25a885893e528c66Rafael Espindola } 23888182132470527e27231f09b25a885893e528c66Rafael Espindola} 23988182132470527e27231f09b25a885893e528c66Rafael Espindola 240115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 241115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 242115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 243115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 244de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 245de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 24694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 247152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 2497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 2507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 2512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 2522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Visibility = MCELF::GetVisibility(OrigData); 2532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 254152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 255152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 256152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 257152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2582c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 2593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 2603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 261f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 262f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 263f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 264f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 265f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 266f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 267f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 268f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 2693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 2727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 2737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 2743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 2753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 276115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 277115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 278115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 279115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 2804beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap) { 2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 2823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 2833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 2863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 2887be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 2913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 2923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 2947be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 2953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 29771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 2984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 2994beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 300a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 3014beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 3024beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 3034beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 3044beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 3054beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_SYMTAB) 306a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 3077be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 3084beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); 309a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 310a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3153223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 3163223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 3173223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 3187be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3192ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3272ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 3331f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFragment &F, 335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 3371f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 33894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 33994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 34094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 34294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 34394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 34494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 34594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 3461f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 3471f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 34894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 34994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 35094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 35194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 35294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3537eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 3547eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 35594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 35625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 3577eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 35825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 359e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 3607eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 36125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 36225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 36325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 36425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 36525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 36625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 3678cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 3683729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 3693729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 3703729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3718cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 372c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 373c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 37425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 37594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 37694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 37794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 37894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3793729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3801c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 38194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 382e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 38394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 38494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 38594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 3861f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 387c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 388e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 389e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 39073ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 39173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 39356a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 40356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 404127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 40556a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 40756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 408e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 41756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Ofeset of the relocation in the section 41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 42556a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 43256a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 43656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 43756a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 43956a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 440bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 44156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 44356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 44456a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 44556a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 44656a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 4472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 44856a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 44956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 4502c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 4512c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_ha16: 4522c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo16: 4532c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky RelocOffset += 2; 4542c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 4552c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: 4562c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 4572c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 45856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 459bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 460bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 46156a399023aba6cf1348533df04732950c43eaca7Jason W Kim ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); 46256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 46356a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 46456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 46556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 4660b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 467115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 468115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 4697b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 470ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 4742ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 4752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 476484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 477484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 478484291c27319668ad99cb87def000254357736fbRafael Espindola 479bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 480bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 481bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 48288182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 48388182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 48488182132470527e27231f09b25a885893e528c66Rafael Espindola 485737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 486a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 487d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 488d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 489d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 49094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 49121451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 49221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 49321451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 4942ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 49521451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 496a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 497a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 498737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 499737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 500737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 501bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 502737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 503737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 504737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 505737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 506737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 5072ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 5082ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 509737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 510737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 511737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 512737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 51394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 5161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 5171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 5181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 519737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 5201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 521737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 522737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 523737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 524737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 525115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 5267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 5277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 528bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 529bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 530bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 531bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 532bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 5342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 5352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 5362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 5372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 5382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 5392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 5402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 5412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 5437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 5447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 5452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 546bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 5477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 5487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 5497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 550bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 551bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 552bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 553115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 5541f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 5557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 5567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 5575c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 558378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 5595c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 5605c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 5615c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 5625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 5635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 5642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 5655c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 5665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 5673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 5683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 571d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 572d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 573d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 574a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 5753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 5763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 579484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 580484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 5811f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 5821f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 58588182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 59094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 5931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 5941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 5952ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 5961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 5972ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 5982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 5991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 6001f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 601484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 6022ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 603484291c27319668ad99cb87def000254357736fbRafael Espindola 604f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 605a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 606f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 607bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 608a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 60988182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 6101f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 6111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 6121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 6131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 6143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 615bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 616bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 617bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 6187be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 6197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 6203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 6215df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 6225df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 62388182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 62488182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 62588182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 6261261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 6271261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 62888182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 62988182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 6301261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 6311261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 6321261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 6331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 63488182132470527e27231f09b25a885893e528c66Rafael Espindola } 63588182132470527e27231f09b25a885893e528c66Rafael Espindola 6361261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 637a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 638a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 6391261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 640a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 642a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 643a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 644a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 645a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 646a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 647a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 648a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 6493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 658ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 661ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 662ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 663ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 6643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 6663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 6717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 6727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 6737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 6803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 6813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 6823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 684bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 6853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 686299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 687299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 688bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 689bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 690299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 691bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 6923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 6947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 6957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 6967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 6977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 6987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 6997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 7007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 7017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 7027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 7037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 7047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 7057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 7067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 7077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 7087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 7097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 7103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 7127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 7137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 7143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 715bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 7163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 7187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 7193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 722115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 723115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 724115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 725115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 726115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 727115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 7283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 7293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 7303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 7313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 7323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 7333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 7343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 7353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 7363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 7373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 7383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 740115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 741115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 742115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 7433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 7443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 7453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 7463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 7483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 75012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 75112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 75212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 7538f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 7548f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 75512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 756bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 757af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 7585e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7598f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 7608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 761af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 7625e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 763bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 764af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 7655e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 766af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 7675e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7688f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 7698f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 770af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 7715e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 772bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 773af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 7745e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 7753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 778d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 779d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 780d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 781d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 782d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 783d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 784d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 785d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 786d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 787d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 788d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 789d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 790d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 791d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 792d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 793d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 794d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 795d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 796115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 797115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 7987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 7997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 8003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 8013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 8023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 803bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 8043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 80538738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 8064283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 8077be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 8083f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 80971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 81071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 81171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8124283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 8137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 8147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 8152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 8163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 817bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 8187be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 8207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8224283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 8237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 8242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 8257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 8267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 8277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 8303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 8313f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 8323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 8333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 8343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 8367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 8377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 8387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 8397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 84071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 84171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 84271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 8437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 8447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 8467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8474beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 84871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 8503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 8513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 8533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 854d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 855d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 856d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 857d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 858d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 859d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 860d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 861d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 862d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 8633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 8643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 8653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 8663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 8673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 8683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 870d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 871d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 874d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 875d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 876d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 877d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 878d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 879d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 8802ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 8823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 8832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 8843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8897070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 8907070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 89196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 89296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 89396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 8947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 8957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 89796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 89896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 89996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 90096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 90196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 90296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 90396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 90496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 90596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 9062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 9072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 9092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9111c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 9152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 9161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 9172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 91896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 9192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 9212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 9232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 9252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 9287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 9302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 9322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9341c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9361f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 9372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 9392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 9417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 9422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 9442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 945115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 946115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 947115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 948115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 949115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 950115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 951c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 952c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 953c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 954c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 955c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 956c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 957c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 9663f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 968c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 969c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 970c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 971c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 972c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 973c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 974c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 975c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 9763f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 977c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 978c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 979c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 980c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 981c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 982c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 983c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 984c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 985c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 986c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 987c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 988c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 989c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 990c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 991c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 992c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 993c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 99498976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 995c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 996c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 99786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 99886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 99986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 10000cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1001c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1002c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1003c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10042ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola case ELF::SHT_GROUP: { 10052ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 10062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 10072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 10082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 10092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1010c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1011c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1012c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1013c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1014c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1015c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1016c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1017c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1018c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1019c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10202ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1021f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 10226db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 10236db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10246db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10252ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 10266db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 10276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 10296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 10306db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 10326db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 10336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 10346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10362ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 10372ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10396db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 10406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 10416db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 10442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 104785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 10486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 10517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 10537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FileOff = OS.tell(); 10547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += Padding; 10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += GetSectionFileSize(Layout, SD); 10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.WriteSectionData(&SD, Layout); 10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 10757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 10917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 10927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 10937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 10947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 10957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 10967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 10987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 11117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 11127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 11177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 11227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 11436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 11446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1145115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1146115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 11472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 11481f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1149bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1150bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 11527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 11607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1163bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11648f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11698f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 11703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 11714beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 11727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 11737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 11741d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1175bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1176bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1177bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1178a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 11793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11802ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 11817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 11827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 11837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 11847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 11852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1188a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1189a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 11917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 11927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 11946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1197a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1198a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 12003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 12037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 12043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 12062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 12072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1208a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1210a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 121344cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 12147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 12156db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 12163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 12197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 12207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 12227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 1227a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1228a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1229a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 12317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 12327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 12333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 12356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 12367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... and then the remainting sections ... 12377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 12387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 12403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 124178c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 124278c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 124378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 124478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 124578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 124678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 124778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 124878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 124978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 125078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 125178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 125278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 12536024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 12546024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1255bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 1256bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (MOTW->getEMachine()) { 1257d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1258d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1259bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1260d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1261bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12624b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 1263bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12642c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC: 12652c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC64: 12662c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12673285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1268d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1269d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1270d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1271d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1272d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1273d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1274d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 127531f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1276bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1277bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1278bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1279d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1280d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1281d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1282d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1283d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 12842d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple. 12852d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() { 12862d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion); 12872d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim} 12882d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim 1289953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly. 1290953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol. 1291e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// This code is an approximation of what ARM/gcc does. 1292e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1293e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(PCRelCount, "Total number of PIC Relocations"); 1294e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(NonPCRelCount, "Total number of non-PIC relocations"); 1295953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1296953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1297953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCValue &Target, 1298953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCFragment &F, 1299e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1300e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1301953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 1302953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool EmitThisSym = false; 1303953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1304e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCSectionELF &Section = 1305e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim static_cast<const MCSectionELF&>(Symbol.getSection()); 1306e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool InNormalSection = true; 1307e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim unsigned RelocType = 0; 1308e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel); 1309e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 13106dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay DEBUG( 13116dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 13126dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VariantKind Kind2; 13136dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay Kind2 = Target.getSymB() ? Target.getSymB()->getKind() : 13146dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VK_None; 13156dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay dbgs() << "considering symbol " 1316e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Section.getSectionName() << "/" 1317e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.getName() << "/" 1318e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Rel:" << (unsigned)RelocType 1319e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Kind: " << (int)Kind << "/" << (int)Kind2 1320e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Tmp:" 1321e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/" 1322e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isVariable() << "/" << Symbol.isTemporary() 1323e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n"); 1324e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1325bebd44a95a94189e79b02cd15edc2d41bc2628feJason W Kim if (IsPCRel) { ++PCRelCount; 1326e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1327e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: 1328e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // Most relocation types are emitted as explicit symbols 1329e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1330e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1331e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1332e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = true; 1336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1337e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: 1338e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // But things get strange with R_ARM_ABS32 1339e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // In this case, most things that go in .rodata show up 1340e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // as section relative relocations 1341e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1342e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1343e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1344e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1345e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1346e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1347e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1348e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = false; 1349e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1350e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1351953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } else { 1352e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim NonPCRelCount++; 1353e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1354e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1355e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1356e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1357e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1359e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1360e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1361e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1362e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: EmitThisSym = true; break; 1363e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: EmitThisSym = false; break; 1364e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1365953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } 1366e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1367953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (EmitThisSym) 1368953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1369e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim if (! Symbol.isTemporary() && InNormalSection) { 1370953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1371e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1372953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return NULL; 1373953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim} 1374953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1375e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// Need to examine the Fixup when determining whether to 1376e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// emit the relocation as an explicit symbol or as a section relative 1377e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// offset 137885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 137985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 138056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 138156a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 138256a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 138385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 138485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 138585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1386e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel); 1387e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1388e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim if (RelocNeedsGOT(Modifier)) 1389e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim NeedsGOT = true; 1390e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1391e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return Type; 1392e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim} 1393e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1394e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kimunsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, 1395e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1396e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1397e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 1398e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1399e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1400a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 140185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 140285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 140385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 14043fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 14053fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14063fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 14073fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 1408e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim Type = ELF::R_ARM_REL32; 14091d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14103fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14111d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "unimplemented"); 14121d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14133fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14143fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14151d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14161d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14171d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1418685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 14193fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14203fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 14211d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_PLT32; 14221d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14233fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 14241d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 14251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14261d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14271d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1428685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1429685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1430685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 143186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16: 143286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 14331d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_PREL; 14341d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 143586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16: 143686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: 14371d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_PREL_NC; 14381d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1439f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1440f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 1441f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_PREL; 1442f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1443f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1444f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 1445f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_PREL_NC; 1446f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1447298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_bl: 1448298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_blx: 1449298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola switch (Modifier) { 1450298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case MCSymbolRefExpr::VK_ARM_PLT: 1451298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_THM_CALL; 1452298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1453298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola default: 1454298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_NONE; 1455298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1456298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola } 1457298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 145885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 145985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 146085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 146185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1462a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1463a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 14643fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 14653fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 14661d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOT_BREL; 14671d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14683fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14691d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_GD32; 14701d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1471f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 14721d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_LE32; 14731d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1474a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14751d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14761d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1477f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 14781d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_ABS32; 14791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14803fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 14811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOTOFF32; 14821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14831d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14841d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1485dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 14869d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1487dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1488662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1489b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1490b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1491e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 14921d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "Unimplemented"); 14931d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1494685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 14951d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 14961d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1497685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1498685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1499685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 15001d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim case ARM::fixup_arm_movt_hi16: 15011d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_ABS; 15021d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 150385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 15041d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; 15051d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1506f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1507f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_ABS; 1508f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1509f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1510f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_ABS_NC; 1511f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 151285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1515a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 151685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 151785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 15182c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky//===- PPCELFObjectWriter -------------------------------------------===// 15192c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15202c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15212c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky raw_ostream &_OS, 15222c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsLittleEndian) 15232c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15242c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15252c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15262c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::~PPCELFObjectWriter() { 15272c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15282c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15292c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divackyunsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 15302c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky const MCFixup &Fixup, 15312c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsPCRel, 15322c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsRelocWithSymbol, 15332c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky int64_t Addend) { 15342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky // determine the type of the relocation 15352c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky unsigned Type; 15362c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky if (IsPCRel) { 15372c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15382c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: 15392c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky llvm_unreachable("Unimplemented"); 15402c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15412c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL24; 15422c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15432c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_PCRel_4: 15442c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL32; 15452c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15462c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15472c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } else { 15482c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15492c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: llvm_unreachable("invalid fixup kind!"); 15502c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15512c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR24; 15522c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15532c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_brcond14: 15542c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ 15552c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15562c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_ha16: 15572c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_HA; 15582c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15592c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo16: 15602c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_LO; 15612c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15622c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo14: 15632c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14; 15642c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15652c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_4: 15662c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR32; 15672c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15682c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_2: 15692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16; 15702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15722c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15732c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return Type; 15742c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15752c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15764b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1577d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 157831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1579bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1580bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1581bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15824b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15834b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 15844b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 15854b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 158756a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 15884b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 158956a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 159056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 159156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 15924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 15944b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 15954b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 15964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 15974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1598e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 15994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 16004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1601e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 16064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 16084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 160956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 161056a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 161156a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 16154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 161856a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 16194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1620d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1621d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1622d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1623d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 162431f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1625bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1626bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1627bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1628d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1629d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1630d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1631d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1632d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 163356a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 163456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 163556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 163656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 163756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 1638d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1639d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 164012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 164112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1642d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1643bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1644d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 16453a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch ((unsigned)Fixup.getKind()) { 16463a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 1647debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 1648debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_8: Type = ELF::R_X86_64_PC64; break; 1649debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_4: Type = ELF::R_X86_64_PC32; break; 1650debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_2: Type = ELF::R_X86_64_PC16; break; 1651debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 16523a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 16533a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 16543a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC64; 1655d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16567a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola case X86::reloc_signed_4byte: 1657c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola case X86::reloc_riprel_4byte_movq_load: 16583a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case X86::reloc_riprel_4byte: 16593a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_4: 16603a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch (Modifier) { 16613a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: 16623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola llvm_unreachable("Unimplemented"); 16633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_None: 16643a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC32; 16653a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16663a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_PLT: 16673a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PLT32; 16683a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 16703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTPCREL; 16713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16723a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 16733a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTTPOFF; 1674d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 16763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSGD; 16773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 16793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSLD; 16803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola } 1682d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_2: 16843a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 16853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC16; 1686d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1687d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger case FK_PCRel_1: 1688d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger assert(Modifier == MCSymbolRefExpr::VK_None); 1689d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger Type = ELF::R_X86_64_PC8; 1690d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger break; 1691d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1693d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1694d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1695d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1697d3443e99e43945fdb0742177da06a32fa225740dJason W Kim assert(isInt<32>(Target.getConstant())); 1698d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1699d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1700d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1722e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1731d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PC32; 1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PLT32; 1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1737d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1738d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1739d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1740d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1741d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1743d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1744d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1745d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1746d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1747d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1748d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1749e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1750d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1751d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1752d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1753d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1754d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1755d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1756d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1765d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1770d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1773d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1774d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1782d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1783d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1784e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky case MCSymbolRefExpr::VK_GOTTPOFF: 1785e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky Type = ELF::R_386_TLS_IE_32; 1786e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky break; 1787d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1788d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1789d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1790e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1791d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1792d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1793d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1794d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1795d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1796d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (RelocNeedsGOT(Modifier)) 1797d3443e99e43945fdb0742177da06a32fa225740dJason W Kim NeedsGOT = true; 1798d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 179956a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 18003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1801