ELFObjectWriter.cpp revision 6024c97ffa15766bc0f200ffd309d9e017ae0d4b
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 148f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola#include "llvm/ADT/SmallPtrSet.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/MCAssembler.h" 193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h" 203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h" 213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCELFSymbolFlags.h" 223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h" 23285b3e5b61af15f11e59a7700375aefa2a326bd8Rafael Espindola#include "llvm/MC/MCELFObjectWriter.h" 243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCObjectWriter.h" 253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h" 263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSymbol.h" 273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h" 283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h" 293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h" 303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h" 313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Target/TargetAsmBackend.h" 323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "../Target/X86/X86FixupKinds.h" 344a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim#include "../Target/ARM/ARMFixupKinds.h" 353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 373565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 39ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindolastatic unsigned GetType(const MCSymbolData &SD) { 40ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola uint32_t Type = (SD.getFlags() & (0xf << ELF_STT_Shift)) >> ELF_STT_Shift; 41ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola assert(Type == ELF::STT_NOTYPE || Type == ELF::STT_OBJECT || 42ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola Type == ELF::STT_FUNC || Type == ELF::STT_SECTION || 43ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola Type == ELF::STT_FILE || Type == ELF::STT_COMMON || 44ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola Type == ELF::STT_TLS); 45ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola return Type; 46ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola} 47ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola 48e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic unsigned GetBinding(const MCSymbolData &SD) { 49e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola uint32_t Binding = (SD.getFlags() & (0xf << ELF_STB_Shift)) >> ELF_STB_Shift; 50e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 51e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola Binding == ELF::STB_WEAK); 52e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola return Binding; 53e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola} 54e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola 55e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindolastatic void SetBinding(MCSymbolData &SD, unsigned Binding) { 56e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola assert(Binding == ELF::STB_LOCAL || Binding == ELF::STB_GLOBAL || 57e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola Binding == ELF::STB_WEAK); 58e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola uint32_t OtherFlags = SD.getFlags() & ~(0xf << ELF_STB_Shift); 59e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola SD.setFlags(OtherFlags | (Binding << ELF_STB_Shift)); 60e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola} 61e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola 62152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindolastatic unsigned GetVisibility(MCSymbolData &SD) { 63152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola unsigned Visibility = 64152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola (SD.getFlags() & (0xf << ELF_STV_Shift)) >> ELF_STV_Shift; 65152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola assert(Visibility == ELF::STV_DEFAULT || Visibility == ELF::STV_INTERNAL || 66152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola Visibility == ELF::STV_HIDDEN || Visibility == ELF::STV_PROTECTED); 67152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola return Visibility; 68152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola} 69152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 704b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 71a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindolastatic bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 72a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola switch (Variant) { 735c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola default: 745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola return false; 75a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_GOT: 76a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_PLT: 77a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_GOTPCREL: 78a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_TPOFF: 79a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_TLSGD: 80a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_GOTTPOFF: 81a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_INDNTPOFF: 82a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_NTPOFF: 83a0a2f8734cdfc19d44201b791a969bcdda96bb70Rafael Espindola case MCSymbolRefExpr::VK_GOTNTPOFF: 84a264f72d3fb9dec1427480fcf17ef3c746ea723aRafael Espindola case MCSymbolRefExpr::VK_TLSLDM: 850cf15d61b7e3bf53f5a99f58ada37b93bc039559Rafael Espindola case MCSymbolRefExpr::VK_DTPOFF: 86b4d1721eff7b43577e5f2e53f885973fb6c43683Rafael Espindola case MCSymbolRefExpr::VK_TLSLD: 875c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola return true; 885c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 895c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola} 905c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 91127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindolastatic bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 92127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola const MCFixupKindInfo &FKI = 93127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 94127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola 95127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 96127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola} 97127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola 983565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingnamespace { 99115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar class ELFObjectWriter : public MCObjectWriter { 100d3443e99e43945fdb0742177da06a32fa225740dJason W Kim protected: 101b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner /*static bool isFixupKindX86RIPRel(unsigned Kind) { 1023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming return Kind == X86::reloc_riprel_4byte || 1033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Kind == X86::reloc_riprel_4byte_movq_load; 104b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner }*/ 1053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// ELFSymbolData - Helper struct for containing some precomputed information 1083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// on symbols. 1093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming struct ELFSymbolData { 1103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData *SymbolData; 1113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t StringIndex; 1123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint32_t SectionIndex; 1133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Support lexicographic sorting. 1153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming bool operator<(const ELFSymbolData &RHS) const { 116ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola if (GetType(*SymbolData) == ELF::STT_FILE) 117ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola return true; 118ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola if (GetType(*RHS.SymbolData) == ELF::STT_FILE) 119ad49cf586624c400302d17ecc2c2e41ea4346f1aRafael Espindola return false; 12036c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer return SymbolData->getSymbol().getName() < 12136c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer RHS.SymbolData->getSymbol().getName(); 1223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 1233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming }; 1243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @name Relocation Data 1263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @{ 1273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming struct ELFRelocationEntry { 1293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Make these big enough for both 32-bit and 64-bit 1303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t r_offset; 1318f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola int Index; 1328f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola unsigned Type; 1338f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola const MCSymbol *Symbol; 1343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t r_addend; 135858e7506e1fabe563eb4222c80ad0fad01641becJason W Kim 1364a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim ELFRelocationEntry() 1374a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim : r_offset(0), Index(0), Type(0), Symbol(0), r_addend(0) {} 1384a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim 13910907426893019c6b7e59c886e41815d4fe50b19Jason W Kim ELFRelocationEntry(uint64_t RelocOffset, int Idx, 14010907426893019c6b7e59c886e41815d4fe50b19Jason W Kim unsigned RelType, const MCSymbol *Sym, 1414a511f0be22542a39ed4f24a36cbbd81d293d7ddJason W Kim uint64_t Addend) 14210907426893019c6b7e59c886e41815d4fe50b19Jason W Kim : r_offset(RelocOffset), Index(Idx), Type(RelType), 14310907426893019c6b7e59c886e41815d4fe50b19Jason W Kim Symbol(Sym), r_addend(Addend) {} 1443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Support lexicographic sorting. 1463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming bool operator<(const ELFRelocationEntry &RE) const { 1473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming return RE.r_offset < r_offset; 1483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 1493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming }; 1503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1518f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola SmallPtrSet<const MCSymbol *, 16> UsedInReloc; 152484291c27319668ad99cb87def000254357736fbRafael Espindola SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; 15388182132470527e27231f09b25a885893e528c66Rafael Espindola DenseMap<const MCSymbol *, const MCSymbol *> Renames; 1548f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 1553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming llvm::DenseMap<const MCSectionData*, 1563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> > Relocations; 1573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; 1583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @} 1603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @name Symbol Table Data 1613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @{ 1623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming SmallString<256> StringTable; 1643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFSymbolData> LocalSymbolData; 1653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFSymbolData> ExternalSymbolData; 1663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFSymbolData> UndefinedSymbolData; 1673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// @} 1693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1705c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola bool NeedsGOT; 1715c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 1727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool NeedsSymtabShndx; 1737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 1743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned Is64Bit : 1; 1753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming bool HasRelocationAddend; 1773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1785baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky Triple::OSType OSType; 1795baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky 180eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck uint16_t EMachine; 181eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck 1823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // This holds the symbol table index of the last local symbol. 1833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned LastLocalSymbolIndex; 1843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // This holds the .strtab section index. 1853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned StringTableIndex; 1867be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola // This holds the .symtab section index. 1877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola unsigned SymbolTableIndex; 1883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned ShstrtabIndex; 1903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1911f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 1921f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol *SymbolToReloc(const MCAssembler &Asm, 1931f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 1941f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCFragment &F) const; 1951f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 1963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming public: 197115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, 198115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint16_t _EMachine, bool _HasRelAddend, 199115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Triple::OSType _OSType) 200115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar : MCObjectWriter(_OS, IsLittleEndian), 201115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar NeedsGOT(false), NeedsSymtabShndx(false), 2025baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky Is64Bit(_Is64Bit), HasRelocationAddend(_HasRelAddend), 203eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck OSType(_OSType), EMachine(_EMachine) { 2043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 205d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 206d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual ~ELFObjectWriter(); 207d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 2083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void WriteWord(uint64_t W) { 209b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner if (Is64Bit) 210115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write64(W); 211b188a3789e2fc64ec7088a220c4c428c41d86faaChris Lattner else 212115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write32(W); 2133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringLE16(char *buf, uint16_t Value) { 2163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming buf[0] = char(Value >> 0); 2173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming buf[1] = char(Value >> 8); 2183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringLE32(char *buf, uint32_t Value) { 22136c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer StringLE16(buf, uint16_t(Value >> 0)); 222c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer StringLE16(buf + 2, uint16_t(Value >> 16)); 2233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringLE64(char *buf, uint64_t Value) { 22636c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer StringLE32(buf, uint32_t(Value >> 0)); 227c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer StringLE32(buf + 4, uint32_t(Value >> 32)); 2283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringBE16(char *buf ,uint16_t Value) { 2313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming buf[0] = char(Value >> 8); 2323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming buf[1] = char(Value >> 0); 2333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringBE32(char *buf, uint32_t Value) { 23636c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer StringBE16(buf, uint16_t(Value >> 16)); 237c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer StringBE16(buf + 2, uint16_t(Value >> 0)); 2383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 2403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming void StringBE64(char *buf, uint64_t Value) { 24136c6dc22bcaed92f03f7019a0d1cd47ea69e12daBenjamin Kramer StringBE32(buf, uint32_t(Value >> 32)); 242c522f6e70b02d161e4bf37023edb20643ee34acfBenjamin Kramer StringBE32(buf + 4, uint32_t(Value >> 0)); 2433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 245af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola void String8(MCDataFragment &F, uint8_t Value) { 246af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola char buf[1]; 247af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola buf[0] = Value; 248af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola F.getContents() += StringRef(buf, 1); 249af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola } 250af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola 251af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola void String16(MCDataFragment &F, uint16_t Value) { 252af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola char buf[2]; 253115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar if (isLittleEndian()) 254f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringLE16(buf, Value); 2553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming else 256f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringBE16(buf, Value); 257af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola F.getContents() += StringRef(buf, 2); 2583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 260af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola void String32(MCDataFragment &F, uint32_t Value) { 261af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola char buf[4]; 262115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar if (isLittleEndian()) 263f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringLE32(buf, Value); 2643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming else 265f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringBE32(buf, Value); 266af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola F.getContents() += StringRef(buf, 4); 2673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 269af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola void String64(MCDataFragment &F, uint64_t Value) { 270af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola char buf[8]; 271115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar if (isLittleEndian()) 272f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringLE64(buf, Value); 2733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming else 274f8020a3978b9a56074a3a5f9821c63165e37bff7Eli Friedman StringBE64(buf, Value); 275af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola F.getContents() += StringRef(buf, 8); 2763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 2773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 278d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteHeader(uint64_t SectionDataSize, unsigned NumberOfSections); 2793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 280d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteSymbolEntry(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 2817be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola uint64_t name, uint8_t info, 2823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t value, uint64_t size, 2837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola uint8_t other, uint32_t shndx, 2847be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool Reserved); 2853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 286d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 2877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ELFSymbolData &MSD, 2883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCAsmLayout &Layout); 2893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 290bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; 291d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteSymbolTable(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 2927be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola const MCAssembler &Asm, 29371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola const MCAsmLayout &Layout, 2944beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap); 2953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 296d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void RecordRelocation(const MCAssembler &Asm, const MCAsmLayout &Layout, 29756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, const MCFixup &Fixup, 29856a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, uint64_t &FixedValue); 2993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 300d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, 3010b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Kramer const MCSymbol *S); 3023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Map from a group section to the signature symbol 3041f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; 3051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Map from a signature symbol to the group section 3061f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; 3071f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// ComputeSymbolTable - Compute the symbol table data 3093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// 3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// \param StringTable [out] - The string table data. 3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// \param StringIndexMap [out] - Map from symbol names to offsets in the 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming /// string table. 313d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void ComputeSymbolTable(MCAssembler &Asm, 3141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap); 316bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 317d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void ComputeIndexMap(MCAssembler &Asm, 318bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy &SectionIndexMap); 3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 320d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, 3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionData &SD); 3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 323d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { 3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::const_iterator it = Asm.begin(), 3253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.end(); it != ie; ++it) { 3263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteRelocation(Asm, Layout, *it); 3273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 330d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, 3314beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap); 3323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 333d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void CreateGroupSections(MCAssembler &Asm, MCAsmLayout &Layout, 3341f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap); 3352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 33685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 33785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout); 3383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 339d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Address, uint64_t Offset, 3413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size, uint32_t Link, uint32_t Info, 3423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Alignment, uint64_t EntrySize); 3433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3441f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar virtual void WriteRelocationsFragment(const MCAssembler &Asm, 3451f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar MCDataFragment *F, 3461f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar const MCSectionData *SD); 3471f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar 3481f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar virtual bool 3491f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar IsSymbolRefDifferenceFullyResolved(const MCAssembler &Asm, 3501f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar const MCSymbolRefExpr *A, 3511f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar const MCSymbolRefExpr *B) const { 3521f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar // FIXME: Implement this! 3531f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar return false; 3541f3662abba2abdf5a0ab77095834271fcf846579Daniel Dunbar } 3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 356d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual bool IsFixupFullyResolved(const MCAssembler &Asm, 3577070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCValue Target, 3587070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola bool IsPCRel, 3597070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCFragment *DF) const; 3607070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 361d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 362d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual void WriteSection(MCAssembler &Asm, 363c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola uint32_t GroupSymbolIndex, 365c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t Offset, uint64_t Size, uint64_t Alignment, 366c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF &Section); 36756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 36856a399023aba6cf1348533df04732950c43eaca7Jason W Kim protected: 36956a399023aba6cf1348533df04732950c43eaca7Jason W Kim virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 37056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, bool IsRelocWithSymbol, 37156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) = 0; 3723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming }; 3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 374d3443e99e43945fdb0742177da06a32fa225740dJason W Kim //===- X86ELFObjectWriter -------------------------------------------===// 375d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 376d3443e99e43945fdb0742177da06a32fa225740dJason W Kim class X86ELFObjectWriter : public ELFObjectWriter { 377d3443e99e43945fdb0742177da06a32fa225740dJason W Kim public: 378d3443e99e43945fdb0742177da06a32fa225740dJason W Kim X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, 379d3443e99e43945fdb0742177da06a32fa225740dJason W Kim uint16_t _EMachine, bool _HasRelAddend, 380d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Triple::OSType _OSType); 3814b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 382d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual ~X86ELFObjectWriter(); 38356a399023aba6cf1348533df04732950c43eaca7Jason W Kim protected: 38456a399023aba6cf1348533df04732950c43eaca7Jason W Kim virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 38556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, bool IsRelocWithSymbol, 38656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend); 387d3443e99e43945fdb0742177da06a32fa225740dJason W Kim }; 388d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 389d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 390d3443e99e43945fdb0742177da06a32fa225740dJason W Kim //===- ARMELFObjectWriter -------------------------------------------===// 391d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 392d3443e99e43945fdb0742177da06a32fa225740dJason W Kim class ARMELFObjectWriter : public ELFObjectWriter { 393d3443e99e43945fdb0742177da06a32fa225740dJason W Kim public: 394d3443e99e43945fdb0742177da06a32fa225740dJason W Kim ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, 395d3443e99e43945fdb0742177da06a32fa225740dJason W Kim uint16_t _EMachine, bool _HasRelAddend, 396d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Triple::OSType _OSType); 3974b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 398d3443e99e43945fdb0742177da06a32fa225740dJason W Kim virtual ~ARMELFObjectWriter(); 39985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim protected: 40056a399023aba6cf1348533df04732950c43eaca7Jason W Kim virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 40156a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, bool IsRelocWithSymbol, 40256a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend); 403d3443e99e43945fdb0742177da06a32fa225740dJason W Kim }; 4044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 4054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck //===- MBlazeELFObjectWriter -------------------------------------------===// 4064b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 4074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck class MBlazeELFObjectWriter : public ELFObjectWriter { 4084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck public: 4094b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, bool IsLittleEndian, 4104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck uint16_t _EMachine, bool _HasRelAddend, 4114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Triple::OSType _OSType); 4124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 4134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck virtual ~MBlazeELFObjectWriter(); 41456a399023aba6cf1348533df04732950c43eaca7Jason W Kim protected: 41556a399023aba6cf1348533df04732950c43eaca7Jason W Kim virtual unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 41656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, bool IsRelocWithSymbol, 41756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend); 4184b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck }; 4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 421d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 422d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 423d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 425115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 426115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 4283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 4313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 4333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 4343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 4373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 4383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 4393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(Is64Bit ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 4413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 443115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 4443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 4465baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 4475baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky switch (OSType) { 4485baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::FreeBSD: Write8(ELF::ELFOSABI_FREEBSD); break; 4495baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky case Triple::Linux: Write8(ELF::ELFOSABI_LINUX); break; 4505baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky default: Write8(ELF::ELFOSABI_NONE); break; 4515baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky } 4523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 4553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 4573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 458eecb858ca86fa949c06f819d6127e2ac68d165c8Wesley Peck Write16(EMachine); // e_machine = target 4593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 4623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 463eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer WriteWord(SectionDataSize + (Is64Bit ? sizeof(ELF::Elf64_Ehdr) : 464eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make this configurable. 4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(0); // e_flags = whatever the target wants 4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 4713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 4733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 4763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(Is64Bit ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 4773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 4797be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 4807be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(0); 4817be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 4833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 4857be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 4867be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 4877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4887be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 4893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 491115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 492115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 493115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 494115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 495115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 496115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 497115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 4987be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 4997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 500af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 5017be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 502af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 5037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 5047be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 505af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 506af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 5073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 508af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola if (Is64Bit) { 509af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 510af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 511af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 512af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 513af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 514af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 5153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 516af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 517af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 518af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 519af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 520af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 521af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 5223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 5243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5252c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindolastatic uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout) { 5262c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 5272c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 5282c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 5292c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 5302c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 5312c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 5322c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 533ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola if (Data.getFragment()) 534ffd902bfb743f0564c8f7689c49403074b6f694dRafael Espindola return Layout.getSymbolOffset(&Data); 5352c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 5362c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 5372c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 5382c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 53985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 54085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 54188182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 54288182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 54388182132470527e27231f09b25a885893e528c66Rafael Espindola 54488182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 54588182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 54688182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 54794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 548f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 549f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 550f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 551f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 552f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 553f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 55407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 55588182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 55688182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 55788182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 55888182132470527e27231f09b25a885893e528c66Rafael Espindola 559f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 560f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 561f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 562f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola SetBinding(*it, GetBinding(SD)); 563f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 56407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 56588182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 56688182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 56788182132470527e27231f09b25a885893e528c66Rafael Espindola 56883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 56983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 57083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 57183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 57283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 57307ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 57488182132470527e27231f09b25a885893e528c66Rafael Espindola } 57588182132470527e27231f09b25a885893e528c66Rafael Espindola} 57688182132470527e27231f09b25a885893e528c66Rafael Espindola 577115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 578115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 579115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 580115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 581de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 582de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 58394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 584152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5857be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 5867be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 5877be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 588152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Binding = GetBinding(OrigData); 589152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Visibility = GetVisibility(OrigData); 590152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Type = GetType(Data); 591152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 592152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 593152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 594152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 5963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 5973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCExpr *ESize; 5983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 599f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 600f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 6013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ESize = Data.getSize(); 6023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming if (Data.getSize()) { 6033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCValue Res; 6043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming if (ESize->getKind() == MCExpr::Binary) { 6053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCBinaryExpr *BE = static_cast<const MCBinaryExpr *>(ESize); 6063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming if (BE->EvaluateAsRelocatable(Res, &Layout)) { 60824f1206c7de0f21d309d27737071ad742d5ddf27Benjamin Kramer assert(!Res.getSymA() || !Res.getSymA()->getSymbol().isDefined()); 60924f1206c7de0f21d309d27737071ad742d5ddf27Benjamin Kramer assert(!Res.getSymB() || !Res.getSymB()->getSymbol().isDefined()); 610f230df9af4012f9510de664b6d62b128e26a5861Rafael Espindola Size = Res.getConstant(); 6113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else if (ESize->getKind() == MCExpr::Constant) { 613368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer Size = static_cast<const MCConstantExpr *>(ESize)->getValue(); 6143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 6153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(0 && "Unsupported size expression"); 6163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 6207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 6217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 624115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 625115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 626115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 627115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 6284beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap) { 6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 6313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 6323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 6343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 6367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 6373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 6393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 6403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 6413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 6427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 64571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 6464beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 6474beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 648a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 6494beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 6504beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 6514beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 6524beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 6534beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_SYMTAB) 654a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 6557be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 6564beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), false); 657a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 658a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 6593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 6613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 6623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6633223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 6643223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 6653223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 6667be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 667e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola if (GetBinding(Data) == ELF::STB_LOCAL) 6683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 6723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 6733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 675e15eb4e14cd543b925a837026cbdde9f94393e1cRafael Espindola if (GetBinding(Data) == ELF::STB_LOCAL) 6763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6801f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 6811f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 6821f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCFragment &F) const { 6831f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 68494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 68594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 68694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 68794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 68894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 68994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 69094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 69194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 6921f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 6931f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 69494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 69594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 69694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 69794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 69894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6997eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 7007eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 70194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 70225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 7037eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 70425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 7051f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola return NULL; 7067eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 70725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 70825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 70925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 71025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 71125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 71225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 7138cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 7143729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 7153729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 7163729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 7178cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 718c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 719c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 72025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 72194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 72294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 72394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 72494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 7253729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 7261f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola if (Section.getFlags() & MCSectionELF::SHF_MERGE) { 72794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 72894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return NULL; 72994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 73094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 73194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 7321f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 733c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 7341f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola return NULL; 73573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 73673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 7373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 73856a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 74456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 74556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 74656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 74756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 74856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 749127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 75156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 75256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 75356a399023aba6cf1348533df04732950c43eaca7Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment); 75456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 75556a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 75656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 75756a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 75856a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 75956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 76056a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 76156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 76256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 76356a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Ofeset of the relocation in the section 76456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 76556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 76656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 76756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 76856a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 76956a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 77056a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 77156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 77256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 77356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 77456a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 77556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 77656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 77756a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 77856a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 77956a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 78056a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 78156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 78256a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 78356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 78456a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 78556a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Is64Bit) 78656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 78756a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 78856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 78956a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 79056a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 79156a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 79256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 79356a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 79456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 79556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 79656a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!HasRelocationAddend) Addend = 0; 79756a399023aba6cf1348533df04732950c43eaca7Jason W Kim ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend); 79856a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 79956a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 80056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 80156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 8020b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 803115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 804115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 8057b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 806ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 8073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 8083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 809737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindolastatic bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, 81088182132470527e27231f09b25a885893e528c66Rafael Espindola bool Used, bool Renamed) { 811484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 812484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 813484291c27319668ad99cb87def000254357736fbRafael Espindola 814bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 815bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 816bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 81788182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 81888182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 81988182132470527e27231f09b25a885893e528c66Rafael Espindola 820737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 821a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 822d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 823d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 824d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 82594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 826d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (!A.isVariable() && A.isUndefined() && !Data.isCommon()) 827a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 828a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 829737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 830737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 831737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 832bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 833737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 834737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 835737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 836737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 837737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 8381f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindolastatic bool isLocal(const MCSymbolData &Data, bool isSignature, 8391f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isUsedInReloc) { 840737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 841737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 842737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 843737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 84494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8451f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8461f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 8471f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 8481f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 8491f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 850737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 8511f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 852737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 853737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 854737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 855737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 856115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 857115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar SectionIndexMapTy &SectionIndexMap) { 858bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 859bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 860bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 861bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 862bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8632ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 8642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8652ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 8662ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 8692ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 8702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8712ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8722ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() == ELF::SHT_GROUP) 8732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 874bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 875bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 876bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 877bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 878115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 8791f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 8801f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap) { 8815c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 8825c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 8835c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 8845c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 8855c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 8865c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 887f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola SetBinding(Data, ELF::STB_GLOBAL); 8885c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 8895c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Build section lookup table. 891ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola int NumRegularSections = Asm.size(); 8923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 8943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 8953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 8963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 897a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 8983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 8993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 9013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 902484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 903484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 9041f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 9051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 9061f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 9071f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 90888182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 9093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 9103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 9123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 91394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 9143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 9161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 9171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 9181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!Local && GetBinding(*it) == ELF::STB_LOCAL) { 9191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 9201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola SetBinding(*it, ELF::STB_GLOBAL); 9211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola SetBinding(SD, ELF::STB_GLOBAL); 9221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 9231f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 924484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 925484291c27319668ad99cb87def000254357736fbRafael Espindola SetBinding(*it, ELF::STB_WEAK); 926484291c27319668ad99cb87def000254357736fbRafael Espindola 927f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 928a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 929f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 930bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 931a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 93288182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 9331f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 9341f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 9351f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 9361f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 9373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 938bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 939bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 940bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 9417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 9427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 9445df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 9455df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 94688182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 94788182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 94888182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 9491261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 9501261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 95188182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 95288182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 9531261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 9541261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 9551261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 9561261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 95788182132470527e27231f09b25a885893e528c66Rafael Espindola } 95888182132470527e27231f09b25a885893e528c66Rafael Espindola 9591261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 960a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 961a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 9621261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 963a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 9643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 965a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 966a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 967a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 968a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 969a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 970a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 971a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 9723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 9753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 9763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 9773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 9783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 9803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 981ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 9823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 984ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 985ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 986ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 9893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 9913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 9923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 993115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocation(MCAssembler &Asm, MCAsmLayout &Layout, 994115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData &SD) { 9953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming if (!Relocations[&SD].empty()) { 9963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 9974283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *RelaSection; 9983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 9993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 10003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 1002377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer std::string RelaSectionName = HasRelocationAddend ? ".rela" : ".rel"; 10033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 1004299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 1005299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 1006299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer if (HasRelocationAddend) 1007299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 1008299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 1009299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer EntrySize = Is64Bit ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 10103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1011377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer RelaSection = Ctx.getELFSection(RelaSectionName, HasRelocationAddend ? 1012377a572d9b92304a0fde4371d726721586c1a5bdBenjamin Kramer ELF::SHT_RELA : ELF::SHT_REL, 0, 10133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming SectionKind::getReadOnly(), 10142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 10153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 1017a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer RelaSD.setAlignment(Is64Bit ? 8 : 4); 10183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 10203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteRelocationsFragment(Asm, F, &SD); 10223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1025115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1026115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 1027115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1028115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 1029115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1030115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 10313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 10323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 10343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 10373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1043115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 1044115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 10463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // sort by the r_offset just like gnu as does 10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(Relocs.begin(), Relocs.end()); 10493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 10513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 10523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 105312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 105412203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 105512203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 10568f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 10578f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 105812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 10595e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer if (Is64Bit) { 1060af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 10615e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10628f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 10638f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 1064af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 10655e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1066af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola if (HasRelocationAddend) 1067af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 10685e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 1069af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 10705e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10718f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 10728f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 1073af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 10745e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1075af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola if (HasRelocationAddend) 1076af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 10775e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 10783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1081115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 1082115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 10834beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const SectionIndexMapTy &SectionIndexMap) { 10843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 10853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 10863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned EntrySize = Is64Bit ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 10883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 108938738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 10904283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 10917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 10923f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 109371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 109471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 109571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabIndex = Asm.size(); 109671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 10974283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 10987be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 10997be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 11002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 11013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 11023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming SymtabSD.setAlignment(Is64Bit ? 8 : 4); 11037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymbolTableIndex = Asm.size(); 11047be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11057be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 11067be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11077be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11084283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 11097be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 11102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 11117be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 11127be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 11137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSection *StrtabSection; 11163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 11173f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 11183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 11193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 11203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTableIndex = Asm.size(); 11213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1122c3c413f63117896f186fc4385bdaac0578d3613fRafael Espindola WriteRelocations(Asm, Layout); 112371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 112471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 112571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 11267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 11277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 11297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11304beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 113171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 11333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 11343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 11363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 11383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 11393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 11403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 11413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 11423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 11433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringMap<uint64_t> SecStringMap; 11453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::const_iterator it = Asm.begin(), 11463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.end(); it != ie; ++it) { 11473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 1148368ae7e4ec0cc0dfc404fa1d07cdf94a7f2a15beBenjamin Kramer static_cast<const MCSectionELF&>(it->getSection()); 114951efe7a253190b672519e8388ce5d45f1dcf1a24Rafael Espindola // FIXME: We could merge suffixes like in .text and .rela.text. 11503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 11522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (SecStringMap.count(Name)) { 11532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = SecStringMap[Name]; 11542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 11552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 11563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 11573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 11582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 11592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SecStringMap[Name] = Index; 11603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 11622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 11633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 11643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11657070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 11667070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 1167115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarbool ELFObjectWriter::IsFixupFullyResolved(const MCAssembler &Asm, 1168115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCValue Target, 1169115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool IsPCRel, 1170115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCFragment *DF) const { 11717070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola // If this is a PCrel relocation, find the section this fixup value is 11727070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola // relative to. 11737070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCSection *BaseSection = 0; 11747070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola if (IsPCRel) { 11757070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola BaseSection = &DF->getParent()->getSection(); 11767070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola assert(BaseSection); 11777070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola } 11787070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 11797070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCSection *SectionA = 0; 11807070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCSymbol *SymbolA = 0; 11817070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola if (const MCSymbolRefExpr *A = Target.getSymA()) { 11822c920850343810535c0cd8720a81eddf7997663aRafael Espindola SymbolA = &A->getSymbol(); 11832c920850343810535c0cd8720a81eddf7997663aRafael Espindola SectionA = &SymbolA->AliasedSymbol().getSection(); 11847070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola } 11857070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 11867070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCSection *SectionB = 0; 118712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola const MCSymbol *SymbolB = 0; 11887070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola if (const MCSymbolRefExpr *B = Target.getSymB()) { 118912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola SymbolB = &B->getSymbol(); 119012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola SectionB = &SymbolB->AliasedSymbol().getSection(); 11917070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola } 11927070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 11937070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola if (!BaseSection) 11947070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola return SectionA == SectionB; 11957070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 119612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (SymbolB) 119712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola return false; 119812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola 119912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola // Absolute address but PCrel instruction, so we need a relocation. 120012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!SymbolA) 120112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola return false; 120212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola 12032c920850343810535c0cd8720a81eddf7997663aRafael Espindola // FIXME: This is in here just to match gnu as output. If the two ends 12042c920850343810535c0cd8720a81eddf7997663aRafael Espindola // are in the same section, there is nothing that the linker can do to 12052c920850343810535c0cd8720a81eddf7997663aRafael Espindola // break it. 12067070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola const MCSymbolData &DataA = Asm.getSymbolData(*SymbolA); 12077070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola if (DataA.isExternal()) 12087070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola return false; 12097070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 121012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola return BaseSection == SectionA; 12113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 12123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1213115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateGroupSections(MCAssembler &Asm, 1214115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 12151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola GroupMapTy &GroupMap, 12161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy &RevGroupMap) { 12172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 12182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 12202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) 12232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 12262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 12271f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 12282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 12292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Group = Asm.getContext().CreateELFGroupSection(); 12302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 12322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12332ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 12342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola unsigned Index = 1; 12401f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola unsigned NumGroups = RevGroupMap.size(); 12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it, ++Index) { 12432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!(Section.getFlags() & MCSectionELF::SHF_GROUP)) 12462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12471f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, NumGroups + Index); 12522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 12542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1255115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 1256115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 1257115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 1258115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1259115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1260115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 1261c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 1262c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 1263c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1264c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 1265c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 1268c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 1272c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 1274c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 1275c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 12763f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1277c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 1278c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 1279c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 12863f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1291c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 1295c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 1303c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 1304c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1305c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 1306c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola case ELF::SHT_GROUP: { 13102ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 13112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 13122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 13132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 13142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1315c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1316c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1317c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1318c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1319c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1320c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1321c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1322c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1323c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1324c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic bool IsELFMetaDataSection(const MCSectionData &SD) { 1326f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 13276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 13286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13306db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic uint64_t DataSectionSize(const MCSectionData &SD) { 13316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 13326db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 13346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 13356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 13376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 13386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 13396db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13416db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic uint64_t GetSectionFileSize(const MCAsmLayout &Layout, 13426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCSectionData &SD) { 13436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 13456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 13466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 134885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolastatic uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, 134985f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCSectionData &SD) { 13506db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13516db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 135285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 13536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13556db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindolastatic void WriteDataSectionData(ELFObjectWriter *W, const MCSectionData &SD) { 13566db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13576db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 13586db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 13596db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13606db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola W->WriteBytes(cast<MCDataFragment>(F).getContents().str()); 13616db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 13626db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1364115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1365115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 13662ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 13671f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 13681f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola CreateGroupSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 13691f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMap); 13702ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1371bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1372bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 1373bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap); 1374bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 13758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 13761f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap); 13778f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 13783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 13794beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 13804beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola SectionIndexMap); 13813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 13821d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola // Update to include the metadata sections. 13831d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap); 13841d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 13853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Add 1 for the null section. 13863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming unsigned NumSections = Asm.size() + 1; 1387a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t NaturalAlignment = Is64Bit ? 8 : 4; 1388a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t HeaderSize = Is64Bit ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr); 1389a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 13903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 13912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 13922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Sections.resize(NumSections); 13932ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 13942ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (SectionIndexMapTy::const_iterator i= 13952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 13962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 13972ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Sections[p.second] = p.first; 13982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 13992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 14002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (unsigned i = 1; i < NumSections; ++i) { 14012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 14022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1404a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1405a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 14063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 14076db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 14083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 14093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1410a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1411a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 14123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the ELF header ... 1413a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteHeader(FileOff - HeaderSize, NumSections); 1414a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 1415a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = HeaderSize; 14163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ... then all of the sections ... 14183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming DenseMap<const MCSection*, uint64_t> SectionOffsetMap; 14193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (unsigned i = 1; i < NumSections; ++i) { 14212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 14222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1423a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 1424a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, SD.getAlignment()); 1425a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1426a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff += Padding; 1427a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 14283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 14292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 143044cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 14316db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 14323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14336db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 14346db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola WriteDataSectionData(this, SD); 14356db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola else 14365d2477cecf53bef911f57423a5cecb743d4286faDaniel Dunbar Asm.WriteSectionData(&SD, Layout); 14373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 14383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1439a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t Padding = OffsetToAlignment(FileOff, NaturalAlignment); 1440a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1441a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff += Padding; 1442a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 14433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ... and then the section header table. 14443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Should we align the section header table? 14453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 14463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Null section first. 14477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola uint64_t FirstSectionSize = 14487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 14497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola uint32_t FirstSectionLink = 14507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 14517be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 14523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (unsigned i = 1; i < NumSections; ++i) { 14542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 14552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola uint32_t GroupSymbolIndex; 14572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 14582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupSymbolIndex = 0; 14592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola else 14602ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, GroupMap[&Section]); 14613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 146285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 14636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 14642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 14656db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola SectionOffsetMap[&Section], Size, 1466c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SD.getAlignment(), Section); 14673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 14683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 14693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14706024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 14716024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1472115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Is64Bit, 1473115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Triple::OSType OSType, 1474115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint16_t EMachine, 1475115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool IsLittleEndian, 1476115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool HasRelocationAddend) { 1477d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (EMachine) { 1478d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_386: 1479d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_X86_64: 1480d3443e99e43945fdb0742177da06a32fa225740dJason W Kim return new X86ELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine, 1481d3443e99e43945fdb0742177da06a32fa225740dJason W Kim HasRelocationAddend, OSType); break; 1482d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case ELF::EM_ARM: 1483d3443e99e43945fdb0742177da06a32fa225740dJason W Kim return new ARMELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine, 1484d3443e99e43945fdb0742177da06a32fa225740dJason W Kim HasRelocationAddend, OSType); break; 14854b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case ELF::EM_MBLAZE: 14864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck return new MBlazeELFObjectWriter(OS, Is64Bit, IsLittleEndian, EMachine, 14874b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck HasRelocationAddend, OSType); break; 14883285877131ed40d7fe75babf4ee3f4e0d287e4a4Benjamin Kramer default: llvm_unreachable("Unsupported architecture"); break; 1489d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1490d3443e99e43945fdb0742177da06a32fa225740dJason W Kim} 1491d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1492d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1493d3443e99e43945fdb0742177da06a32fa225740dJason W Kim/// START OF SUBCLASSES for ELFObjectWriter 1494d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- ARMELFObjectWriter -------------------------------------------===// 1495d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1496d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::ARMELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, 1497d3443e99e43945fdb0742177da06a32fa225740dJason W Kim bool _IsLittleEndian, 1498d3443e99e43945fdb0742177da06a32fa225740dJason W Kim uint16_t _EMachine, bool _HasRelocationAddend, 1499d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Triple::OSType _OSType) 1500d3443e99e43945fdb0742177da06a32fa225740dJason W Kim : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine, 1501d3443e99e43945fdb0742177da06a32fa225740dJason W Kim _HasRelocationAddend, _OSType) 1502d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1503d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1504d3443e99e43945fdb0742177da06a32fa225740dJason W KimARMELFObjectWriter::~ARMELFObjectWriter() 1505d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1506d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 150785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kimunsigned ARMELFObjectWriter::GetRelocType(const MCValue &Target, 150885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim const MCFixup &Fixup, 150956a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 151056a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 151156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 151285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 151385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 151485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 1515a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim unsigned Type = 0; 151685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (IsPCRel) { 151785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 151885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: assert(0 && "Unimplemented"); 15193fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case FK_Data_4: 15203fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 15213fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); 15223fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_None: 15233fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_BASE_PREL; break; 15243fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 15253fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim assert(0 && "unimplemented"); break; 15263fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 15273fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; 15283fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim } break; 15293fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case ARM::fixup_arm_branch: 15303fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim switch (Modifier) { 15313fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_PLT: 15323fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_PLT32; break; 15333fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: 15343fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_CALL; break; 15353fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim } break; 153685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 153785fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } else { 153885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim switch ((unsigned)Fixup.getKind()) { 153985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim default: llvm_unreachable("invalid fixup kind!"); 1540a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case FK_Data_4: 1541a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim switch (Modifier) { 15423fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim default: llvm_unreachable("Unsupported Modifier"); break; 15433fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOT: 15443fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_GOT_BREL; break; 15453fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_TLSGD: 15463fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_GD32; break; 1547f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_ARM_TPOFF: 1548f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim Type = ELF::R_ARM_TLS_LE32; break; 1549a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim case MCSymbolRefExpr::VK_ARM_GOTTPOFF: 15503fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_TLS_IE32; break; 1551f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim case MCSymbolRefExpr::VK_None: 1552f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim Type = ELF::R_ARM_ABS32; break; 15533fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim case MCSymbolRefExpr::VK_ARM_GOTOFF: 15543fa4c1dc95098105e73aa7055c27bebbf9112966Jason W Kim Type = ELF::R_ARM_GOTOFF32; break; 1555a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim } break; 1556dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_ldst_pcrel_12: 15579d63d90de5e57ad96f467b270544443a9284eb2bOwen Anderson case ARM::fixup_arm_pcrel_10: 1558dff84b03258514463ede477af38f1246b95b0cd0Jim Grosbach case ARM::fixup_arm_adr_pcrel_12: 1559662a816e89a9d77bf75e1328b09cf9235b4682aaJim Grosbach case ARM::fixup_arm_thumb_bl: 1560b492a7c2134d3886f545f1b5ea55115d71529a10Jim Grosbach case ARM::fixup_arm_thumb_cb: 1561b8958b031ec5163261f490f131780c5dc3d823d6Bill Wendling case ARM::fixup_arm_thumb_cp: 1562e246717c3a36a913fd4200776ed621649bb2b624Jim Grosbach case ARM::fixup_arm_thumb_br: 156385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim assert(0 && "Unimplemented"); break; 156485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_branch: 1565f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim // FIXME: Differentiate between R_ARM_CALL and 1566f13743bb3c3fb37a59b59f26056bc391bf0adcdcJason W Kim // R_ARM_JUMP24 (latter used for conditional jumps) 1567a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim Type = ELF::R_ARM_CALL; break; 156885fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movt_hi16: 1569a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim Type = ELF::R_ARM_MOVT_ABS; break; 157085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim case ARM::fixup_arm_movw_lo16: 1571a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim Type = ELF::R_ARM_MOVW_ABS_NC; break; 157285fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 157385fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim } 157485fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 157585fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim if (RelocNeedsGOT(Modifier)) 157685fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim NeedsGOT = true; 1577a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim 1578a0871e79270b2a05f93c9df73bbe24c587faa94eJason W Kim return Type; 157985fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim} 158085fed5e0c5bc010f967948a4af6b425a5a2f2bd0Jason W Kim 15814b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck//===- MBlazeELFObjectWriter -------------------------------------------===// 1582d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 15834b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::MBlazeELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, 15844b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck bool _IsLittleEndian, 15854b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck uint16_t _EMachine, 15864b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck bool _HasRelocationAddend, 15874b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Triple::OSType _OSType) 15884b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine, 15894b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck _HasRelocationAddend, _OSType) { 15904b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15914b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 15924b04713423c6da988db75c7546baa3db7ddfa119Wesley PeckMBlazeELFObjectWriter::~MBlazeELFObjectWriter() { 15934b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 15944b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck 159556a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned MBlazeELFObjectWriter::GetRelocType(const MCValue &Target, 15964b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck const MCFixup &Fixup, 159756a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 159856a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 159956a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 16004b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck // determine the type of the relocation 16014b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck unsigned Type; 16024b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck if (IsPCRel) { 16034b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16044b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: 16054b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck llvm_unreachable("Unimplemented"); 1606e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 16074b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_64_PCREL; 16084b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 1609e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_2: 16104b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32_PCREL; 16114b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16124b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16134b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } else { 16144b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck switch ((unsigned)Fixup.getKind()) { 16154b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck default: llvm_unreachable("invalid fixup kind!"); 16164b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_4: 161756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Type = ((IsRelocWithSymbol || Addend !=0) 161856a399023aba6cf1348533df04732950c43eaca7Jason W Kim ? ELF::R_MICROBLAZE_32 161956a399023aba6cf1348533df04732950c43eaca7Jason W Kim : ELF::R_MICROBLAZE_64); 16204b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16214b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck case FK_Data_2: 16224b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck Type = ELF::R_MICROBLAZE_32; 16234b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck break; 16244b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 16254b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck } 162656a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 16274b04713423c6da988db75c7546baa3db7ddfa119Wesley Peck} 1628d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1629d3443e99e43945fdb0742177da06a32fa225740dJason W Kim//===- X86ELFObjectWriter -------------------------------------------===// 1630d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1631d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1632d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::X86ELFObjectWriter(raw_ostream &_OS, bool _Is64Bit, 1633d3443e99e43945fdb0742177da06a32fa225740dJason W Kim bool _IsLittleEndian, 1634d3443e99e43945fdb0742177da06a32fa225740dJason W Kim uint16_t _EMachine, bool _HasRelocationAddend, 1635d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Triple::OSType _OSType) 1636d3443e99e43945fdb0742177da06a32fa225740dJason W Kim : ELFObjectWriter(_OS, _Is64Bit, _IsLittleEndian, _EMachine, 1637d3443e99e43945fdb0742177da06a32fa225740dJason W Kim _HasRelocationAddend, _OSType) 1638d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1639d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1640d3443e99e43945fdb0742177da06a32fa225740dJason W KimX86ELFObjectWriter::~X86ELFObjectWriter() 1641d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 1642d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 164356a399023aba6cf1348533df04732950c43eaca7Jason W Kimunsigned X86ELFObjectWriter::GetRelocType(const MCValue &Target, 164456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 164556a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsPCRel, 164656a399023aba6cf1348533df04732950c43eaca7Jason W Kim bool IsRelocWithSymbol, 164756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend) { 1648d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // determine the type of the relocation 1649d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 165012203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 165112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 1652d3443e99e43945fdb0742177da06a32fa225740dJason W Kim unsigned Type; 1653d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (Is64Bit) { 1654d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1655d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1656d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1657d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1658d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1659d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_PC32; 1660d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1661d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1662d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_PLT32; 1663d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1664d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1665d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1666d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1667d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTTPOFF: 1668d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTTPOFF; 1669d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1670d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1671d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TLSGD; 1672d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1673d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLD: 1674d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TLSLD; 1675d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1676d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1677d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1678d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1679d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1680d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_8: Type = ELF::R_X86_64_64; break; 1681d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1682e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1683d3443e99e43945fdb0742177da06a32fa225740dJason W Kim assert(isInt<32>(Target.getConstant())); 1684d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1685d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1686d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1687d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1688d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32S; 1689d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1690d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1691d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOT32; 1692d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1693d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTPCREL: 1694d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_GOTPCREL; 1695d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1696d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1697d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_TPOFF32; 1698d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1699d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1700d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_DTPOFF32; 1701d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1702d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1703d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1704d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1705d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_X86_64_32; 1706d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1707d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_X86_64_16; break; 1708e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1709d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_X86_64_8; break; 1710d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1711d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1712d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1713d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (IsPCRel) { 1714d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1715d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1716d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1717d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1718d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PC32; 1719d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1720d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_PLT: 1721d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_PLT32; 1722d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1723d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1724d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } else { 1725d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch ((unsigned)Fixup.getKind()) { 1726d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: llvm_unreachable("invalid fixup kind!"); 1727d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1728d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_global_offset_table: 1729d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTPC; 1730d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1731d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1732d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // FIXME: Should we avoid selecting reloc_signed_4byte in 32 bit mode 1733d3443e99e43945fdb0742177da06a32fa225740dJason W Kim // instead? 1734d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case X86::reloc_signed_4byte: 1735e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_4: 1736d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_4: 1737d3443e99e43945fdb0742177da06a32fa225740dJason W Kim switch (Modifier) { 1738d3443e99e43945fdb0742177da06a32fa225740dJason W Kim default: 1739d3443e99e43945fdb0742177da06a32fa225740dJason W Kim llvm_unreachable("Unimplemented"); 1740d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_None: 1741d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_32; 1742d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1743d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOT: 1744d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOT32; 1745d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1746d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTOFF: 1747d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_GOTOFF; 1748d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1749d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSGD: 1750d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GD; 1751d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1752d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TPOFF: 1753d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE_32; 1754d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1755d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_INDNTPOFF: 1756d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_IE; 1757d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1758d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_NTPOFF: 1759d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LE; 1760d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1761d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_GOTNTPOFF: 1762d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_GOTIE; 1763d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1764d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_TLSLDM: 1765d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDM; 1766d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1767d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case MCSymbolRefExpr::VK_DTPOFF: 1768d3443e99e43945fdb0742177da06a32fa225740dJason W Kim Type = ELF::R_386_TLS_LDO_32; 1769d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1770d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1771d3443e99e43945fdb0742177da06a32fa225740dJason W Kim break; 1772d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_2: Type = ELF::R_386_16; break; 1773e04ed7e45f194f14a7b28bbf3f55694d8e2bcf80Rafael Espindola case FK_PCRel_1: 1774d3443e99e43945fdb0742177da06a32fa225740dJason W Kim case FK_Data_1: Type = ELF::R_386_8; break; 1775d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1776d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1777d3443e99e43945fdb0742177da06a32fa225740dJason W Kim } 1778d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 1779d3443e99e43945fdb0742177da06a32fa225740dJason W Kim if (RelocNeedsGOT(Modifier)) 1780d3443e99e43945fdb0742177da06a32fa225740dJason W Kim NeedsGOT = true; 1781d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 178256a399023aba6cf1348533df04732950c43eaca7Jason W Kim return Type; 17833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 1784