ELFObjectWriter.cpp revision d5321da8d22d60f528397a05dc10db4185fcb680
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 547d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 548d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 549d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 550a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 5513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 5523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 5533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 5543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 555484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 556484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 5571f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 5581f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 5591f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 5601f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 56188182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 5633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 5653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 56694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 5673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5681f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 5691f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 5701f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 5712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 5721f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 5732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 5742ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 5751f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 5761f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 577484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 5782ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 579484291c27319668ad99cb87def000254357736fbRafael Espindola 580f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 581a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 582f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 583bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 584a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 58588182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 5861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 5871f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 5881f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 5891f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 591bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 592bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 593bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 5947be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 5957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 5963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 5975df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 5985df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 59988182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 60088182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 60188182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 6021261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 6031261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 60488182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 60588182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 6061261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 6071261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 6081261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 6091261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 61088182132470527e27231f09b25a885893e528c66Rafael Espindola } 61188182132470527e27231f09b25a885893e528c66Rafael Espindola 6121261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 613a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 614a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 6151261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 616a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 618a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 619a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 620a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 621a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 622a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 623a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 624a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 6313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 634ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 6353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 6363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 637ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 638ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 639ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 6403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 6423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 6433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 6443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 6477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 6487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 6497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 6537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 6563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 6573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 6583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 660bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 6613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 662299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 663299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 664bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 665bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 666299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 667bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 6707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 6717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 6727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 6737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 6747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 6757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 6767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 6777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 6787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 6797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 6807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 6817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 6827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 6837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 6847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 6857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 6863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 6887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 6897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 6903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 691bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 6923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 6947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 6953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 698115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 699115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 700115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 701115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 702115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 703115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 7043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 7053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 7063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 7073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 7083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 7093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 7103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 7113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 7123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 7133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 7143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 716115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 717115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 718115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 7193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 7203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 7213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 7223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 7243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 7253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 72612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 72712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 72812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 7298f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 7308f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 73112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 732bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 733af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 7345e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7358f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 7368f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 737af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 7385e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 739bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 740af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 7415e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 742af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 7435e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 7448f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 7458f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 746af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 7475e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 748bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 749af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 7505e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 7513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 7523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 754d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 755d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 756d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 757d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 758d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 759d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 760d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 761d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 762d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 763d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 764d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 765d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 766d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 767d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 768d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 769d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 770d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 771d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 772115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 773115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 7747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 7757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 7763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 7773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 7783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 779bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 7803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 78138738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 7824283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 7837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 7843f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 78571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 78671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 78771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 7884283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 7897be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 7907be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 7912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 7923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 793bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 7947be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 7957be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 7967be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 7977be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 7984283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 7997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 8002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 8017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 8027be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 8037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 8063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 8073f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 8093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 8103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 8127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 8137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 8147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 8157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 81671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 81771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 81871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 8197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 8207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 8217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 8227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 8234beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 82471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 8253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 8263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 8273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 8293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 830d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 831d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 832d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 833d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 834d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 835d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 836d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 837d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 838d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 8393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 8403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 8413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 8423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 8433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 8443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 846d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 847d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 8483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 850d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 851d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 852d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 853d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 854d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 855d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 8562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 8583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 8592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 8603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 8622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 8633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 8643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8657070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 8667070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 86796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 86896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 86996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 8707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 8717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 87396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 87496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 87596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 87696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 87796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 87896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 87996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 88096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 88196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 8822ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 8832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 8842ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 8852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 8871c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 8882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 8912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 8921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 8932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 89496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 8952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 8962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 8972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 8982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 8992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 9012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 9037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 9047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9052ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 9062ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 9077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 9082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 9092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 9101c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 9112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 9121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 9132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 9142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 9152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 9167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 9177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 9182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 9202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 921115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 922115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 923115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 924115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 925115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 926115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 927c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 928c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 929c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 930c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 931c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 932c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 933c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 934c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 935c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 936c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 937c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 938c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 939c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 940c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 941c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 9423f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 943c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 944c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 945c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 946c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 947c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 948c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 949c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 950c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 951c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 9523f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 953c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 954c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 955c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 956c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 957c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 958c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 959c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 960c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 961c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 962c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 963c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 964c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 965c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 966c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 967c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 968c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 969c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 97098976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 971c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 972c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 97386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 97486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 97586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 9760cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 977c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 978c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 979c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 9802ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola case ELF::SHT_GROUP: { 9812ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 9822ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 9832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 9842ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 9852ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 986c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 987c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 988c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 989c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 990c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 991c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 992c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 993c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 994c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 995c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 9962ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 997f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 9986db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 9996db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10006db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10012ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 10026db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 10036db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10046db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 10056db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 10066db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10076db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 10086db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 10096db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 10106db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10116db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10122ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 10132ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10146db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10156db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 10166db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 10176db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10186db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10192ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 10202ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 10216db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 10226db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 102385f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 10246db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 10256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 10267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 10277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 10297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FileOff = OS.tell(); 10307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 10337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 10347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += Padding; 10357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += GetSectionFileSize(Layout, SD); 10377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 10397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 10407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 10417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 10427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 10437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 10447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 10467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.WriteSectionData(&SD, Layout); 10477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 10517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 10527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 10537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 10547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 10557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 10567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 10587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 10597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 10617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 10627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 10637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 10647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 10677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 10687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 10697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 10707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 10717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 10727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 10747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 10757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 10767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 10777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 10787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 10797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 10807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 10817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 10827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 10847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 10867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 10877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 10887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 10927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 10937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 10947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 10977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 10987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 10997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 11067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 11077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 11087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 11107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 11127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 11157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 11167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 11177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 11186db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 11196db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 11206db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1121115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1122115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 11232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 11241f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1125bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1126bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 11307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 11337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 11347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 11367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 11377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1139bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11408f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 11427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 11458f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 11463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 11474beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 11487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 11497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 11501d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1151bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1152bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1153bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1154a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 11553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 11577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 11607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 11612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 11633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1164a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1165a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 11706db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1173a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1174a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 11763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 11787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 11797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 11803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 11822ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 11832ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1184a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1186a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 118944cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 11907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 11916db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 11923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 11957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 11967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 11987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 11997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 12007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 1203a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1204a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1205a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 12077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 12087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 12093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = OS.tell(); 12116db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 12127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... and then the remainting sections ... 12137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 12147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 12153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 12163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 121778c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 121878c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 121978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 122078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 122178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 122278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 122378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 122478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 122578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 122678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 122778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 122878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 12296024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 12306024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1231bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 1232bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola switch (MOTW->getEMachine()) { 1233d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1234d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1235bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new X86ELFObjectWriter(MOTW, OS, IsLittleEndian); break; 1236d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1237bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new ARMELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12384b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 1239bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola return new MBlazeELFObjectWriter(MOTW, OS, IsLittleEndian); break; 12403285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1241d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1242d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1243d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1244d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1245d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1246d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1247d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 124831f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaARMELFObjectWriter::ARMELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1249bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1250bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1251bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1252d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1253d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1254d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1255d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1256d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 12572d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim// FIXME: get the real EABI Version from the Triple. 12582d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kimvoid ARMELFObjectWriter::WriteEFlags() { 12592d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim Write32(ELF::EF_ARM_EABIMASK & DefaultEABIVersion); 12602d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim} 12612d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim 1262953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// In ARM, _MergedGlobals and other most symbols get emitted directly. 1263953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// I.e. not as an offset to a section symbol. 1264953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim// This code is a first-cut approximation of what ARM/gcc does. 1265953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1266953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kimconst MCSymbol *ARMELFObjectWriter::ExplicitRelSym(const MCAssembler &Asm, 1267953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCValue &Target, 1268953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCFragment &F, 1269953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool IsBSS) const { 1270953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 1271953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim bool EmitThisSym = false; 1272953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1273953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (IsBSS) { 1274953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim EmitThisSym = StringSwitch<bool>(Symbol.getName()) 1275953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Case("_MergedGlobals", true) 1276953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Default(false); 1277953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } else { 1278953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim EmitThisSym = StringSwitch<bool>(Symbol.getName()) 1279953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Case("_MergedGlobals", true) 1280953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .StartsWith(".L.str", true) 1281953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim .Default(false); 1282953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim } 1283953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (EmitThisSym) 1284953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1285953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim if (! Symbol.isTemporary()) 1286953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return &Symbol; 1287953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim return NULL; 1288953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim} 1289953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 129085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 129185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 129256a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 129356a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 129456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 129585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 129685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 129785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1298a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 129985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 130085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 130185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 13023fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 13033fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 13043fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 13053fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 13061d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_BASE_PREL; 13071d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13083fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 13091d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "unimplemented"); 13101d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13113fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 13123fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 13131d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13141d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 13151d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1316685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 13173fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 13183fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 13191d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_PLT32; 13201d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13213fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 13221d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 13231d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13241d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 13251d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1326685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1327685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1328685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 132986a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16: 133086a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movt_hi16_pcrel: 13311d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_PREL; 13321d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 133386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16: 133486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ARM::fixup_arm_movw_lo16_pcrel: 13351d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_PREL_NC; 13361d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1337f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1338f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16_pcrel: 1339f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_PREL; 1340f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1341f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1342f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16_pcrel: 1343f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_PREL_NC; 1344f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 134585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 134685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 134785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 134885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1349a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1350a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 13513fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 13523fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 13531d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOT_BREL; 13541d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13553fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 13561d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_GD32; 13571d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1358f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 13591d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_LE32; 13601d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1361a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 13621d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_TLS_IE32; 13631d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1364f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 13651d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_ABS32; 13661d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13673fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 13681d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_GOTOFF32; 13691d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 13701d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim } 13711d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1372dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 13739d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1374dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1375662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1376b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1377b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1378e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 13791d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim assert(0 && "Unimplemented"); 13801d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1381685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_uncondbranch: 13821d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_CALL; 13831d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1384685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim case ARM::fixup_arm_condbranch: 1385685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim Type = ELF::R_ARM_JUMP24; 1386685c350ae76b588e1f00c01a511fe8bd57f18394Jason W Kim break; 13871d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim case ARM::fixup_arm_movt_hi16: 13881d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVT_ABS; 13891d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 139085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 13911d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; 13921d8661744b3ad300ee483cf83be179e93cbd1245Jason W Kim break; 1393f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movt_hi16: 1394f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVT_ABS; 1395f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 1396f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng case ARM::fixup_t2_movw_lo16: 1397f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng Type = ELF::R_ARM_THM_MOVW_ABS_NC; 1398f3eb3bba1614a7935b44fc963a805088d71267f3Evan Cheng break; 139985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 140085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 140185fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 140285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (RelocNeedsGOT(Modifier)) 140385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim NeedsGOT = true; 1404953a2a3dee46bebd70b129fd62709710f5f2b033Jason W Kim 1405a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 140685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 140785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 14084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1409d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 141031f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaMBlazeELFObjectWriter::MBlazeELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1411bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1412bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1413bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) { 14144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 14154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 14164b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 14174b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 14184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 141956a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 14204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 142156a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 142256a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 142356a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 14244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 14254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 14264b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 14274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 14284b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 14294b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1430e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 14314b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 14324b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1433e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 14344b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 14354b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14364b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 14374b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 14384b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 14394b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 14404b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 144156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 144256a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 144356a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 14444b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14454b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 14464b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 14474b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 14484b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 14494b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 145056a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 14514b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1452d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1453d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1454d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1455d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 145631f3578b00a2ea85fb730b690f0478529103c748Rafael EspindolaX86ELFObjectWriter::X86ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1457bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola raw_ostream &_OS, 1458bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) 1459bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola : ELFObjectWriter(MOTW, _OS, IsLittleEndian) 1460d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1461d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1462d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1463d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1464d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 146556a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 146656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 146756a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 146856a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 146956a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 1470d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1471d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 147212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 147312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1474d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1475bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1476d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 14773a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch ((unsigned)Fixup.getKind()) { 14783a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: llvm_unreachable("invalid fixup kind!"); 14793a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_8: 14803a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 14813a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC64; 1482d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 14837a54997d670d92f7f0ece87911800aa68fcb8c6dRafael Espindola case X86::reloc_signed_4byte: 1484c3a561cb8ed6f04e3cf7b1ff38c9f51a695d196dRafael Espindola case X86::reloc_riprel_4byte_movq_load: 14853a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_Data_4: // FIXME? 14863a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case X86::reloc_riprel_4byte: 14873a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_4: 14883a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola switch (Modifier) { 14893a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola default: 14903a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola llvm_unreachable("Unimplemented"); 14913a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_None: 14923a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC32; 14933a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14943a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_PLT: 14953a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PLT32; 14963a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 14973a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 14983a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTPCREL; 14993a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 15003a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 15013a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_GOTTPOFF; 1502d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 15033a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 15043a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSGD; 15053a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 15063a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 15073a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_TLSLD; 15083a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola break; 15093a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola } 1510d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 15113a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola case FK_PCRel_2: 15123a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola assert(Modifier == MCSymbolRefExpr::VK_None); 15133a83c40ab61d5ca624f2bbadd70237c6adbdb304Rafael Espindola Type = ELF::R_X86_64_PC16; 1514d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1515d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger case FK_PCRel_1: 1516d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger assert(Modifier == MCSymbolRefExpr::VK_None); 1517d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger Type = ELF::R_X86_64_PC8; 1518d45e8bf93b2024213e423b7b40272da6636e78f7Joerg Sonnenberger break; 1519d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1520d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1521d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1522d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1523d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1524d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1525d3443e99e43945fdb0742177da06a32fa225740dJason W Kim assert(isInt<32>(Target.getConstant())); 1526d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1527d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1528d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1529d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1530d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1531d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1532d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1533d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1534d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1535d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1536d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1537d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1538d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1539d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1540d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1541d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1542d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1543d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1544d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1545d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1546d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1547d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1548d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1549d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1550e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1551d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1552d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1553d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1554d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1555d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1556d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1557d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1558d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1559d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1560d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PC32; 1561d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1562d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1563d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PLT32; 1564d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1565d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1566d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1567d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1568d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1569d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1570d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1571d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1572d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1573d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1574d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1575d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1576d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1577e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1578d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1579d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1580d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1581d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1582d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1583d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1584d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1585d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1586d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1587d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1588d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1589d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1590d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1591d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1592d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1593d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1594d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1595d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1596d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1597d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1598d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1599d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1600d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1601d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1602d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1603d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1604d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1605d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1606d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1607d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1608d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1609d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1610d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1611d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1612d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1613d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1614d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1615e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1616d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1617d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1618d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1619d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1620d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1621d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (RelocNeedsGOT(Modifier)) 1622d3443e99e43945fdb0742177da06a32fa225740dJason W Kim NeedsGOT = true; 1623d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 162456a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 16253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1626