ELFObjectWriter.cpp revision 7aabcb1fc0a94becb437134747a63ff686c0661f
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) 128aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky Write16(ELF::SHN_UNDEF); 1297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 133b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky if (ShstrtabIndex >= 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 || 305d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB || 306d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB_SHNDX) 307a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 3087be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 3094beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); 310a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 311a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3163223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 3173223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 3183223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 3197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3202ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3282ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 3323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3331f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 3341f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFragment &F, 336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 337e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 3381f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 33994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 34094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 34294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 34394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 34494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 34594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 34694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 3471f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 3481f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 34994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 35094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 35194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 35294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 35394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3547eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 3557eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 35694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 35725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 3587eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 35925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 360e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 3617eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 36225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 36325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 36425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 36525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 36625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 36725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 3688cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 3693729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 3703729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 3713729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3728cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 373c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 374c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 37525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 37694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 37794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 37894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 37994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3803729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3811c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 38294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 383e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 38494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 38594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 38694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 3871f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 388c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 389e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 390e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 39173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 39273ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 3933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 39456a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 40356a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 40456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 405127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 40756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 409e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 41756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Ofeset of the relocation in the section 42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 42556a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 43256a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 43656a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 43756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 43956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 44056a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 441bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 44356a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 44456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 44556a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 44656a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 44756a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 4482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 44956a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 45056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 4512a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 4522a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky adjustFixupOffset(Fixup, RelocOffset); 45356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 454bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 455bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 456bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 457bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola if (is64Bit()) 458bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<64>(Addend)); 459bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola else 460bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<32>(Addend)); 461bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 46256a399023aba6cf1348533df04732950c43eaca7Jason W Kim ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); 46356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 46456a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 46556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 46656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 4670b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 468115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 469115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 4707b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 471ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4742ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 4752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 4762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 477484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 478484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 479484291c27319668ad99cb87def000254357736fbRafael Espindola 480bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 481bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 482bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 48388182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 48488182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 48588182132470527e27231f09b25a885893e528c66Rafael Espindola 486737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 487a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 488d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 489d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 490d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 49194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 49221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 49321451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 49421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 4952ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 49621451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 497a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 498a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 499737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 500737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 501737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 502bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 503737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 504737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 505737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 506737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 507737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 5082ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 5092ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 510737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 511737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 512737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 513737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 51494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 5171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 5181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 5191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 520737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 5211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 522737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 523737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 524737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 525737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 526115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 5277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 5287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 529bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 530bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 531bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 532bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 533bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 5352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 5362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 5372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 5382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 5392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 5402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 5412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 5422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 5447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 5457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 5462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 547bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 5487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 5497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 5507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 551bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 552bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 553bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 554115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 5551f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 5567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 5577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 5585c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 559378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 5605c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 5615c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 5625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 5635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 5645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 5652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 5665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 5675c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 5683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 5713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 572d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 573d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 574d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 575a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 5763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 580484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 581484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 5821f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 5831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 5851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 58688182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 59194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 5941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 5951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 5962ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 5971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 5982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 5992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 6001f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 6011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 602484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 6032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 604484291c27319668ad99cb87def000254357736fbRafael Espindola 605f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 606a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 607f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 608bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 609a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 61088182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 6111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 6121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 6131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 6141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 6153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 616bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 617bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 618bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 6197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 6207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 6213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 6225df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 6235df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 62488182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 62588182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 62688182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 6271261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 6281261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 62988182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 63088182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 6311261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 6321261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 6331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 6341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 63588182132470527e27231f09b25a885893e528c66Rafael Espindola } 63688182132470527e27231f09b25a885893e528c66Rafael Espindola 6371261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 638a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 639a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 6401261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 641a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 6423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 643a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 644a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 645a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 646a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 647a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 648a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 649a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 6503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 659ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 662ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 663ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 664ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 6653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6697aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky 6707aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky if (NumRegularSections > ELF::SHN_LORESERVE) 6717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky NeedsSymtabShndx = true; 6723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 6757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 6843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 6853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 6863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 688bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 690299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 691299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 692bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 693bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 694299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 695bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 6963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 6987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 6997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 7007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 7017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 7027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 7037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 7047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 7057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 7067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 7077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 7087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 7097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 7107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 7117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 7127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 7137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 7143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 7167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 7177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 7183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 719bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 7227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 7233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 726115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 727115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 728115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 729115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 730115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 731115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 7323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 7333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 7343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 7353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 7363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 7373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 7383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 7393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 7403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 7413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 7423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 744115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 745115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 746115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 7473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 7483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 7503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 7523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 7533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 75412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 75512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 75612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 7578f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 7588f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 75912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 760bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 761af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 7625e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7638f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 7648f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 765af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 7665e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 767bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 768af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 7695e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 770af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 7715e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7728f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 7738f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 774af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 7755e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 776bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 777af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 7785e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 7793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 782d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 783d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 784d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 785d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 786d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 787d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 788d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 789d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 790d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 791d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 792d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 793d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 794d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 795d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 796d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 797d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 798d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 799d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 800115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 801115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 8027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 8043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 8053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 807bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 80938738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 8104283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 8117be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 8123f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 81371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 81471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 81571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8164283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 8177be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 8187be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 8192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 8203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 821bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 8227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 8247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8264283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 8277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 8282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 8297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 8307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 8317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 8343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 8353f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 8363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 8373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 8383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 8407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 8417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 8427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 84471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 84571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 84671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 8477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 8487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 8507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8514beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 85271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 8543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 8553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 8573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 858d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 859d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 860d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 861d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 862d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 863d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 864d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 865d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 866d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 8673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 8683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 874d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 875d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 8763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8772ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 878d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 879d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 880d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 881d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 882d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 883d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 8842ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 8863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 8872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 8902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 8913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8937070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 8947070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 89596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 89696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 89796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 8987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 8997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 9007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 90196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 90296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 90396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 90496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 90596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 90696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 90796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 90896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 90996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 9102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 9112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 9132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9151c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 9192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 9201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 9212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 92296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 9232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 9252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 9272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 9292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 9327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 9342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 9362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9381c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9401f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 9412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 9432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 9457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 9462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 9482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 949115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 950115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 951115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 952115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 953115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 954115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 955c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 956c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 957c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 968c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 969c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 9703f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 971c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 972c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 973c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 974c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 975c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 976c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 977c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 978c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 979c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 9803f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 981c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 982c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 983c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 984c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 985c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 986c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 987c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 988c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 989c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 990c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 991c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 992c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 993c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 994c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 995c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 996c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 997c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 99898976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 999c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1000c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 100186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 100286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 100386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 10040cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1005c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1006c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1007c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10084a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 10092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 10102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 10112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 10122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1013c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1014c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1015c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1016c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1017c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1018c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1019c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1020c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1021c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1022c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10232ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1024f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 10256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 10266db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10282ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 10296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 10306db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 10326db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 10336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 10356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 10366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 10376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 10402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10416db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 10436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 10446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 10472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 105085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 10516db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10526db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 10547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FileOff = OS.tell(); 10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += Padding; 10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += GetSectionFileSize(Layout, SD); 10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.WriteSectionData(&SD, Layout); 10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 10907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 10917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 10947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 10957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 10967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 10977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 10987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 11117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 11177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 11197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 11257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 11337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 11347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 11437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 11466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 11476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1148115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1149115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 11502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 11511f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1152bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1153bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 11557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 11607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 11637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1166bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11678f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 11697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11728f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 11733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 11744beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 11757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 11767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 11771d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1178bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1179bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1180bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1181a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 11847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 11857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 11867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 11877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1191a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1192a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 11947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 11957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 11976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1200a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1201a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 12033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 12057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 12067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 12073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 12092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 12102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1211a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1213a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 12152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 121644cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 12177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 12186db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 12193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 12227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 12267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 12277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 1230a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1231a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1232a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 12347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 12357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 12363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 12386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1239aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky // ... and then the remaining sections ... 12407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 12417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 12433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 124478c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 124578c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 124678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 124778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 124878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 124978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 125078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 125178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 125278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 125378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 125478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 125578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 12566024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 12576024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1258bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 1259bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (MOTW->getEMachine()) { 1260d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1261d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1262bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1263d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1264bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12654b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 1266bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12672c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC: 12682c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC64: 12692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1270291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka case ELF::EM_MIPS: 1271291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12723285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1273d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1274d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1275d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1276d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1277d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1278d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1279d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 128031f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1281bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1282bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1283bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1284d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1285d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1286d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1287d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1288d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 12892d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple. 12902d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() { 12912d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion); 12922d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim} 12932d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim 1294953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly. 1295953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol. 1296e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// This code is an approximation of what ARM/gcc does. 1297e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1298e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(PCRelCount, "Total number of PIC Relocations"); 1299e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(NonPCRelCount, "Total number of non-PIC relocations"); 1300953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1301953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1302953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCValue &Target, 1303953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCFragment &F, 1304e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1305e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1306953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 1307953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool EmitThisSym = false; 1308953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1309e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCSectionELF &Section = 1310e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim static_cast<const MCSectionELF&>(Symbol.getSection()); 1311e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool InNormalSection = true; 1312e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim unsigned RelocType = 0; 1313e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel); 1314e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 13156dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay DEBUG( 13166dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 13176dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VariantKind Kind2; 13186dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay Kind2 = Target.getSymB() ? Target.getSymB()->getKind() : 13196dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VK_None; 13206dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay dbgs() << "considering symbol " 1321e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Section.getSectionName() << "/" 1322e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.getName() << "/" 1323e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Rel:" << (unsigned)RelocType 1324e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Kind: " << (int)Kind << "/" << (int)Kind2 1325e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Tmp:" 1326e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/" 1327e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isVariable() << "/" << Symbol.isTemporary() 1328e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n"); 1329e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1330bebd44a95a94189e79b02cd15edc2d41bc2628feJason W Kim if (IsPCRel) { ++PCRelCount; 1331e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1332e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: 1333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // Most relocation types are emitted as explicit symbols 1334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1337e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1338e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1339e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1340e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = true; 1341e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1342e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: 1343e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // But things get strange with R_ARM_ABS32 1344e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // In this case, most things that go in .rodata show up 1345e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // as section relative relocations 1346e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1347e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1348e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1349e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1350e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1351e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1352e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1353e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = false; 1354e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1355e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1356953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } else { 1357e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim NonPCRelCount++; 1358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1359e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1360e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1361e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1362e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1363e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1364e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1365e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1366e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1367e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: EmitThisSym = true; break; 1368e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: EmitThisSym = false; break; 1369e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1370953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } 1371e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1372953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (EmitThisSym) 1373953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1374e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim if (! Symbol.isTemporary() && InNormalSection) { 1375953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1376e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1377953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return NULL; 1378953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim} 1379953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1380e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// Need to examine the Fixup when determining whether to 1381e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// emit the relocation as an explicit symbol or as a section relative 1382e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// offset 138385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 138485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 138556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 138656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 138756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 138885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 138985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 139085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1391e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim unsigned Type = GetRelocTypeInner(Target, Fixup, IsPCRel); 1392e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1393e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim if (RelocNeedsGOT(Modifier)) 1394e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim NeedsGOT = true; 1395e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1396e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return Type; 1397e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim} 1398e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1399e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kimunsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, 1400e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1401e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1402e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 1403e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1404e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1405a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 140685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 140785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 140885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 14093fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 14103fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14113fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 14123fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 1413e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim Type = ELF::R_ARM_REL32; 14141d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14153fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14161d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "unimplemented"); 14171d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14183fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14193fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14201d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14211d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14221d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1423685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 14243fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14253fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 14261d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_PLT32; 14271d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14283fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 14291d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 14301d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1433685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1434685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1435685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 143686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16: 143786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 14381d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_PREL; 14391d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 144086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16: 144186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: 14421d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_PREL_NC; 14431d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1444f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1445f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 1446f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_PREL; 1447f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1448f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1449f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 1450f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_PREL_NC; 1451f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1452298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_bl: 1453298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_blx: 1454298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola switch (Modifier) { 1455298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case MCSymbolRefExpr::VK_ARM_PLT: 1456298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_THM_CALL; 1457298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1458298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola default: 1459298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_NONE; 1460298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1461298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola } 1462298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 146385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 146485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 146585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 146685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1467a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1468a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 14693fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 14703fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 14711d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOT_BREL; 14721d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14733fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14741d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_GD32; 14751d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1476f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 14771d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_LE32; 14781d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1479a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14801d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1482f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 14831d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_ABS32; 14841d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14853fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 14861d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOTOFF32; 14871d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14881d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14891d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1490dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 14919d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1492dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1493662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1494b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1495b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1496e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 14971d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "Unimplemented"); 14981d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1499685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 15001d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 15011d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1502685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1503685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1504685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 15051d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim case ARM::fixup_arm_movt_hi16: 15061d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_ABS; 15071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 150885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 15091d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; 15101d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1511f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1512f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_ABS; 1513f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1514f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1515f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_ABS_NC; 1516f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 151785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1520a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 152185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 152285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 15232c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky//===- PPCELFObjectWriter -------------------------------------------===// 15242c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15252c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15262c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky raw_ostream &_OS, 15272c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsLittleEndian) 15282c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15292c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15302c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15312c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::~PPCELFObjectWriter() { 15322c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15332c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divackyunsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 15352c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky const MCFixup &Fixup, 15362c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsPCRel, 15372c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsRelocWithSymbol, 15382c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky int64_t Addend) { 15392c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky // determine the type of the relocation 15402c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky unsigned Type; 15412c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky if (IsPCRel) { 15422c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15432c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: 15442c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky llvm_unreachable("Unimplemented"); 15452c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15462c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL24; 15472c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15482c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_PCRel_4: 15492c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL32; 15502c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15512c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15522c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } else { 15532c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15542c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: llvm_unreachable("invalid fixup kind!"); 15552c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15562c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR24; 15572c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15582c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_brcond14: 15592c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ 15602c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15612c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_ha16: 15622c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_HA; 15632c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15642c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo16: 15652c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_LO; 15662c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15672c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo14: 15682c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14; 15692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_4: 15712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR32; 15722c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15732c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_2: 15742c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16; 15752c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15762c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15772c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15782c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return Type; 15792c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15802c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15812a66cea1b82b82c7bf19e232aed741331377ad30Roman Divackyvoid 15822a66cea1b82b82c7bf19e232aed741331377ad30Roman DivackyPPCELFObjectWriter::adjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { 15832a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky switch ((unsigned)Fixup.getKind()) { 15842a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky case PPC::fixup_ppc_ha16: 15852a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky case PPC::fixup_ppc_lo16: 15862a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky RelocOffset += 2; 15872a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky break; 15882a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky default: 15892a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky break; 15902a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky } 15912a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky} 15922a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1594d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 159531f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1596bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1597bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1598bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 16004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 16014b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 160456a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 160656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 160756a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 160856a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 16094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 16104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 16114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1615e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 16164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 16174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1618e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 16194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 16204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 16234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 16254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 162656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 162756a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 162856a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 16294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16304b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 16314b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 16324b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16334b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16344b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 163556a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 16364b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1637d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1638d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1639d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1640d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 164131f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1642bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1643bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1644bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1645d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1646d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1647d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1648d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 165056a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 165156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 165256a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 165356a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 165456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 1655d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1656d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 165712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 165812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1659d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1660bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1661d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 16623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch ((unsigned)Fixup.getKind()) { 16633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 1664debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 1665debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_8: Type = ELF::R_X86_64_PC64; break; 1666debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_4: Type = ELF::R_X86_64_PC32; break; 1667debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_2: Type = ELF::R_X86_64_PC16; break; 1668debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 16693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 16703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 16713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC64; 1672d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16737a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola case X86::reloc_signed_4byte: 1674c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola case X86::reloc_riprel_4byte_movq_load: 16753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case X86::reloc_riprel_4byte: 16763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_4: 16773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch (Modifier) { 16783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: 16793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola llvm_unreachable("Unimplemented"); 16803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_None: 16813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC32; 16823a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_PLT: 16843a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PLT32; 16853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16863a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 16873a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTPCREL; 16883a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16893a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 16903a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTTPOFF; 1691d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16923a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 16933a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSGD; 16943a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16953a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 16963a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSLD; 16973a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16983a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola } 1699d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 17003a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_2: 17013a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 17023a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC16; 1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1704d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger case FK_PCRel_1: 1705d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger assert(Modifier == MCSymbolRefExpr::VK_None); 1706d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger Type = ELF::R_X86_64_PC8; 1707d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger break; 1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1731d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1737d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1738e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1739d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1740d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1741d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1743d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1744d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1745d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1746d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1747d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1748d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PC32; 1749d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1750d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1751d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PLT32; 1752d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1753d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1754d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1755d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1756d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1765e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1770d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1773d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1774d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1782d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1783d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1784d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1785d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1786d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1787d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1788d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1789d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1790d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1791d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1792d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1793d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1794d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1795d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1796d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1797d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1798d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1799d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1800e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky case MCSymbolRefExpr::VK_GOTTPOFF: 1801e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky Type = ELF::R_386_TLS_IE_32; 1802e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky break; 1803d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1804d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1805d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1806e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1807d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1808d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1809d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1810d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1811d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1812d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (RelocNeedsGOT(Modifier)) 1813d3443e99e43945fdb0742177da06a32fa225740dJason W Kim NeedsGOT = true; 1814d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 181556a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 18163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1817291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 1818291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1819291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka raw_ostream &_OS, 1820291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsLittleEndian) 1821291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {} 1822291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 1823291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::~MipsELFObjectWriter() {} 1824291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 1825291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanakaunsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, 1826291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka const MCFixup &Fixup, 1827291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsPCRel, 1828291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsRelocWithSymbol, 1829291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka int64_t Addend) { 1830291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka // tbd 1831291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka return 1; 1832291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka} 1833