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 /// 273828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param Asm - The assembler. 274828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param SectionIndexMap - Maps a section to its index. 275828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param RevGroupMap - Maps a signature symbol to the group section. 276828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param NumRegularSections - Number of non-relocation sections. 2773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSymbolTable(MCAssembler &Asm, 2783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 2793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy RevGroupMap, 2803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned NumRegularSections); 2813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeIndexMap(MCAssembler &Asm, 2833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, 2873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RelMapTy &RelMap); 2883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 2903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, 2933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Create the sections that show up in the symbol table. Currently 2973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // those are the .note.GNU-stack section and the group sections. 2983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, 2993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola GroupMapTy &GroupMap, 3003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy &RevGroupMap, 3013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 3023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 3033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 3053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout); 3063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, 3083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 3093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionOffsetMapTy &SectionOffsetMap); 3113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSectionOrder(MCAssembler &Asm, 3133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<const MCSectionELF*> &Sections); 3143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 3163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Address, uint64_t Offset, 3173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Size, uint32_t Link, uint32_t Info, 3183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Alignment, uint64_t EntrySize); 3193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocationsFragment(const MCAssembler &Asm, 3213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *F, 3223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData *SD); 3233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual bool 3253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 3263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbolData &DataA, 3273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &FB, 3283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool InSet, 3293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const; 3303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 3323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSection(MCAssembler &Asm, 3333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t GroupSymbolIndex, 3353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Offset, uint64_t Size, uint64_t Alignment, 3363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 3373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 3383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola} 3393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3402ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 3412ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 3422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 3432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 3452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 3482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 3492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 3502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 3512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 3522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 3532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 354378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola case MCSymbolRefExpr::VK_GOTOFF: 3552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 3562ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 3572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 3582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 3592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 3602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 3612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 3622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 3632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 3642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 3652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 3662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 368d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 369d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 370d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 3713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 372115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteHeader(uint64_t SectionDataSize, 373115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 3743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 3753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 3763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 387bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 390115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 3935baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 394dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola Write8(TargetObjectWriter->getOSABI()); 3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 3963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 401bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 4043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 406bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 407eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4092d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 410e8526d030f2cf8cc79f2d923274944cb0fa9c4ebRafael Espindola Write32(getEFlags()); 4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 413bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 4163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 419bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 4227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 423aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky Write16(ELF::SHN_UNDEF); 4247be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 4263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 428b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky if (ShstrtabIndex >= ELF::SHN_LORESERVE) 4297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 4307be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 4323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 434115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 435115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 436115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 437115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 438115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 439115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 440115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 4417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 4427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 443af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 4447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 445af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 4467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 4477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 448af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 449af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 4503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 451bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 452af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 453af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 454af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 455af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 456af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 457af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 4583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 459af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 460af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 461af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 462af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 463af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 464af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 4653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 4663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 4692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 4702c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 4712c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 4722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 474d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 475d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 476d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 477d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 478d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 479f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach return (uint64_t)IntValue; 480d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 481d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 482d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 4832c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 4842c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4852c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4866469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4876469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFragment()) { 4886469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFlags() & ELF_Other_ThumbFunc) 4896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data)+1; 4906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola else 4916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data); 4926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 4932c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4942c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4952c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 4962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 49785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 49885f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 49988182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 50088182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 50188182132470527e27231f09b25a885893e528c66Rafael Espindola 50288182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 50388182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 50488182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 50594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 506f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 507f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 508f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 509f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 510f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 511f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 51207ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 51388182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 51488182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 51588182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 51688182132470527e27231f09b25a885893e528c66Rafael Espindola 517f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 518f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 519f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 5202ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 521f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 52207ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 52388182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 52488182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 52588182132470527e27231f09b25a885893e528c66Rafael Espindola 52683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 52783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 52883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 52983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 53083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 53107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 53288182132470527e27231f09b25a885893e528c66Rafael Espindola } 53388182132470527e27231f09b25a885893e528c66Rafael Espindola} 53488182132470527e27231f09b25a885893e528c66Rafael Espindola 535115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 536115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 537115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 538115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 539de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 540de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 54194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 542152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 5447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 5457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 5462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 5472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Visibility = MCELF::GetVisibility(OrigData); 5482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 549152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 550152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 551152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Other = Visibility; 552152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5532c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 5543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 5553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 556f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 557f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 558f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 559f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 560f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 561f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 562f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 563f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 5643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 5677be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 5687be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 5693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 5703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 571115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 572115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 573115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 574115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 575a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes const SectionIndexMapTy &SectionIndexMap) { 5763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 5793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 5813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 5837be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 5843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 5897be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 59271859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 5934beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 5944beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 595a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 5964beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 5974beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 5984beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 5994beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 600d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB || 601d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB_SHNDX) 602a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 6037be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 604a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), 605a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes false); 606a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 607a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 6083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6093565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 6103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 6113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6123223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 6133223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 6143223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 6157be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6162ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 6213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 6223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6237be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6242ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 6253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6283565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6291f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 6301f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 6312684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach const MCFragment &F, 632e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 633e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 6341f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 63594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 63694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 63794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 63894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 63994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 64094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 64194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 64294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &ASymbol; 6431f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 6441f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 64594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 64694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 64794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 64894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 64994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6507eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 6517eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 65294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 65325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 6547eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 65525958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 656e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 6577eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 65825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 65925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 66025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 66125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 66225958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 66325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 6648cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 6653729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 6663729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 6673729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6688cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 669c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 670c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 67125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 67294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 67394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 67494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 67594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6763729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6771c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 67894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 679e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 68294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 6831f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 684c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 685e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 686e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 68773ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 68873ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 6893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 69056a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 69156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 69256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 69356a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 69456a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 69556a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 69656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 69756a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 69856a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 69956a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 70056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 701127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 70256a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 70356a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 70456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 705e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 70656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 70756a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 70856a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 70956a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 71056a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 71156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 71256a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 71356a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 71456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 715a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes // Offset of the relocation in the section 71656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 71756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 71856a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 71956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 72156a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 72256a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 72356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = F->getParent()->getOrdinal() + 1; 72556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72656a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 72756a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += Layout.getSymbolOffset(&SD); 72856a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 72956a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 73256a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 73356a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 73456a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 73556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 73656a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Compensate for the addend on i386. 737bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) 73856a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 744c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 745c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 746c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola if (RelocNeedsGOT(Modifier)) 747c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola NeedsGOT = true; 7482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 7512a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 752f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola // FIXME: no tests cover this. Is adjustFixupOffset dead code? 753f3a86fb03d196994dc7923351f15d8ed9343013eRafael Espindola TargetObjectWriter->adjustFixupOffset(Fixup, RelocOffset); 75456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 755bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 756bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 757bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 758bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola if (is64Bit()) 759bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<64>(Addend)); 760bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola else 761bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<32>(Addend)); 762bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 76300ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup); 76456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 76556a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 76656a399023aba6cf1348533df04732950c43eaca7Jason W Kim 76756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 7680b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 769115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 770115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 7717b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 772ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 7733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7752ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 7762ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 7772ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 778484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 779484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 780484291c27319668ad99cb87def000254357736fbRafael Espindola 781bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 782bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 783bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 78488182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 78588182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 78688182132470527e27231f09b25a885893e528c66Rafael Espindola 787737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 788a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 789d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 790d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 791d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 79294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 79321451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 79421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 79521451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 7962ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 79721451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 798a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 799a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 800737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 801737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 802737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 803bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 804737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 805737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 806737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 807737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 808737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 8092ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 8102ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 811737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 814737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 81594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8161f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 8181f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 8191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 8201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 821737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 8221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 823737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 824737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 825737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 826737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 827115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 8287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 830bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 831bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 832bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 833bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 834bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 8362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 8382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 8412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 8422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 8457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 8467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 8472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 848bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 8497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 8507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 8517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 852bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 853bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 854bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 855115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 8561f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 8577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 8587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 8595c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 860378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 8615c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 8625c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola llvm::StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 8635c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 8645c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 8655c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 8662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 8675c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 8685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 8693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 8703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 8713565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 8723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 873d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 874d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 875d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 876a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 8793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 8803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 881484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 882484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 8831f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 8841f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8851f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 8861f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 88788182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 8883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 8893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 8913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 89294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8941f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 8951f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 8961f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 8972ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 8981f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 8992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 9002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 9011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 9021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 903484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 9042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 905484291c27319668ad99cb87def000254357736fbRafael Espindola 906f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 907a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 908f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 909bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 910a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 91188182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 9121f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 9131f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 9141f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 9151f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 9163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 917bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 918bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 919bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 9207be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 9217be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 9223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 9235df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 9245df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 92588182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 92688182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 92788182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 9281261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 9291261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 93088182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 93188182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 9321261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 9331261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 9341261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 9351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 93688182132470527e27231f09b25a885893e528c66Rafael Espindola } 93788182132470527e27231f09b25a885893e528c66Rafael Espindola 9381261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 939a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 940a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 9411261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 942a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 944a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 945a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 946a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 947a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 948a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 949a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 950a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 9513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 9523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 9553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 9563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 9573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 9593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 960ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 963ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 964ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 965ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 9707aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky 9717aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky if (NumRegularSections > ELF::SHN_LORESERVE) 9727aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky NeedsSymtabShndx = true; 9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 9767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 9777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 9787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 9797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 9807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 9817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 9827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 9837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 9853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 9863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 9873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 989bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 9903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 991299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 992299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 993bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 994bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 995299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 996bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 9973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 9997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 10007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ELF::SHT_RELA : ELF::SHT_REL, 0, 10017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 10027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola EntrySize, ""); 10037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 10047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 10057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 10097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 10107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 10117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 10153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 10193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 1020bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 10213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 10243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10253565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1027115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1028115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 1029115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1030115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 1031115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1032115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 10343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 10373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 10433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 1047115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 104900ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka 105000ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // Sort the relocation entries. Most targets just sort by r_offset, but some 105100ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // (e.g., MIPS) have additional constraints. 105200ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka TargetObjectWriter->sortRelocs(Asm, Relocs); 10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 10553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 10563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 105712203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 105812203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 105912203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 10608f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 10618f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 106212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 1063bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1064af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 106593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter if (TargetObjectWriter->isN64()) { 106693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String32(*F, entry.Index); 10675e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 106893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRSsym(entry.Type)); 106993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType3(entry.Type)); 107093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType2(entry.Type)); 107193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType(entry.Type)); 107293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 107393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter else { 107493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter struct ELF::Elf64_Rela ERE64; 107593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter ERE64.setSymbolAndType(entry.Index, entry.Type); 107693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String64(*F, ERE64.r_info); 107793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 1078bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1079af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 10805e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 1081af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 10825e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10838f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 10848f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 1085af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 10865e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1087bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1088af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 10895e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 10903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1093d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 1094d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 1095d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 1096d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 1097d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 1098d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 1099d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 1100d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 1101d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 1102d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 1103d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 1104d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 1105d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 1106d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1107d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1108d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 1109d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 1110d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1111115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 1112115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 11137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 11147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 11153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 11163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 11173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1118bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 11193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 112038738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 11214283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 11227be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 11233f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 112471859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 112571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 112671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11274283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 11287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 11297be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 11302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 1132bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 11337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 11357be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11374283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 11387be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 11392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 11407be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 11417be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 11427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 11453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 11463f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 11473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 11483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 11493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 11517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 11537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 115571859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 115671859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 115771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 11587be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 11597be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11607be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 11617be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11624beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 116371859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 11653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 11663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 11683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1169d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 1170d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 1171d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 1172d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 1173d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 1174d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 1175d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1176d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 1177d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 11783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 11793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 11803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 11833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 11843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1185d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 1186d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 11873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11882ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 1189d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 1190d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 1191d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 1192d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 1193d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 1194d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 11952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 11973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 11982ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 11993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 12012ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola F->getContents() += Name; 12023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents() += '\x00'; 12033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12047070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 12057070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 120696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 120796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 120896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 12097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 12107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 12117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 121296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 121396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 121496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 121596aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 121696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 121796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 121896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 121996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 122096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 12212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 12222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 12242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12252ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12261c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12272ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12282ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 12302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 12311f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 12322ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 123396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 12342ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 12402ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 12437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 12452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 12472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12491c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12511f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 12522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 12542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 12567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 12572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 12592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1260115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 1261115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 1262115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 1263115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1264115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1265115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 1266c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 1267c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 1268c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1269c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 1270c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 1271c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 1272c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 1273c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1274c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1275c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 1276c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 1277c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 1278c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 1279c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 12813f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 12913f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1295c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 1303c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 1304c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1305c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1306c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 130998976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 1310c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1311c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 131286a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 131386a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 131486a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 13150cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1316c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1317c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1318c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13194a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 13202ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 13212ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 13222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 13232ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1324c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1325c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1326c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1327c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1328c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1329c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1330c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1331c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1332c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1333c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13342ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1335f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 13366db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 13376db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13392ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 13406db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 13416db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13426db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 13436db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 13446db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13456db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 13466db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 13476db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 13486db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13496db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 13512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13526db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 13546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 13556db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13566db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 13582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13596db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13606db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 136185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 13626db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13636db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 13657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 13667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 13677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 13687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1369263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); 13707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 13717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 13737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 13757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 13767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteBytes(cast<MCDataFragment>(F).getContents().str()); 13787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 1380f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(&SD, Layout); 13817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 13837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 13857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 13867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 13877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 13887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 13897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 13907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 13927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 13937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 13947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 13957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 13967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 13977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 13987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 13997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 14017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 14027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 14037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 14047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 14057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 14067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 14087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 14097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 14117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 14127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 14137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 14147c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 14157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 14167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 14187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 14207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 14217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 14227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 14247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 14267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 14277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 14327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 14407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 14417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 14427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 14507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 14517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14526db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 14536db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 14546db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1455115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1456115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 14572ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 14581f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1459bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1460bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 14617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 14627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 14647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 14657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 14677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 14687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 14697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 14707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 14717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1473bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 14748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 14757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 14767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 14798f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 14803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 14814beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 14827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 14837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 14841d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1485bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1486bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1487bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1488a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 14893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 14902ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 14917c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 14927c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 14937c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 14947c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 14952ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 14962ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1498a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1499a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 15017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 15027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 15046db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 15053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 15063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1507a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1508a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 15103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 15127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 15137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 15143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 15162ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 15172ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1518a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1520a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 15222ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 152344cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 15247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 15256db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 15263565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 15273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 15297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteHeader(SectionHeaderOffset, NumSections + 1); 15307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 15327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 15337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 15347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1536263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); 1537a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1538a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 15407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 15417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 15423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1543aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky // ... and then the remaining sections ... 15447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 15457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 15473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 154878c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 154978c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 155078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 155178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 155278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 155378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 155478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 155578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 155678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 155778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 155878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 155978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 15606024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15616024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1562bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 15637bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola return new ELFObjectWriter(MOTW, OS, IsLittleEndian); 1564edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola} 1565