ELFObjectWriter.cpp revision 7c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9
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" 183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h" 193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h" 203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h" 213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h" 223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h" 233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h" 243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h" 253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h" 263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h" 27953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim#include "llvm/ADT/StringSwitch.h" 283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "../Target/X86/X86FixupKinds.h" 304a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim#include "../Target/ARM/ARMFixupKinds.h" 313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 333565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 352ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 362ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 372ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 382ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 62d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 63d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 64d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 66115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 67115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 81bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 84115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 875baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 88bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (TargetObjectWriter->getOSType()) { 895baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; 905baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; 915baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky default: Write8(ELF::ELFOSABI_NONE); break; 925baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky } 933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 99bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 1003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 104bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 105eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1072d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 1082d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim WriteEFlags(); 1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 111bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 117bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 1183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 1207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 1217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(0); 1227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 1267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 1277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 1287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 1297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 1303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 132115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 133115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 134115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 135115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 136115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 137115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 138115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 1397be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 1407be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 141af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 1427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 143af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 1447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 1457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 146af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 147af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 149bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 150af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 151af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 152af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 153af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 154af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 155af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 1563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 157af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 158af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 159af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 160af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 161af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 162af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 1643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 1672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 1682c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 1692c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 1702c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1712c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 172d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 173d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 174d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 175d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 176d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 177d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky return (uint64_t)IntValue; 178d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 179d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 180d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 1812c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 1822c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 1832c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 184ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola if (Data.getFragment()) 185ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola return Layout.getSymbolOffset(&Data); 1862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 1872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 1882c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 1892c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 19085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 19185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 19288182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 19388182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 19488182132470527e27231f09b25a885893e528c66Rafael Espindola 19588182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 19688182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 19788182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 19894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 199f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 200f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 201f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 202f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 203f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 204f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 20507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 20688182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 20788182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 20888182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 20988182132470527e27231f09b25a885893e528c66Rafael Espindola 210f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 211f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 212f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 2132ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 214f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 21507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 21688182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 21788182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 21888182132470527e27231f09b25a885893e528c66Rafael Espindola 21983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 22083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 22183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 22283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 22383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 22407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 22588182132470527e27231f09b25a885893e528c66Rafael Espindola } 22688182132470527e27231f09b25a885893e528c66Rafael Espindola} 22788182132470527e27231f09b25a885893e528c66Rafael Espindola 228115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 229115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 230115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 231115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 232de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 233de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 23494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 235152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 2377be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 2387be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 2392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 2402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Visibility = MCELF::GetVisibility(OrigData); 2412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 242152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 243152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 244152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 245152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 2462c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 2473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 2483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 249f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 250f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 251f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 252f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 253f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 254f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 255f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 256f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 2573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 2607be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 2617be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 2623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 2633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 264115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 265115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 266115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 267115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 2684beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap) { 2693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 2703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 2713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 2723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 2743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 2767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 2773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 2793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 2803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 2813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 2827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 2833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 28571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 2864beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 2874beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 288a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 2894beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 2904beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 2914beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 2924beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 2934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_SYMTAB) 294a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 2957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 2964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); 297a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 298a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 2993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 3013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3033223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 3043223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 3053223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 3067be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3072ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 3147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 3152ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3201f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 3211f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 3221f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCFragment &F) const { 3231f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 32494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 32594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 32694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 32794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 32894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 32994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 33094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 33194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 3321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 3331f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 33494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 33594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 33694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 33794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 33894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3397eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 3407eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 34194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 34225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 3437eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 34425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 345953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return ExplicitRelSym(Asm, Target, F, true); 3467eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 34725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 34825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 34925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 35025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 35125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 35225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 3538cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 3543729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 3553729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 3563729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3578cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 358c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 359c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 36025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 36194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 36294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 36394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 36494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 3653729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 3661c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 36794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 36894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return NULL; 36994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 37094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 37194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 3721f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 373c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 374953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return ExplicitRelSym(Asm, Target, F, false); 37573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 37673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 37856a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 37956a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 38056a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 38156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 38256a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 38356a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 38456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 38556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 38656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 38756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 38856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 389127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 39056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 39156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 39256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 39356a399023aba6cf1348533df04732950c43eaca7Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment); 39456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 39556a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 39656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 39756a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 39856a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 39956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 40356a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Ofeset of the relocation in the section 40456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 40556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 40656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 40756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 40856a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 40956a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 41056a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 41156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 41356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 41756a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 41856a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 41956a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 42056a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 42156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 42256a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 42356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 42456a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 425bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 42656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 42756a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 42856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 42956a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 43056a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 43156a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 4322ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 43356a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 43456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 43556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 436bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 437bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 43856a399023aba6cf1348533df04732950c43eaca7Jason W Kim ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); 43956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 44056a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 44156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 44256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 4430b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 444115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 445115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 4467b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 447ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 4483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 4512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 4522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 453484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 454484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 455484291c27319668ad99cb87def000254357736fbRafael Espindola 456bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 457bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 458bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 45988182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 46088182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 46188182132470527e27231f09b25a885893e528c66Rafael Espindola 462737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 463a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 464d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 465d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 466d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 46794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 46821451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 46921451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 47021451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 4712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 47221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 473a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 474a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 475737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 476737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 477737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 478bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 479737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 480737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 481737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 482737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 483737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 4842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 4852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 486737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 487737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 488737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 489737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 49094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 4911f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 4921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 4931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 4941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 4951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 496737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 4971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 498737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 499737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 500737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 501737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 502115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 5037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 5047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 505bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 506bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 507bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 508bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 509bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 5112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 5122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 5132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 5142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 5152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 5162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 5172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 5182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 5197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 5207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 5217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 5222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 523bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 5247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 5257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 5267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 527bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 528bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 529bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 530115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 5311f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 5327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 5337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 5345c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 5355c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 5365c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 5375c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 5385c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 5395c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 5402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 5415c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 5425c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 5433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 5443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 5453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 5463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 547a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 5483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 5493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 5503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 5513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 552484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 553484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 5541f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 5551f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5561f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 5571f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 55888182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 5593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 5603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 56394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5651f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 5661f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 5671f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 5682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 5691f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 5702ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 5712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 5721f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 5731f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 574484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 5752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 576484291c27319668ad99cb87def000254357736fbRafael Espindola 577f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 578a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 579f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 580bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 581a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 58288182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 5831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 5841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 5851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 5861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 588bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 589bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 590bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 5917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 5927be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 5933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 5945df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 5955df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 59688182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 59788182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 59888182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 5991261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 6001261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 60188182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 60288182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 6031261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 6041261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 6051261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 6061261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 60788182132470527e27231f09b25a885893e528c66Rafael Espindola } 60888182132470527e27231f09b25a885893e528c66Rafael Espindola 6091261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 610a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 611a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 6121261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 613a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 6143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 615a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 616a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 617a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 618a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 619a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 620a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 621a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 631ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 634ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 635ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 636ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 6373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 6393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 6447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 6457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 6467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 6507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 6533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 6543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 657bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 659299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 660299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 661bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 662bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 663299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 664bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 6653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 6677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 6687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 6697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 6707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 6717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 6727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 6737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 6747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 6757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 6833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 6857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 6867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 688bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 6917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 6923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 695115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 696115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 697115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 698115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 699115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 700115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 7013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 7023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 7033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 7043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 7053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 7063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 7073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 7083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 7093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 7103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 7113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 713115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 714115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 715115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 7163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 7173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 7183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 7193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 7213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 7223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 72312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 72412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 72512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 7268f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 7278f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 72812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 729bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 730af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 7315e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7328f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 7338f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 734af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 7355e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 736bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 737af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 7385e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 739af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 7405e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7418f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 7428f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 743af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 7445e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 745bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 746af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 7475e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 7483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 751115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 752115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 7537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 7547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 7553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 7563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 7573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 758bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 7593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 76038738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 7614283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 7627be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 7633f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 76471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 76571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 76671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 7674283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 7687be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 7697be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 7702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 7713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 772bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 7737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 7747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 7757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 7767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 7774283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 7787be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 7792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 7807be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 7817be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 7827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 7833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 7853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 7863f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 7873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 7883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 7893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 7917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 7927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 7937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 7947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 79571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 79671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 79771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 7987be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 7997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8007be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 8017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8024beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 80371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 8053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 8103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 8113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 8123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 8133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 8143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringMap<uint64_t> SecStringMap; 8173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::const_iterator it = Asm.begin(), 8183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.end(); it != ie; ++it) { 8193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 820368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer static_cast<const MCSectionELF&>(it->getSection()); 82151efe7a253190b672519e8388ce5d45f1dcf1a24Rafael Espindola // FIXME: We could merge suffixes like in .text and .rela.text. 8223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 8242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (SecStringMap.count(Name)) { 8252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = SecStringMap[Name]; 8262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 8293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 8302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 8312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SecStringMap[Name] = Index; 8323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 8342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 8353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8377070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 8387070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 83996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 84096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 84196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 8427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 84596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 84696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 84796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 84896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 84996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 85096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 85196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 85296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 85396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 8542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 8552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 8562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 8572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 8591c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 8602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 8632ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 8641f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 8652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 86696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 8672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 8682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 8692ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 8702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 8712ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8722ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 8732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8742ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 8767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 8772ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 8782ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 8797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 8802ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8812ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 8821c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 8832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 8852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 8872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 8887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 8897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 8902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 8922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 893115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 894115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 895115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 896115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 897115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 898115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 899c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 900c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 901c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 902c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 903c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 904c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 905c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 906c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 907c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 908c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 909c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 910c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 911c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 912c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 913c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 9143f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 915c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 916c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 917c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 918c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 919c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 920c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 921c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 922c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 923c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 9243f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 925c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 926c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 927c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 928c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 929c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 930c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 931c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 932c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 933c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 934c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 935c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 936c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 937c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 938c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 939c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 940c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 941c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 94298976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 943c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 944c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 94586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 94686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 94786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 9480cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 949c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 950c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 951c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 9522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola case ELF::SHT_GROUP: { 9532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 9542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 9552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 9562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 9682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 969f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 9706db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 9716db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 9726db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 9732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 9746db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 9756db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 9766db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 9776db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 9786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 9796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 9806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 9816db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 9826db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 9836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 9842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 9852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 9866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 9876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 9886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 9896db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 9906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 9912ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 9922ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 9936db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 9946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 99585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 9966db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 9976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 9987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 9997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 10017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FileOff = OS.tell(); 10027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 10057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 10067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += Padding; 10077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += GetSectionFileSize(Layout, SD); 10097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 10117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 10147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 10167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.WriteSectionData(&SD, Layout); 10197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 10247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 10267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 10277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 10287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 10307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 10317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 10337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 10347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 10357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 10367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 10397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 10407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 10417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 10427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 10437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 10447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 10467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 10477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 10497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 10507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 10517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 10527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 10537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 10547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 10906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 10916db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10926db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1093115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1094115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 10952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 10961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1097bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1098bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1111bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11128f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11178f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 11183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 11194beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 11207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 11217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 11221d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1123bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1124bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1125bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1126a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 11273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 11332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1136a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1137a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 11397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 11407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 11426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1145a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1146a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 11483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 11507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 11517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 11523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 11542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1156a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1158a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 11602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 116144cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 11627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 11636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 11707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 11717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 11727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 11737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 1175a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1176a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1177a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 11797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 11807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 11836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 11847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... and then the remainting sections ... 11857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 11867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 11883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 118978c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 119078c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 119178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 119278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 119378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 119478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 119578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 119678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 119778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 119878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 119978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 120078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 12016024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 12026024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1203bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 1204bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (MOTW->getEMachine()) { 1205d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1206d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1207bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1208d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1209bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 1211bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12123285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1213d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1214d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1215d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1216d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1217d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1218d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1219d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 122031f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1221bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1222bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1223bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1224d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1225d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1226d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1227d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1228d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 12292d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple. 12302d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() { 12312d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion); 12322d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim} 12332d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim 1234953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly. 1235953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol. 1236953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// This code is a first-cut approximation of what ARM/gcc does. 1237953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1238953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1239953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCValue &Target, 1240953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCFragment &F, 1241953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool IsBSS) const { 1242953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 1243953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool EmitThisSym = false; 1244953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1245953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (IsBSS) { 1246953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim EmitThisSym = StringSwitch<bool>(Symbol.getName()) 1247953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Case("_MergedGlobals", true) 1248953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Default(false); 1249953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } else { 1250953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim EmitThisSym = StringSwitch<bool>(Symbol.getName()) 1251953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Case("_MergedGlobals", true) 1252953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .StartsWith(".L.str", true) 1253953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Default(false); 1254953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } 1255953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (EmitThisSym) 1256953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1257953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (! Symbol.isTemporary()) 1258953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1259953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return NULL; 1260953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim} 1261953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 126285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 126385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 126456a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 126556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 126656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 126785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 126885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 126985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1270a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 127185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 127285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 127385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 12743fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 12753fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 12763fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 12773fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 12781d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_BASE_PREL; 12791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 12803fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 12811d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "unimplemented"); 12821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 12833fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 12843fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 12851d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 12861d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 12871d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1288685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 12893fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 12903fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 12911d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_PLT32; 12921d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 12933fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 12941d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 12951d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 12961d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 12971d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1298685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1299685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1300685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 130186a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16: 130286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 13031d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_PREL; 13041d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 130586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16: 130686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: 13071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_PREL_NC; 13081d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1309f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1310f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 1311f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_PREL; 1312f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1313f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1314f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 1315f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_PREL_NC; 1316f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 131785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 131885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 131985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 132085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1321a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1322a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 13233fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 13243fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 13251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOT_BREL; 13261d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13273fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 13281d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_GD32; 13291d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1330f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 13311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_LE32; 13321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1333a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 13341d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_IE32; 13351d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1336f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 13371d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_ABS32; 13381d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13393fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 13401d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOTOFF32; 13411d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13421d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 13431d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1344dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 13459d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1346dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1347662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1348b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1349b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1350e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 13511d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "Unimplemented"); 13521d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1353685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 13541d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 13551d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1356685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1357685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1358685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 13591d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim case ARM::fixup_arm_movt_hi16: 13601d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_ABS; 13611d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 136285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 13631d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; 13641d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1365f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1366f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_ABS; 1367f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1368f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1369f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_ABS_NC; 1370f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 137185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 137285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 137385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 137485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (RelocNeedsGOT(Modifier)) 137585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim NeedsGOT = true; 1376953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1377a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 137885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 137985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 13804b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1381d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 138231f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1383bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1384bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1385bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 13864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 13874b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 13884b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 13894b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 13904b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 139156a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 13924b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 139356a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 139456a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 139556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 13964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 13974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 13984b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 13994b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 14004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 14014b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1402e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 14034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 14044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1405e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 14064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 14074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 14094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 14104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 14114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 14124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 141356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 141456a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 141556a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 14164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 14184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 14194b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 14214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 142256a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 14234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1424d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1425d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1426d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1427d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 142831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1429bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1430bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1431bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1432d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1433d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1434d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1435d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1436d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 143756a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 143856a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 143956a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 144056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 144156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 1442d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1443d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 144412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 144512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1446d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1447bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1448d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 14493a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch ((unsigned)Fixup.getKind()) { 14503a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 14513a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 14523a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 14533a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC64; 1454d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 14557a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola case X86::reloc_signed_4byte: 1456c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola case X86::reloc_riprel_4byte_movq_load: 14573a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_Data_4: // FIXME? 14583a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case X86::reloc_riprel_4byte: 14593a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_4: 14603a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch (Modifier) { 14613a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: 14623a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola llvm_unreachable("Unimplemented"); 14633a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_None: 14643a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC32; 14653a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14663a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_PLT: 14673a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PLT32; 14683a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14693a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 14703a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTPCREL; 14713a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14723a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 14733a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTTPOFF; 1474d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 14753a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 14763a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSGD; 14773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 14793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSLD; 14803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola } 1482d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 14833a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_2: 14843a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 14853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC16; 1486d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1487d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger case FK_PCRel_1: 1488d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger assert(Modifier == MCSymbolRefExpr::VK_None); 1489d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger Type = ELF::R_X86_64_PC8; 1490d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger break; 1491d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1492d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1493d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1494d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1495d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1496d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1497d3443e99e43945fdb0742177da06a32fa225740dJason W Kim assert(isInt<32>(Target.getConstant())); 1498d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1499d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1500d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1501d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1502d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1503d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1504d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1505d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1506d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1507d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1508d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1509d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1510d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1511d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1512d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1513d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1514d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1515d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1516d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1517d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1518d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1519d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1520d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1521d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1522e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1523d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1524d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1525d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1526d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1527d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1528d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1529d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1530d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1531d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1532d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PC32; 1533d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1534d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1535d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PLT32; 1536d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1537d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1538d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1539d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1540d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1541d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1542d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1543d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1544d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1545d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1546d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1547d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1548d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1549e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1550d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1551d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1552d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1553d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1554d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1555d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1556d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1557d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1558d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1559d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1560d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1561d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1562d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1563d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1564d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1565d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1566d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1567d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1568d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1569d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1570d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1571d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1572d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1573d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1574d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1575d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1576d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1577d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1578d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1579d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1580d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1581d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1582d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1583d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1584d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1585d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1586d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1587e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1588d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1589d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1590d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1591d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1592d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1593d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (RelocNeedsGOT(Modifier)) 1594d3443e99e43945fdb0742177da06a32fa225740dJason W Kim NeedsGOT = true; 1595d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 159656a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 15973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1598