ELFObjectWriter.cpp revision dc9a8a378daf432d8dcfc178507afe149706f9a6
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 31a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes#include "../Target/Mips/MCTargetDesc/MipsFixupKinds.h" 328c3fee59038d8fd98db2a01b6a309a8941a16a3fEvan Cheng#include "../Target/X86/MCTargetDesc/X86FixupKinds.h" 33be74029f44c32efc09274a16cbff588ad10dc5eaEvan Cheng#include "../Target/ARM/MCTargetDesc/ARMFixupKinds.h" 342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky#include "../Target/PowerPC/MCTargetDesc/PPCFixupKinds.h" 353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 373565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef DEBUG_TYPE 40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info" 41e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 56378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola case MCSymbolRefExpr::VK_GOTOFF: 572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 70d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 71d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 72d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 74115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 75115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 89bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 92115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 955baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 96dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola Write8(TargetObjectWriter->getOSABI()); 973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 103bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 1043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 108bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 109eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1112d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 1122d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim WriteEFlags(); 1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 115bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 121bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 1247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 125aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky Write16(ELF::SHN_UNDEF); 1267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 1283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 130b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky if (ShstrtabIndex >= ELF::SHN_LORESERVE) 1317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 1327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 1343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 136115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 137115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 138115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 139115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 140115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 141115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 142115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 1437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 1447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 145af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 1467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 147af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 1487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 1497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 150af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 151af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 1523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 153bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 154af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 155af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 156af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 157af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 158af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 159af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 161af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 162af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 163af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 164af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 165af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 166af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1702ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 1712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 1722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 1732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 1742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 176d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 177d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 178d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 179d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 180d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 181f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach return (uint64_t)IntValue; 182d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 183d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 184d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 1852c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 1862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 1872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 1896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFragment()) { 1906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFlags() & ELF_Other_ThumbFunc) 1916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data)+1; 1926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola else 1936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data); 1946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 1952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 1972c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 1982c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 19985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 20085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 20188182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 20288182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 20388182132470527e27231f09b25a885893e528c66Rafael Espindola 20488182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 20588182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 20688182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 20794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 208f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 209f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 210f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 211f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 212f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 213f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 21407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 21588182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 21688182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 21788182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 21888182132470527e27231f09b25a885893e528c66Rafael Espindola 219f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 220f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 221f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 2222ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 223f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 22407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 22588182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 22688182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 22788182132470527e27231f09b25a885893e528c66Rafael Espindola 22883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 22983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 23083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 23183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 23283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 23307ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 23488182132470527e27231f09b25a885893e528c66Rafael Espindola } 23588182132470527e27231f09b25a885893e528c66Rafael Espindola} 23688182132470527e27231f09b25a885893e528c66Rafael Espindola 237115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 238115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 239115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 240115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 241de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 242de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 24394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 244152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 2467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 2477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 2482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 2492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Visibility = MCELF::GetVisibility(OrigData); 2502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 251152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 252152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 253152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 254152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2552c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 2563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 2573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 258f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 259f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 260f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 261f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 262f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 263f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 264f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 265f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 2663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 2697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 2707be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 273115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 274115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 275115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 276115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 277a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes const SectionIndexMapTy &SectionIndexMap) { 2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 2793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 2833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 2857be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 2863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 2883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 2903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 2917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 2923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 29471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 2954beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 2964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 297a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 2984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 2994beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 3004beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 3014beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 302d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB || 303d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB_SHNDX) 304a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 3057be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 306a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), 307a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes false); 308a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 309a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3143223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 3153223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 3163223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 3177be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3182ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 3233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3262ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3311f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 3321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFragment &F, 334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 3361f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 33794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 33894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 33994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 34094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 34294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 34394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 34494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 3451f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 3461f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 34794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 34894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 34994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 35094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 35194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3527eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 3537eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 35494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 35525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 3567eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 35725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 3597eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 36025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 36125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 36225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 36325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 36425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 36525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 3668cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 3673729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 3683729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 3693729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3708cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 371c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 372c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 37325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 37494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 37594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 37694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 37794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3783729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3791c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 38094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 381e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 38294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 38394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 38494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 3851f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 386c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 387e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 388e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 38973ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 39073ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 39256a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 39356a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 403127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 40456a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 40556a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 407e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 417a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes // Offset of the relocation in the section 41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 42556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 43256a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 43656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 43756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 439bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 44056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 44156a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 44356a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 44456a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 44556a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 446c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 447c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 448c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola if (RelocNeedsGOT(Modifier)) 449c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola NeedsGOT = true; 4502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 45156a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 45256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 4532a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 4542a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky adjustFixupOffset(Fixup, RelocOffset); 45556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 456bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 457bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 458bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 459bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola if (is64Bit()) 460bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<64>(Addend)); 461bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola else 462bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<32>(Addend)); 463bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 46456a399023aba6cf1348533df04732950c43eaca7Jason W Kim ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); 46556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 46656a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 46756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 46856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 4690b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 470115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 471115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 4727b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 473ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 4772ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 4782ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 479484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 480484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 481484291c27319668ad99cb87def000254357736fbRafael Espindola 482bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 483bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 484bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 48588182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 48688182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 48788182132470527e27231f09b25a885893e528c66Rafael Espindola 488737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 489a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 490d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 491d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 492d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 49394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 49421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 49521451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 49621451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 4972ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 49821451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 499a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 500a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 501737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 502737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 503737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 504bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 505737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 506737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 507737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 508737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 509737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 5102ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 5112ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 512737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 513737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 514737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 515737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 51694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 5191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 5201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 5211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 522737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 5231f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 524737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 525737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 526737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 527737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 528115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 5297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 5307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 531bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 532bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 533bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 534bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 535bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 5372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 5382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 5392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 5402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 5412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 5422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 5432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 5442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 5467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 5477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 5482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 549bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 5507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 5517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 5527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 553bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 554bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 555bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 556115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 5571f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 5587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 5597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 5605c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 561378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 5625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 5635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 5645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 5655c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 5665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 5672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 5685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 5695c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 5713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 5723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 5733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 574d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 575d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 576d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 577a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 5803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 5813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 582484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 583484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 5851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 5871f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 58888182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 5923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 59394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 5961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 5971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 5982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 5991f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 6002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 6012ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 6021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 6031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 604484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 6052ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 606484291c27319668ad99cb87def000254357736fbRafael Espindola 607f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 608a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 609f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 610bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 611a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 61288182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 6131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 6141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 6151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 6161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 618bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 619bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 620bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 6217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 6227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 6245df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 6255df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 62688182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 62788182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 62888182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 6291261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 6301261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 63188182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 63288182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 6331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 6341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 6351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 6361261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 63788182132470527e27231f09b25a885893e528c66Rafael Espindola } 63888182132470527e27231f09b25a885893e528c66Rafael Espindola 6391261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 640a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 641a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 6421261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 643a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 6443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 645a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 646a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 647a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 648a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 649a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 650a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 651a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 661ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 6623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 664ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 665ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 666ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 6673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 6693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky 6727aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky if (NumRegularSections > ELF::SHN_LORESERVE) 6737aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky NeedsSymtabShndx = true; 6743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 6837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 6863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 6883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 690bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 6913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 692299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 693299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 694bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 695bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 696299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 697bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 6983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 7007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 7017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 7027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 7037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 7047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 7057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 7067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 7077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 7087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 7097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 7107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 7117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 7127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 7137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 7147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 7157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 7163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 7187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 7197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 721bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 7223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 7247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 7253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 728115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 729115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 730115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 731115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 732115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 733115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 7343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 7353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 7363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 7373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 7383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 7393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 7403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 7413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 7423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 7433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 7443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 746115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 747115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 748115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 7503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 7513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 7523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 7543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 7553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 75612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 75712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 75812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 7598f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 7608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 76112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 762bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 763af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 7645e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7658f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 7668f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 767af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 7685e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 769bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 770af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 7715e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 772af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 7735e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 7758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 776af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 7775e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 778bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 779af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 7805e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 7813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 784d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 785d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 786d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 787d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 788d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 789d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 790d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 791d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 792d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 793d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 794d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 795d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 796d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 797d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 798d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 799d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 800d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 801d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 802115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 803115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 8047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 8073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 809bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 8103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 81138738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 8124283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 8137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 8143f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 81571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 81671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 81771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8184283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 8197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 8207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 8212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 8223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 823bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 8247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 8267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 8277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8284283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 8297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 8302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 8317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 8327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 8337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 8363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 8373f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 8383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 8393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 8403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 8427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 8457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 84671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 84771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 84871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 8497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 8507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8517be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 8527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8534beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 85471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 8563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 8573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 8593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 860d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 861d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 862d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 863d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 864d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 865d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 866d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 867d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 868d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 8733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 8743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 876d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 877d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 880d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 881d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 882d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 883d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 884d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 885d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 8892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 8922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8957070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 8967070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 89796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 89896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 89996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 9007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 9017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 9027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 90396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 90496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 90596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 90696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 90796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 90896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 90996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 91096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 91196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 9122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 9132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 9152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9171c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 9212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 9221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 9232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 92496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 9252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 9272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 9292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 9312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 9347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 9362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 9382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9401c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9421f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 9432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 9452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 9477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 9482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 9502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 951115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 952115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 953115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 954115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 955115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 956115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 957c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 968c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 969c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 970c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 971c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 9723f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 973c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 974c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 975c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 976c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 977c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 978c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 979c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 980c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 981c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 9823f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 983c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 984c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 985c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 986c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 987c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 988c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 989c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 990c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 991c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 992c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 993c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 994c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 995c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 996c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 997c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 998c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 999c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 100098976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 1001c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1002c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 100386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 100486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 100586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 10060cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1007c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1008c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1009c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10104a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 10112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 10122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 10132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 10142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1015c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1016c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1017c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1018c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1019c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1020c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1021c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1022c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1023c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1024c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 10252ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1026f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 10276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 10286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10302ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 10316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 10326db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 10346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 10356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 10376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 10386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 10396db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 10422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 10456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 10466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 10492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10506db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10516db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 105285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 10536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FileOff = OS.tell(); 10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += Padding; 10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += GetSectionFileSize(Layout, SD); 10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 1075f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(&SD, Layout); 10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 10907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 10917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 10927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 10937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 10967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 10977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 10987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 11117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 11177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 11197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 11227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 11367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 11377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 11457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 11467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 11486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 11496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1150115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1151115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 11522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 11531f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1154bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1155bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 11637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1168bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11698f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 11707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 11717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 11753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 11764beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 11777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 11787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 11791d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1180bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1181bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1182bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1183a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 11843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 11867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 11877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 11887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 11897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 11902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1193a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1194a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 11967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 11977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 11996db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 12003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1202a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1203a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 12053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 12077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 12087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 12093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 12112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1213a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1215a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 12172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 121844cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 12197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 12206db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 12213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 12277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 12287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 12297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 1232a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1233a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1234a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 12367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 12377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 12383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 12406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1241aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky // ... and then the remaining sections ... 12427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 12437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 12453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 124678c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 124778c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 124878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 124978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 125078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 125178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 125278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 125378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 125478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 125578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 125678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 125778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 12586024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 12596024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1260bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 1261bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (MOTW->getEMachine()) { 1262d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1263d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1264bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1265d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1266bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12674b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 1268bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC: 12702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case ELF::EM_PPC64: 12712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return new PPCELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1272291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka case ELF::EM_MIPS: 1273291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka return new MipsELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12743285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1275d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1276d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1277d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1278d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1279d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1280d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 128131f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1282bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1283bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1284bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1285d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1286d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1287d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1288d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1289d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 12902d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple. 12912d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() { 12922d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion); 12932d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim} 12942d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim 1295953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly. 1296953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol. 1297e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// This code is an approximation of what ARM/gcc does. 1298e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1299e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(PCRelCount, "Total number of PIC Relocations"); 1300e964d1192a82cf8c1371a7440667de67595d6d35Jason W KimSTATISTIC(NonPCRelCount, "Total number of non-PIC relocations"); 1301953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1302953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1303953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCValue &Target, 1304953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCFragment &F, 1305e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1306e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1307953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 1308953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool EmitThisSym = false; 1309953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1310e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCSectionELF &Section = 1311e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim static_cast<const MCSectionELF&>(Symbol.getSection()); 1312e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool InNormalSection = true; 1313e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim unsigned RelocType = 0; 1314e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocType = GetRelocTypeInner(Target, Fixup, IsPCRel); 1315e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 13166dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay DEBUG( 13176dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay const MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 13186dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VariantKind Kind2; 13196dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay Kind2 = Target.getSymB() ? Target.getSymB()->getKind() : 13206dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay MCSymbolRefExpr::VK_None; 13216dcd413fbb488222200c6b42c4f5d55ce39db557Matt Beaumont-Gay dbgs() << "considering symbol " 1322e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Section.getSectionName() << "/" 1323e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.getName() << "/" 1324e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Rel:" << (unsigned)RelocType 1325e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Kind: " << (int)Kind << "/" << (int)Kind2 1326e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Tmp:" 1327e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isAbsolute() << "/" << Symbol.isDefined() << "/" 1328e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << Symbol.isVariable() << "/" << Symbol.isTemporary() 1329e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim << " Counts:" << PCRelCount << "/" << NonPCRelCount << "\n"); 1330e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1331bebd44a95a94189e79b02cd15edc2d41bc2628feJason W Kim if (IsPCRel) { ++PCRelCount; 1332e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1333e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: 1334e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // Most relocation types are emitted as explicit symbols 1335e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1336e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1337e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1338e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1339e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1340e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1341e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = true; 1342e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1343e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: 1344e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // But things get strange with R_ARM_ABS32 1345e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // In this case, most things that go in .rodata show up 1346e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim // as section relative relocations 1347e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1348e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1349e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1350e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1351e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1352e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1353e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1354e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim EmitThisSym = false; 1355e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim break; 1356e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1357953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } else { 1358e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim NonPCRelCount++; 1359e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim InNormalSection = 1360e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim StringSwitch<bool>(Section.getSectionName()) 1361e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel.ro.local", false) 1362e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".rodata", false) 1363e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".data.rel", false) 1364e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Case(".bss", false) 1365e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim .Default(true); 1366e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1367e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim switch (RelocType) { 1368e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim default: EmitThisSym = true; break; 1369e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim case ELF::R_ARM_ABS32: EmitThisSym = false; break; 1370e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1371953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } 1372e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1373953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (EmitThisSym) 1374953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1375e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim if (! Symbol.isTemporary() && InNormalSection) { 1376953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1377e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim } 1378953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return NULL; 1379953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim} 1380953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1381e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// Need to examine the Fixup when determining whether to 1382e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// emit the relocation as an explicit symbol or as a section relative 1383e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim// offset 138485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 138585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 138656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 138756a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 1388c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola int64_t Addend) const { 1389c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola return GetRelocTypeInner(Target, Fixup, IsPCRel); 1390e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim} 1391e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1392e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kimunsigned ARMELFObjectWriter::GetRelocTypeInner(const MCValue &Target, 1393e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 1394e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 1395e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 1396e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1397e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 1398a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 139985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 140085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 140185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 14023fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 14033fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14043fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 14053fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 1406e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim Type = ELF::R_ARM_REL32; 14071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14083fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14091d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "unimplemented"); 14101d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14113fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14123fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14131d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14141d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14151d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1416685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 14173fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 14183fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 14191d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_PLT32; 14201d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14213fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 14221d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 14231d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14241d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1426685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1427685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1428685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 142986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16: 143086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 14311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_PREL; 14321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 143386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16: 143486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: 14351d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_PREL_NC; 14361d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1437f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1438f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 1439f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_PREL; 1440f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1441f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1442f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 1443f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_PREL_NC; 1444f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1445298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_bl: 1446298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case ARM::fixup_arm_thumb_blx: 1447298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola switch (Modifier) { 1448298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola case MCSymbolRefExpr::VK_ARM_PLT: 1449298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_THM_CALL; 1450298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1451298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola default: 1452298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola Type = ELF::R_ARM_NONE; 1453298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 1454298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola } 1455298c8e12ea063f7522c59d2a297b47a879b6ed55Rafael Espindola break; 145685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 145785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 145885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 145985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1460a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1461a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 14623fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 14633fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 14641d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOT_BREL; 14651d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14663fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 14671d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_GD32; 14681d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1469f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 14701d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_LE32; 14711d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1472a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 14731d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_IE32; 14741d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1475f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 14761d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_ABS32; 14771d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14783fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 14791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOTOFF32; 14801d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 14811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 14821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1483dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 14849d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1485dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1486662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1487b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1488b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1489e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 14901d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "Unimplemented"); 14911d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1492685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 14931d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 14941d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1495685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1496685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1497685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 14981d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim case ARM::fixup_arm_movt_hi16: 14991d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_ABS; 15001d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 150185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 15021d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; 15031d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1504f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1505f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_ABS; 1506f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1507f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1508f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_ABS_NC; 1509f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 151085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 151285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1513a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 151485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 151585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 15162c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky//===- PPCELFObjectWriter -------------------------------------------===// 15172c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15182c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::PPCELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15192c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky raw_ostream &_OS, 15202c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsLittleEndian) 15212c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15222c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15232c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15242c0d69fad0e658117922f3d96d9b732bedf9fd47Roman DivackyPPCELFObjectWriter::~PPCELFObjectWriter() { 15252c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15262c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 15272c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divackyunsigned PPCELFObjectWriter::GetRelocType(const MCValue &Target, 15282c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky const MCFixup &Fixup, 15292c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsPCRel, 15302c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky bool IsRelocWithSymbol, 1531c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola int64_t Addend) const { 15322c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky // determine the type of the relocation 15332c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky unsigned Type; 15342c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky if (IsPCRel) { 15352c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15362c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: 15372c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky llvm_unreachable("Unimplemented"); 15382c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15392c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL24; 15402c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15412c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_PCRel_4: 15422c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_REL32; 15432c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15442c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15452c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } else { 15462c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky switch ((unsigned)Fixup.getKind()) { 15472c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky default: llvm_unreachable("invalid fixup kind!"); 15482c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_br24: 15492c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR24; 15502c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15512c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_brcond14: 15522c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14_BRTAKEN; // XXX: or BRNTAKEN?_ 15532c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15542c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_ha16: 15552c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_HA; 15562c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15572c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo16: 15582c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16_LO; 15592c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15602c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case PPC::fixup_ppc_lo14: 15612c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR14; 15622c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15632c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_4: 15642c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR32; 15652c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15662c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky case FK_Data_2: 15672c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky Type = ELF::R_PPC_ADDR16; 15682c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky break; 15692c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15702c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky } 15712c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky return Type; 15722c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky} 15732c0d69fad0e658117922f3d96d9b732bedf9fd47Roman Divacky 1574946227d64afcc8cb3f4db94b6ee0cdb1aa55fa31Jim Grosbachvoid PPCELFObjectWriter:: 1575946227d64afcc8cb3f4db94b6ee0cdb1aa55fa31Jim GrosbachadjustFixupOffset(const MCFixup &Fixup, uint64_t &RelocOffset) { 15762a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky switch ((unsigned)Fixup.getKind()) { 15772a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky case PPC::fixup_ppc_ha16: 15782a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky case PPC::fixup_ppc_lo16: 15792a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky RelocOffset += 2; 15802a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky break; 15812a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky default: 15822a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky break; 15832a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky } 15842a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky} 15852a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 15864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1587d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 158831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1589bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1590bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1591bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 15924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 15944b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 15954b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 159756a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 15984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 159956a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 160056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 1601c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola int64_t Addend) const { 16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 16044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 16074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1608e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 16094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 16104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1611e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 16134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 16164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 16184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 161956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 162056a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 162156a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 16224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 16244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 16254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16264b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 162856a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 16294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1630d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1631d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1632d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1633d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 163431f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1635bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1636bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1637bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1638d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1639d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1640d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1641d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1642d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 164356a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 164456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 164556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 164656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 1647c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola int64_t Addend) const { 1648d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 165012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 165112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1652d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1653bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1654d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 16553a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch ((unsigned)Fixup.getKind()) { 16563a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 1657debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 1658debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_8: Type = ELF::R_X86_64_PC64; break; 1659debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_4: Type = ELF::R_X86_64_PC32; break; 1660debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola case FK_Data_2: Type = ELF::R_X86_64_PC16; break; 1661debd7e4e8bc5cfe61bfb71835ce2b1a3fbccc2beRafael Espindola 16623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 16633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 16643a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC64; 1665d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16667a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola case X86::reloc_signed_4byte: 1667c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola case X86::reloc_riprel_4byte_movq_load: 16683a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case X86::reloc_riprel_4byte: 16693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_4: 16703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch (Modifier) { 16713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: 16723a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola llvm_unreachable("Unimplemented"); 16733a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_None: 16743a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC32; 16753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_PLT: 16773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PLT32; 16783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 16803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTPCREL; 16813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16823a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 16833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTTPOFF; 1684d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 16863a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSGD; 16873a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16883a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 16893a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSLD; 16903a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 16913a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola } 1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 16933a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_2: 16943a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 16953a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC16; 1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1697d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger case FK_PCRel_1: 1698d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger assert(Modifier == MCSymbolRefExpr::VK_None); 1699d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger Type = ELF::R_X86_64_PC8; 1700d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger break; 1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1708d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1731e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1735d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 17371d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola switch ((unsigned)Fixup.getKind()) { 17381d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 17391d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola 17401d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola case X86::reloc_global_offset_table: 17411d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola Type = ELF::R_386_GOTPC; 1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 17431d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola 17443c68acd202d061c38e9b7744012094b4009d932aRafael Espindola case X86::reloc_signed_4byte: 17451d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola case FK_PCRel_4: 17461d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola case FK_Data_4: 17471d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola switch (Modifier) { 17481d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola default: 17491d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola llvm_unreachable("Unimplemented"); 17501d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola case MCSymbolRefExpr::VK_None: 17511d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola Type = ELF::R_386_PC32; 17521d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola break; 17531d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola case MCSymbolRefExpr::VK_PLT: 17541d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola Type = ELF::R_386_PLT32; 17551d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola break; 17561d5969d839ddc4d0af93fd035aa13131e5c6fa82Rafael Espindola } 1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1765d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1770e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1773d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1774d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1782d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1783d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1784d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1785d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1786d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1787d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1788d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1789d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1790d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1791d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1792d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1793d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1794d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1795d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1796d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1797d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1798d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1799d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1800d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1801d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1802d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1803d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1804d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1805e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky case MCSymbolRefExpr::VK_GOTTPOFF: 1806e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky Type = ELF::R_386_TLS_IE_32; 1807e0b87032f5ac8134b7585bdc4a0f2c77158b962dNick Lewycky break; 1808d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1809d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1810d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1811e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1812d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1813d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1814d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1815d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1816d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 181756a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 18183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1819291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 1820a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes//===- MipsELFObjectWriter -------------------------------------------===// 1821a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes 1822291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::MipsELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1823291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka raw_ostream &_OS, 1824291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsLittleEndian) 1825291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka : ELFObjectWriter(MOTW, _OS, IsLittleEndian) {} 1826291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 1827291512f96fe807da7c1a3a6e001feb1017b56e26Akira HatanakaMipsELFObjectWriter::~MipsELFObjectWriter() {} 1828291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka 182984bfc2f090639f933df06cc675c4385511516befAkira Hatanaka// FIXME: get the real EABI Version from the Triple. 183084bfc2f090639f933df06cc675c4385511516befAkira Hatanakavoid MipsELFObjectWriter::WriteEFlags() { 183184bfc2f090639f933df06cc675c4385511516befAkira Hatanaka Write32(ELF::EF_MIPS_NOREORDER | 183284bfc2f090639f933df06cc675c4385511516befAkira Hatanaka ELF::EF_MIPS_ARCH_32R2); 183384bfc2f090639f933df06cc675c4385511516befAkira Hatanaka} 183484bfc2f090639f933df06cc675c4385511516befAkira Hatanaka 1835a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopesconst MCSymbol *MipsELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1836a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes const MCValue &Target, 1837a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes const MCFragment &F, 1838a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes const MCFixup &Fixup, 1839a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes bool IsPCRel) const { 1840a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes assert(Target.getSymA() && "SymA cannot be 0."); 1841a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes const MCSymbol &Sym = Target.getSymA()->getSymbol(); 1842a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes 1843f3315cf65f9574cd1e4e784d2860c943cfa65ce9Akira Hatanaka if (Sym.getSection().getKind().isMergeableCString() || 1844f3315cf65f9574cd1e4e784d2860c943cfa65ce9Akira Hatanaka Sym.getSection().getKind().isMergeableConst()) 1845a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes return &Sym; 1846a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes 1847a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes return NULL; 1848a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes} 1849a00a62acd02a94aabecc94ac551d8bb305ed7265Bruno Cardoso Lopes 1850291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanakaunsigned MipsELFObjectWriter::GetRelocType(const MCValue &Target, 1851291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka const MCFixup &Fixup, 1852291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsPCRel, 1853291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka bool IsRelocWithSymbol, 1854c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola int64_t Addend) const { 1855a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes // determine the type of the relocation 1856a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes unsigned Type = (unsigned)ELF::R_MIPS_NONE; 1857a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes unsigned Kind = (unsigned)Fixup.getKind(); 1858a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes 1859a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes switch (Kind) { 1860a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes default: 1861a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes llvm_unreachable("invalid fixup kind!"); 1862a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case FK_Data_4: 1863a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_32; 1864a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 186584bfc2f090639f933df06cc675c4385511516befAkira Hatanaka case FK_GPRel_4: 186684bfc2f090639f933df06cc675c4385511516befAkira Hatanaka Type = ELF::R_MIPS_GPREL32; 186784bfc2f090639f933df06cc675c4385511516befAkira Hatanaka break; 1868a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_GPREL16: 1869a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_GPREL16; 1870a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1871a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_26: 1872a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_26; 1873a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1874a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_CALL16: 1875a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_CALL16; 1876a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1877e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes case Mips::fixup_Mips_GOT_Global: 1878e3d3572e282733bd7aa5ac14115ed0804174e426Bruno Cardoso Lopes case Mips::fixup_Mips_GOT_Local: 1879a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_GOT16; 1880a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1881a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_HI16: 1882a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_HI16; 1883a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1884a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_LO16: 1885a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_LO16; 1886a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1887a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_TLSGD: 1888a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_TLS_GD; 1889a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1890a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_GOTTPREL: 1891a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_TLS_GOTTPREL; 1892a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1893a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_TPREL_HI: 1894a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_TLS_TPREL_HI16; 1895a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1896a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_TPREL_LO: 1897a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_TLS_TPREL_LO16; 1898a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1899a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_Branch_PCRel: 1900a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes case Mips::fixup_Mips_PC16: 1901a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes Type = ELF::R_MIPS_PC16; 1902a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes break; 1903a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes } 1904a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes 1905a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes return Type; 1906291512f96fe807da7c1a3a6e001feb1017b56e26Akira Hatanaka} 1907