ELFObjectWriter.cpp revision f1d0f7781e766df878bec4e7977fa3204374f394
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 143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "MCELF.h" 153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/OwningPtr.h" 163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h" 173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.h" 183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/STLExtras.h" 193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h" 2078c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h" 213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h" 223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCAssembler.h" 233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h" 243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCELFObjectWriter.h" 253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCELFSymbolFlags.h" 263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h" 27f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h" 28f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h" 293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h" 303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h" 313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h" 323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ErrorHandling.h" 333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h" 343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 363565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 38e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef DEBUG_TYPE 39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info" 40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 413963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace { 423963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter { 433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola protected: 443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); 463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); 473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); 483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, 493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool Used, bool Renamed); 503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isLocal(const MCSymbolData &Data, bool isSignature, 513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool isUsedInReloc); 523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool IsELFMetaDataSection(const MCSectionData &SD); 533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t DataSectionSize(const MCSectionData &SD); 543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, 553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData &SD); 563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, 573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData &SD); 583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteDataSectionData(MCAssembler &Asm, 603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /*static bool isFixupKindX86RIPRel(unsigned Kind) { 643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return Kind == X86::reloc_riprel_4byte || 653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Kind == X86::reloc_riprel_4byte_movq_load; 663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }*/ 673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// ELFSymbolData - Helper struct for containing some precomputed 693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// information on symbols. 703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola struct ELFSymbolData { 713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCSymbolData *SymbolData; 723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t StringIndex; 733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t SectionIndex; 743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Support lexicographic sorting. 763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool operator<(const ELFSymbolData &RHS) const { 773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (MCELF::GetType(*SymbolData) == ELF::STT_FILE) 783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return true; 793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE) 803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return false; 813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return SymbolData->getSymbol().getName() < 823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RHS.SymbolData->getSymbol().getName(); 833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// The target specific ELF writer instance. 873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter; 883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallPtrSet<const MCSymbol *, 16> UsedInReloc; 903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; 913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola DenseMap<const MCSymbol *, const MCSymbol *> Renames; 923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola llvm::DenseMap<const MCSectionData*, 943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFRelocationEntry> > Relocations; 953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; 963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @name Symbol Table Data 993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @{ 1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallString<256> StringTable; 1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> LocalSymbolData; 1033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> ExternalSymbolData; 1043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> UndefinedSymbolData; 1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool NeedsGOT; 1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool NeedsSymtabShndx; 1113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the symbol table index of the last local symbol. 1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned LastLocalSymbolIndex; 1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .strtab section index. 1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned StringTableIndex; 1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .symtab section index. 1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned SymbolTableIndex; 1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned ShstrtabIndex; 1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *SymbolToReloc(const MCAssembler &Asm, 1233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCValue &Target, 1243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &F, 1253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const; 1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // TargetObjectWriter wrappers. 1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCValue &Target, 1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &F, 1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 1333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const { 1343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 1353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool is64Bit() const { return TargetObjectWriter->is64Bit(); } 1383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool hasRelocationAddend() const { 1393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->hasRelocationAddend(); 1403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned getEFlags() const { 1423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->getEFlags(); 1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 1453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel, bool IsRelocWithSymbol, 1463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola int64_t Addend) const { 1473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel, 1483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola IsRelocWithSymbol, Addend); 1493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola public: 1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola raw_ostream &_OS, bool IsLittleEndian) 1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola : MCObjectWriter(_OS, IsLittleEndian), 1563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola TargetObjectWriter(MOTW), 1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola NeedsGOT(false), NeedsSymtabShndx(false){ 1583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual ~ELFObjectWriter(); 1613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteWord(uint64_t W) { 1633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (is64Bit()) 1643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Write64(W); 1653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Write32(W); 1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE16(char *buf, uint16_t Value) { 1703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = char(Value >> 0); 1713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[1] = char(Value >> 8); 1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE32(char *buf, uint32_t Value) { 1753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf, uint16_t(Value >> 0)); 1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf + 2, uint16_t(Value >> 16)); 1773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE64(char *buf, uint64_t Value) { 1803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf, uint32_t(Value >> 0)); 1813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf + 4, uint32_t(Value >> 32)); 1823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE16(char *buf ,uint16_t Value) { 1853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = char(Value >> 8); 1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[1] = char(Value >> 0); 1873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE32(char *buf, uint32_t Value) { 1903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf, uint16_t(Value >> 16)); 1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf + 2, uint16_t(Value >> 0)); 1923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE64(char *buf, uint64_t Value) { 1953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf, uint32_t(Value >> 32)); 1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf + 4, uint32_t(Value >> 0)); 1973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String8(MCDataFragment &F, uint8_t Value) { 2003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[1]; 2013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = Value; 2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola F.getContents() += StringRef(buf, 1); 2033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String16(MCDataFragment &F, uint16_t Value) { 2063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[2]; 2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf, Value); 2093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf, Value); 2113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola F.getContents() += StringRef(buf, 2); 2123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String32(MCDataFragment &F, uint32_t Value) { 2153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[4]; 2163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf, Value); 2183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf, Value); 2203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola F.getContents() += StringRef(buf, 4); 2213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String64(MCDataFragment &F, uint64_t Value) { 2243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[8]; 2253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE64(buf, Value); 2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE64(buf, Value); 2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola F.getContents() += StringRef(buf, 8); 2303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteHeader(uint64_t SectionDataSize, 2333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned NumberOfSections); 2343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbolEntry(MCDataFragment *SymtabF, 2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *ShndxF, 2373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t name, uint8_t info, 2383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t value, uint64_t size, 2393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint8_t other, uint32_t shndx, 2403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool Reserved); 2413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 2433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola ELFSymbolData &MSD, 2443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout); 2453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; 2473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbolTable(MCDataFragment *SymtabF, 2483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *ShndxF, 2493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAssembler &Asm, 2503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 2513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap); 2523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void RecordRelocation(const MCAssembler &Asm, 2543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 2553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment *Fragment, 2563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 2573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCValue Target, uint64_t &FixedValue); 2583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, 2603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *S); 2613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a group section to the signature symbol 2633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; 2643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a signature symbol to the group section 2653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; 2663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a section to the section with the relocations 2673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy; 2683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a section to its offset 2693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy; 2703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// ComputeSymbolTable - Compute the symbol table data 2723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// 2733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// \param StringTable [out] - The string table data. 2743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// \param StringIndexMap [out] - Map from symbol names to offsets in the 2753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// string table. 2763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSymbolTable(MCAssembler &Asm, 2773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 2783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy RevGroupMap, 2793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned NumRegularSections); 2803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeIndexMap(MCAssembler &Asm, 2823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, 2863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RelMapTy &RelMap); 2873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 2893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, 2923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Create the sections that show up in the symbol table. Currently 2963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // those are the .note.GNU-stack section and the group sections. 2973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, 2983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola GroupMapTy &GroupMap, 2993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy &RevGroupMap, 3003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 3013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 3023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 3043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout); 3053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, 3073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 3083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionOffsetMapTy &SectionOffsetMap); 3103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSectionOrder(MCAssembler &Asm, 3123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<const MCSectionELF*> &Sections); 3133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 3153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Address, uint64_t Offset, 3163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Size, uint32_t Link, uint32_t Info, 3173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Alignment, uint64_t EntrySize); 3183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocationsFragment(const MCAssembler &Asm, 3203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *F, 3213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData *SD); 3223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual bool 3243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 3253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbolData &DataA, 3263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &FB, 3273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool InSet, 3283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const; 3293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 3313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSection(MCAssembler &Asm, 3323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t GroupSymbolIndex, 3343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Offset, uint64_t Size, uint64_t Alignment, 3353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 3363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 3373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola} 3383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 3402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 3412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 3422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 3442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 3472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 3482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 3492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 3502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 3512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 3522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 353378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola case MCSymbolRefExpr::VK_GOTOFF: 3542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 3552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 3562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 3572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 3582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 3592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 3602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 3612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 3622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 3632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 3642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 3652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 367d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 368d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 369d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 3703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 371115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 372115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 3763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 386bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 3873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 389115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 3903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 3925baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 393dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola Write8(TargetObjectWriter->getOSABI()); 3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 3973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 400bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 4013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 4043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 405bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 406eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4082d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 409e8526d030f2cf8cc79f2d923274944cb0fa9c4ebRafael Espindola Write32(getEFlags()); 4103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 412bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 4133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 4163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 418bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 4217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 422aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky Write16(ELF::SHN_UNDEF); 4237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 4253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 427b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky if (ShstrtabIndex >= ELF::SHN_LORESERVE) 4287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 4297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 4313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 433115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 434115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 435115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 436115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 437115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 438115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 439115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 4407be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 4417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 442af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 4437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 444af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 4457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 4467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 447af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 448af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 4493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 450bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 451af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 452af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 453af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 454af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 455af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 456af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 4573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 458af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 459af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 460af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 461af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 462af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 463af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 4643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 4682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 4692c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 4702c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 4712c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 473d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 474d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 475d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 476d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 477d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 478f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach return (uint64_t)IntValue; 479d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 480d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 481d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 4822c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 4832c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4842c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4856469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFragment()) { 4876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFlags() & ELF_Other_ThumbFunc) 4886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data)+1; 4896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola else 4906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data); 4916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 4922c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4932c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4942c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 4952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 49685f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 49785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 49888182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 49988182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 50088182132470527e27231f09b25a885893e528c66Rafael Espindola 50188182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 50288182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 50388182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 50494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 505f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 506f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 507f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 508f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 509f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 510f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 51107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 51288182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 51388182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 51488182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 51588182132470527e27231f09b25a885893e528c66Rafael Espindola 516f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 517f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 518f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 5192ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 520f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 52107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 52288182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 52388182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 52488182132470527e27231f09b25a885893e528c66Rafael Espindola 52583ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 52683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 52783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 52883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 52983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 53007ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 53188182132470527e27231f09b25a885893e528c66Rafael Espindola } 53288182132470527e27231f09b25a885893e528c66Rafael Espindola} 53388182132470527e27231f09b25a885893e528c66Rafael Espindola 534115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 535115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 536115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 537115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 538de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 539de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 54094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 541152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 5437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 5447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 5452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 5462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Visibility = MCELF::GetVisibility(OrigData); 5472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 548152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 549152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 550152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 551152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5522c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 5533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 5543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 555f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 556f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 557f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 558f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 559f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 560f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 561f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 562f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 5633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 5667be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 5677be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 5683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 570115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 571115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 572115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 573115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 574a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes const SectionIndexMapTy &SectionIndexMap) { 5753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 5763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 5803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 5827be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 5833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 5853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 5887be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 59171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 5924beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 5934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 594a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 5954beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 5964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 5974beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 5984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 599d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB || 600d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB_SHNDX) 601a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 6027be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 603a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), 604a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes false); 605a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 606a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 6073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 6093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 6103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6113223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 6123223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 6133223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 6147be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6152ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 6163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 6203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 6213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6232ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 6243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6281f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 6291f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 630e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFragment &F, 631e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 632e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 6331f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 63494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 63594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 63694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 63794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 63894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 63994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 64094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 64194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 6421f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 6431f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 64494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 64594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 64694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 64794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 64894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6497eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 6507eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 65194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 65225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 6537eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 65425958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 655e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 6567eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 65725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 65825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 65925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 66025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 66125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 66225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 6638cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 6643729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 6653729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 6663729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6678cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 668c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 669c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 67025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 67194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 67294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 67394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 67494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6753729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6761c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 67794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 678e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 67994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 6821f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 683c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 684e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 685e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 68673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 68773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 6883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 68956a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 69056a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 69156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 69256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 69356a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 69456a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 69556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 69656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 69756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 69856a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 69956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 700127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 70156a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 70256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 70356a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 704e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 70556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 70656a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 70756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 70856a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 70956a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 71056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 71156a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 71256a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 71356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 714a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes // Offset of the relocation in the section 71556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 71656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 71756a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 71856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 71956a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 72056a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 72156a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 72256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72556a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 72656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 72756a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 72856a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 72956a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 73256a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 73356a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 73456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 73556a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 736bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 73756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 73856a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 743c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 744c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 745c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola if (RelocNeedsGOT(Modifier)) 746c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola NeedsGOT = true; 7472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 74856a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 7502a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 751f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola // FIXME: no tests cover this. Is adjustFixupOffset dead code? 752f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset); 75356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 754bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 755bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 756bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 757bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola if (is64Bit()) 758bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<64>(Addend)); 759bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola else 760bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<32>(Addend)); 761bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 76200ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup); 76356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 76456a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 76556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 76656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 7670b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 768115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 769115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 7707b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 771ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 7723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7742ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 7752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 7762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 777484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 778484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 779484291c27319668ad99cb87def000254357736fbRafael Espindola 780bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 781bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 782bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 78388182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 78488182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 78588182132470527e27231f09b25a885893e528c66Rafael Espindola 786737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 787a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 788d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 789d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 790d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 79194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 79221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 79321451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 79421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 7952ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 79621451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 797a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 798a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 799737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 800737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 801737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 802bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 803737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 804737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 805737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 806737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 807737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 8082ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 8092ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 810737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 811737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 81494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 8171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 8181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 8191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 820737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 8211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 822737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 823737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 824737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 825737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 826115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 8277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 829bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 830bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 831bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 832bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 833bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 8352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 8372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 8402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 8412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 8457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 8462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 847bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 8487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 8497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 8507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 851bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 852bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 853bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 854115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 8551f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 8567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 8577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 8585c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 859378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 8605c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 8615c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 8625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 8635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 8645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 8652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 8665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 8675c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 8683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 872d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 873d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 874d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 875a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 8763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 8793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 880484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 881484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 8821f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 8831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 8851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 88688182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 89194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 8941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 8951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 8962ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 8971f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 8982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 8992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 9001f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 9011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 902484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 9032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 904484291c27319668ad99cb87def000254357736fbRafael Espindola 905f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 906a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 907f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 908bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 909a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 91088182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 9111f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 9121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 9131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 9141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 9153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 916bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 917bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 918bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 9197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 9207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 9213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 9225df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 9235df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 92488182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 92588182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 92688182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 9271261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 9281261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 92988182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 93088182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 9311261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 9321261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 9331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 9341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 93588182132470527e27231f09b25a885893e528c66Rafael Espindola } 93688182132470527e27231f09b25a885893e528c66Rafael Espindola 9371261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 938a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 939a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 9401261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 941a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 9423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 943a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 944a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 945a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 946a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 947a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 948a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 949a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 9513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 9533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 9553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 9563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 959ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 9603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 962ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 963ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 964ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 9653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 9673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 9697aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky 9707aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky if (NumRegularSections > ELF::SHN_LORESERVE) 9717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky NeedsSymtabShndx = true; 9723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 9757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 9767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 9777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 9787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 9797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 9807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 9817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 9827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 9843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 9853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 9863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 988bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 9893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 990299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 991299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 992bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 993bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 994299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 995bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 9963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 9987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 9997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 10007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 10017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 10027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 10037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 10047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 10087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 10097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 10107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 10143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 10167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 10183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 1019bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 10203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 10227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 10233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1026115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1027115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 1028115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1029115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 1030115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1031115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 10323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 10343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 10373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1044115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 104800ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka 104900ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // Sort the relocation entries. Most targets just sort by r_offset, but some 105000ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // (e.g., MIPS) have additional constraints. 105100ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka TargetObjectWriter->sortRelocs(Asm, Relocs); 10523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 10543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 10553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 105612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 105712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 105812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 10598f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 10608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 106112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 1062bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1063af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 10645e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10658f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf64_Rela ERE64; 10668f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE64.setSymbolAndType(entry.Index, entry.Type); 1067af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, ERE64.r_info); 10685e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1069bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1070af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 10715e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 1072af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 10735e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 10758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 1076af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 10775e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1078bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1079af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 10805e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 10813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1084d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 1085d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 1086d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 1087d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 1088d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 1089d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 1090d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 1091d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 1092d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 1093d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 1094d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 1095d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 1096d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 1097d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1098d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1099d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 1100d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 1101d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1102115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 1103115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 11047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 11057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 11063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 11073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 11083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1109bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 11103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 111138738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 11124283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 11137be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 11143f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 111571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 111671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 111771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11184283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 11197be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 11207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 11212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 11223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 1123bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 11247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 11267be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11284283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 11297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 11302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 11317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 11327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 11337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 11363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 11373f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 11383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 11393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 11403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 11427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 11457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 114671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 114771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 114871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 11497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 11507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11517be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 11527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11534beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 115471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 11563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 11573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 11593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1160d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 1161d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 1162d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 1163d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 1164d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 1165d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 1166d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1167d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 1168d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 11693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 11703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 11713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 11723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 11733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 11743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 11753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1176d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 1177d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 11783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11792ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 1180d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 1181d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 1182d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 1183d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 1184d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 1185d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 11862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 11883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 11892ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 11903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 11922ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 11933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 11943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11957070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 11967070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 119796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 119896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 119996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 12007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 12017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 120396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 120496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 120596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 120696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 120796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 120896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 120996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 121096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 121196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 12132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 12152ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12171c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12182ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12192ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 12212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 12221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 12232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 122496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 12252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12262ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 12272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 12292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 12312ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 12347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12401c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12421f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 12432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 12452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 12477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1251115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 1252115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 1253115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 1254115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1255115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1256115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 1257c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 1258c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 1259c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1260c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 1261c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 1262c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 1263c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 1264c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1265c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 1268c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 12723f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 1274c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 1275c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1276c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 1277c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 1278c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 1279c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 12823f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 1291c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 1295c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 130098976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 130386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 130486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 130586a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 13060cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1309c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13104a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 13112ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 13122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 13132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 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 13252ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1326f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 13276db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 13286db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13296db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13302ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::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 13412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 13422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 13456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 13466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 13492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13506db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13516db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 135285f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 13536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 13567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 13577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 13587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 13597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1360263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); 13617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 13627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 13647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 13667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 13677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 13697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 1371f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(&SD, Layout); 13727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 13747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 13767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 13777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 13787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 13797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 13807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 13817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 13837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 13847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 13867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 13877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 13887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 13897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 13927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 13937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 13947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 13957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 13967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 13977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 13997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 14007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 14027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 14037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 14047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 14057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 14067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 14077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 14097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 14117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 14127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 14137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 14157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 14177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 14187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 14237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 14317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 14327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 14337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 14417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 14427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 14446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 14456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1446115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1447115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 14482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 14491f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1450bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1451bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 14527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 14537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 14557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 14567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 14587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 14597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 14607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 14617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 14627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1464bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 14658f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 14667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 14677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 14708f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 14713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 14724beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 14737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 14747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 14751d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1476bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1477bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1478bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1479a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 14803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14812ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 14827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 14837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 14847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 14857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 14862ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 14872ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1489a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1490a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 14917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 14927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 14937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 14956db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 14963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 14973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1498a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1499a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 15013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 15037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 15047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 15053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 15072ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 15082ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1509a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1511a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 15132ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 151444cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 15157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 15166db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 15173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 15183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 15207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 15217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 15237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 15247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 15257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1527263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); 1528a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1529a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 15317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 15327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 15333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1534aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky // ... and then the remaining sections ... 15357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 15367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 15383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 153978c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 154078c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 154178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 154278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 154378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 154478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 154578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 154678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 154778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 154878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 154978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 155078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 15516024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15526024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1553bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 15547bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola return new ELFObjectWriter(MOTW, OS, IsLittleEndian); 1555edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola} 1556