17394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky//===- 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 14d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/MC/MCELFObjectWriter.h" 153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/OwningPtr.h" 16d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h" 183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.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" 246eb3e87df04f8b035562d9865292c23f5b79f1a2Tim Northover#include "llvm/MC/MCELF.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/ELF.h" 33d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h" 343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 353565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 37e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef DEBUG_TYPE 38e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info" 39e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 403963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace { 413963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter { 423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola protected: 433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); 453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); 463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); 473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isInSymtab(const MCAssembler &Asm, const MCSymbolData &Data, 483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool Used, bool Renamed); 493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isLocal(const MCSymbolData &Data, bool isSignature, 503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool isUsedInReloc); 513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool IsELFMetaDataSection(const MCSectionData &SD); 523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t DataSectionSize(const MCSectionData &SD); 533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t GetSectionFileSize(const MCAsmLayout &Layout, 543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData &SD); 553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, 563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData &SD); 573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteDataSectionData(MCAssembler &Asm, 593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /*static bool isFixupKindX86RIPRel(unsigned Kind) { 633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return Kind == X86::reloc_riprel_4byte || 643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Kind == X86::reloc_riprel_4byte_movq_load; 653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }*/ 663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// ELFSymbolData - Helper struct for containing some precomputed 683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// information on symbols. 693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola struct ELFSymbolData { 703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCSymbolData *SymbolData; 713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t StringIndex; 723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t SectionIndex; 733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Support lexicographic sorting. 753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool operator<(const ELFSymbolData &RHS) const { 763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (MCELF::GetType(*SymbolData) == ELF::STT_FILE) 773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return true; 783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (MCELF::GetType(*RHS.SymbolData) == ELF::STT_FILE) 793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return false; 803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return SymbolData->getSymbol().getName() < 813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RHS.SymbolData->getSymbol().getName(); 823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// The target specific ELF writer instance. 863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola llvm::OwningPtr<MCELFObjectTargetWriter> TargetObjectWriter; 873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallPtrSet<const MCSymbol *, 16> UsedInReloc; 893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; 903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola DenseMap<const MCSymbol *, const MCSymbol *> Renames; 913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola llvm::DenseMap<const MCSectionData*, 933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFRelocationEntry> > Relocations; 943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola DenseMap<const MCSection*, uint64_t> SectionStringTableIndex; 953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @name Symbol Table Data 983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @{ 993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SmallString<256> StringTable; 1013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> LocalSymbolData; 1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> ExternalSymbolData; 1033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<ELFSymbolData> UndefinedSymbolData; 1043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool NeedsGOT; 1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool NeedsSymtabShndx; 1103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the symbol table index of the last local symbol. 1123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned LastLocalSymbolIndex; 1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .strtab section index. 1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned StringTableIndex; 1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .symtab section index. 1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned SymbolTableIndex; 1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned ShstrtabIndex; 1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *SymbolToReloc(const MCAssembler &Asm, 1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCValue &Target, 1233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &F, 1243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 1253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const; 1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // TargetObjectWriter wrappers. 1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *ExplicitRelSym(const MCAssembler &Asm, 1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCValue &Target, 1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &F, 1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const { 1333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 1343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 135aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella const MCSymbol *undefinedExplicitRelSym(const MCValue &Target, 136aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella const MCFixup &Fixup, 137aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella bool IsPCRel) const { 138dc08bfbd565ba6540be698bba551b2039661299dJack Carter return TargetObjectWriter->undefinedExplicitRelSym(Target, Fixup, 139dc08bfbd565ba6540be698bba551b2039661299dJack Carter IsPCRel); 140aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella } 1413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool is64Bit() const { return TargetObjectWriter->is64Bit(); } 1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool hasRelocationAddend() const { 1443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->hasRelocationAddend(); 1453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 1473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel, bool IsRelocWithSymbol, 1483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola int64_t Addend) const { 1493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel, 1503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola IsRelocWithSymbol, Addend); 1513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola public: 1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola ELFObjectWriter(MCELFObjectTargetWriter *MOTW, 1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola raw_ostream &_OS, bool IsLittleEndian) 1563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola : MCObjectWriter(_OS, IsLittleEndian), 1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola TargetObjectWriter(MOTW), 1587394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky NeedsGOT(false), NeedsSymtabShndx(false) { 1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual ~ELFObjectWriter(); 1623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteWord(uint64_t W) { 1643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (is64Bit()) 1653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Write64(W); 1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola Write32(W); 1683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE16(char *buf, uint16_t Value) { 1713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = char(Value >> 0); 1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[1] = char(Value >> 8); 1733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1753963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE32(char *buf, uint32_t Value) { 1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf, uint16_t(Value >> 0)); 1773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf + 2, uint16_t(Value >> 16)); 1783963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringLE64(char *buf, uint64_t Value) { 1813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf, uint32_t(Value >> 0)); 1823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf + 4, uint32_t(Value >> 32)); 1833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE16(char *buf ,uint16_t Value) { 1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = char(Value >> 8); 1873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[1] = char(Value >> 0); 1883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE32(char *buf, uint32_t Value) { 1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf, uint16_t(Value >> 16)); 1923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf + 2, uint16_t(Value >> 0)); 1933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void StringBE64(char *buf, uint64_t Value) { 1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf, uint32_t(Value >> 32)); 1973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf + 4, uint32_t(Value >> 0)); 1983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String8(MCDataFragment &F, uint8_t Value) { 2013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[1]; 2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola buf[0] = Value; 203550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F.getContents().append(&buf[0], &buf[1]); 2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String16(MCDataFragment &F, uint16_t Value) { 2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[2]; 2083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE16(buf, Value); 2103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE16(buf, Value); 212550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F.getContents().append(&buf[0], &buf[2]); 2133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String32(MCDataFragment &F, uint32_t Value) { 2163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[4]; 2173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE32(buf, Value); 2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE32(buf, Value); 221550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F.getContents().append(&buf[0], &buf[4]); 2223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void String64(MCDataFragment &F, uint64_t Value) { 2253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola char buf[8]; 2263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (isLittleEndian()) 2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringLE64(buf, Value); 2283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola StringBE64(buf, Value); 230550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F.getContents().append(&buf[0], &buf[8]); 2313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 2323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2339a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter void WriteHeader(const MCAssembler &Asm, 2349a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter uint64_t SectionDataSize, 2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned NumberOfSections); 2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbolEntry(MCDataFragment *SymtabF, 2383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *ShndxF, 2393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t name, uint8_t info, 2403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t value, uint64_t size, 2413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint8_t other, uint32_t shndx, 2423963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool Reserved); 2433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2443963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbol(MCDataFragment *SymtabF, MCDataFragment *ShndxF, 2453963d617b3709c510003ac816fb42f28539fc62bRafael Espindola ELFSymbolData &MSD, 2463963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout); 2473963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2483963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, uint32_t> SectionIndexMapTy; 2493963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSymbolTable(MCDataFragment *SymtabF, 2503963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *ShndxF, 2513963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAssembler &Asm, 2523963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 2533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap); 2543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void RecordRelocation(const MCAssembler &Asm, 2563963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 2573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment *Fragment, 2583963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFixup &Fixup, 2593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCValue Target, uint64_t &FixedValue); 2603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2613963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, 2623963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbol *S); 2633963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2643963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a group section to the signature symbol 2653963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; 2663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a signature symbol to the group section 2673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; 2683963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a section to the section with the relocations 2693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, const MCSectionELF*> RelMapTy; 2703963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Map from a section to its offset 2713963d617b3709c510003ac816fb42f28539fc62bRafael Espindola typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy; 2723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// ComputeSymbolTable - Compute the symbol table data 2743963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// 275828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param Asm - The assembler. 276828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param SectionIndexMap - Maps a section to its index. 277828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param RevGroupMap - Maps a signature symbol to the group section. 278828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param NumRegularSections - Number of non-relocation sections. 2793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSymbolTable(MCAssembler &Asm, 2803963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 2813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy RevGroupMap, 2823963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned NumRegularSections); 2833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeIndexMap(MCAssembler &Asm, 2853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2873963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2883963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateRelocationSections(MCAssembler &Asm, MCAsmLayout &Layout, 2893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RelMapTy &RelMap); 2903963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 2923963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2933963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2943963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, 2953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 2963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 2973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Create the sections that show up in the symbol table. Currently 2993963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // those are the .note.GNU-stack section and the group sections. 3003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void CreateIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, 3013963d617b3709c510003ac816fb42f28539fc62bRafael Espindola GroupMapTy &GroupMap, 3023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola RevGroupMapTy &RevGroupMap, 3033963d617b3709c510003ac816fb42f28539fc62bRafael Espindola SectionIndexMapTy &SectionIndexMap, 3043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const RelMapTy &RelMap); 3053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void ExecutePostLayoutBinding(MCAssembler &Asm, 3073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout); 3083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSectionHeader(MCAssembler &Asm, const GroupMapTy &GroupMap, 3103963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCAsmLayout &Layout, 3113963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3123963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionOffsetMapTy &SectionOffsetMap); 3133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void ComputeSectionOrder(MCAssembler &Asm, 3153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola std::vector<const MCSectionELF*> &Sections); 3163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 3183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Address, uint64_t Offset, 3193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Size, uint32_t Link, uint32_t Info, 3203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Alignment, uint64_t EntrySize); 3213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteRelocationsFragment(const MCAssembler &Asm, 3233963d617b3709c510003ac816fb42f28539fc62bRafael Espindola MCDataFragment *F, 3243963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionData *SD); 3253963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual bool 3273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 3283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSymbolData &DataA, 3293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCFragment &FB, 3303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool InSet, 3313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool IsPCRel) const; 3323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola virtual void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout); 3343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteSection(MCAssembler &Asm, 3353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 3363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t GroupSymbolIndex, 3373963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint64_t Offset, uint64_t Size, uint64_t Alignment, 3383963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 3393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 3403963d617b3709c510003ac816fb42f28539fc62bRafael Espindola} 3413963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 3422ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 3432ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 3442ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 3452ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3462ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 3472ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3482ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3492ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { 3502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin switch (Variant) { 3512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin default: 3522ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return false; 3532ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOT: 3542ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_PLT: 3552ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTPCREL: 356378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola case MCSymbolRefExpr::VK_GOTOFF: 3572ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TPOFF: 3582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSGD: 3592ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTTPOFF: 3602ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_INDNTPOFF: 3612ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_NTPOFF: 3622ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_GOTNTPOFF: 3632ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLDM: 3642ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_DTPOFF: 3652ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin case MCSymbolRefExpr::VK_TLSLD: 3662ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return true; 3672ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin } 3682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3692ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 370d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 371d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 372d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 3733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 3749a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Cartervoid ELFObjectWriter::WriteHeader(const MCAssembler &Asm, 3759a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter uint64_t SectionDataSize, 376115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar unsigned NumberOfSections) { 3773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 3783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 3793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 3803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 3813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 3823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 3833565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 3843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0x7f); // e_ident[EI_MAG0] 3863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('E'); // e_ident[EI_MAG1] 3873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('L'); // e_ident[EI_MAG2] 3883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8('F'); // e_ident[EI_MAG3] 3893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 390bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 3913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 393115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 3943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 3965baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 397dc9a8a378daf432d8dcfc178507afe149706f9a6Rafael Espindola Write8(TargetObjectWriter->getOSABI()); 3983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write8(0); // e_ident[EI_ABIVERSION] 3993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 4013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(ELF::ET_REL); // e_type 4033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 404bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(TargetObjectWriter->getEMachine()); // e_machine = target 4053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(ELF::EV_CURRENT); // e_version 4073565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 4083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 409bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola WriteWord(SectionDataSize + (is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 410eb97677764beb115c658ac559d3649c6c4068eb9Benjamin Kramer sizeof(ELF::Elf32_Ehdr))); // e_shoff = sec hdr table off in bytes 4113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4122d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 4139a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter Write32(Asm.getELFHeaderEFlags()); 4143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 416bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 4173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phentsize = prog header entry size 4193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write16(0); // e_phnum = # prog header entries = 0 4203565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 422bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 4233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 4257be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NumberOfSections >= ELF::SHN_LORESERVE) 426aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky Write16(ELF::SHN_UNDEF); 4277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(NumberOfSections); 4293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 431b3429d34b641d2b5aaa3e7df70d268904d2c039cNick Lewycky if (ShstrtabIndex >= ELF::SHN_LORESERVE) 4327be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ELF::SHN_XINDEX); 4337be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 4347be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Write16(ShstrtabIndex); 4353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 437115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolEntry(MCDataFragment *SymtabF, 438115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 439115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t name, 440115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint8_t info, uint64_t value, 441115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t size, uint8_t other, 442115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t shndx, 443115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar bool Reserved) { 4447be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (ShndxF) { 4457be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (shndx >= ELF::SHN_LORESERVE && !Reserved) 446af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, shndx); 4477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola else 448af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*ShndxF, 0); 4497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 4507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 451af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t Index = (shndx >= ELF::SHN_LORESERVE && !Reserved) ? 452af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola uint16_t(ELF::SHN_XINDEX) : shndx; 4533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 454bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 455af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 456af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 457af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 458af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 459af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, value); // st_value 460af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*SymtabF, size); // st_size 4613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 462af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, name); // st_name 463af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, value); // st_value 464af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*SymtabF, size); // st_size 465af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, info); // st_info 466af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String8(*SymtabF, other); // st_other 467af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String16(*SymtabF, Index); // st_shndx 4683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 4693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4712ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, 4722ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCAsmLayout &Layout) { 4732c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (Data.isCommon() && Data.isExternal()) 4742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return Data.getCommonAlignment(); 4752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4762c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 477d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 478d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Symbol.isAbsolute() && Symbol.isVariable()) { 479d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (const MCExpr *Value = Symbol.getVariableValue()) { 480d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky int64_t IntValue; 481d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky if (Value->EvaluateAsAbsolute(IntValue, Layout)) 482f68a26b5d8e06a85edba97702884a74673b60807Jim Grosbach return (uint64_t)IntValue; 483d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 484d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky } 485d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 4862c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola if (!Symbol.isInSection()) 4872c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4882c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4896469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola 4906469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFragment()) { 4916469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola if (Data.getFlags() & ELF_Other_ThumbFunc) 4926469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data)+1; 4936469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola else 4946469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola return Layout.getSymbolOffset(&Data); 4956469540adf63d94a876c2b623cb4ca70479647f7Rafael Espindola } 4962c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 4972c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola return 0; 4982c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 4992c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 50085f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindolavoid ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, 50185f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 50288182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 50388182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 50488182132470527e27231f09b25a885893e528c66Rafael Espindola 50588182132470527e27231f09b25a885893e528c66Rafael Espindola for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 50688182132470527e27231f09b25a885893e528c66Rafael Espindola ie = Asm.symbol_end(); it != ie; ++it) { 50788182132470527e27231f09b25a885893e528c66Rafael Espindola const MCSymbol &Alias = it->getSymbol(); 50894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &Symbol = Alias.AliasedSymbol(); 509f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola MCSymbolData &SD = Asm.getSymbolData(Symbol); 510f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 511f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 512f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola if (&Symbol == &Alias) 513f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 514f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 51507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 51688182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 51788182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 51888182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 51988182132470527e27231f09b25a885893e528c66Rafael Espindola 520f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 521f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 522f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola it->setExternal(SD.isExternal()); 5232ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, MCELF::GetBinding(SD)); 524f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 52507ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 52688182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 52788182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 52888182132470527e27231f09b25a885893e528c66Rafael Espindola 52983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 53083ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 53183ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 53283ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 53383ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 53407ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 53588182132470527e27231f09b25a885893e528c66Rafael Espindola } 53688182132470527e27231f09b25a885893e528c66Rafael Espindola} 53788182132470527e27231f09b25a885893e528c66Rafael Espindola 538115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbol(MCDataFragment *SymtabF, 539115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 540115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar ELFSymbolData &MSD, 541115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 542de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &OrigData = *MSD.SymbolData; 543de89b010b0b347cdbd1bc9553a970880a3e721bfRafael Espindola MCSymbolData &Data = 54494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola Layout.getAssembler().getSymbolData(OrigData.getSymbol().AliasedSymbol()); 545152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5467be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola bool IsReserved = Data.isCommon() || Data.getSymbol().isAbsolute() || 5477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Data.getSymbol().isVariable(); 5487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 54977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter // Binding and Type share the same byte as upper and lower nibbles 5502ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Binding = MCELF::GetBinding(OrigData); 5512ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin uint8_t Type = MCELF::GetType(Data); 552152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); 55377afbdce53aa740777486b0cc4e9df151ae65468Jack Carter 55477afbdce53aa740777486b0cc4e9df151ae65468Jack Carter // Other and Visibility share the same byte with Visability using the lower 55577afbdce53aa740777486b0cc4e9df151ae65468Jack Carter // 2 bits 55677afbdce53aa740777486b0cc4e9df151ae65468Jack Carter uint8_t Visibility = MCELF::GetVisibility(OrigData); 55777afbdce53aa740777486b0cc4e9df151ae65468Jack Carter uint8_t Other = MCELF::getOther(OrigData) << 55877afbdce53aa740777486b0cc4e9df151ae65468Jack Carter (ELF_Other_Shift - ELF_STV_Shift); 55977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter Other |= Visibility; 560152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 5612c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola uint64_t Value = SymbolValue(Data, Layout); 5623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 5633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 564f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola assert(!(Data.isCommon() && !Data.isExternal())); 565f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 566f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola const MCExpr *ESize = Data.getSize(); 567f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 568f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 569f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (!ESize->EvaluateAsAbsolute(Res, Layout)) 570f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 571f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 5723565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 5757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, MSD.StringIndex, Info, Value, 5767be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Size, Other, MSD.SectionIndex, IsReserved); 5773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 5783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 579115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, 580115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *ShndxF, 581115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAssembler &Asm, 582115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout, 583a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes const SectionIndexMapTy &SectionIndexMap) { 5843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The string table must be emitted first because we need the index 5853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the string table for all the symbol names. 5863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(StringTable.size() && "Missing string table"); 5873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5883565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // FIXME: Make sure the start of the symbol table is aligned. 5893565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry is the undefined symbol entry. 5917be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, 0, 0, 0, 0, 0, false); 5923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 5933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write the symbol table entries. 5943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex = LocalSymbolData.size() + 1; 5953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { 5963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = LocalSymbolData[i]; 5977be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 5983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 5993565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 60071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Write out a symbol table entry for each regular section. 6014beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola for (MCAssembler::const_iterator i = Asm.begin(), e = Asm.end(); i != e; 6024beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola ++i) { 603a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman const MCSectionELF &Section = 6044beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola static_cast<const MCSectionELF&>(i->getSection()); 6054beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola if (Section.getType() == ELF::SHT_RELA || 6064beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_REL || 6074beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola Section.getType() == ELF::SHT_STRTAB || 608d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB || 609d2fdb4a28560688be5cbc5b2b0c305ec7207cbd0Nick Lewycky Section.getType() == ELF::SHT_SYMTAB_SHNDX) 610a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman continue; 6117be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbolEntry(SymtabF, ShndxF, 0, ELF::STT_SECTION, 0, 0, 612a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes ELF::STV_DEFAULT, SectionIndexMap.lookup(&Section), 613a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes false); 614a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman LastLocalSymbolIndex++; 615a44fa2473a5f2a13730d44e0aea8897b5656b555Eli Friedman } 6163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { 6183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = ExternalSymbolData[i]; 6193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6203223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola assert(((Data.getFlags() & ELF_STB_Global) || 6213223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola (Data.getFlags() & ELF_STB_Weak)) && 6223223f19ff0920ffee686faba3bf74babf580e8a5Rafael Espindola "External symbol requires STB_GLOBAL or STB_WEAK flag"); 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 for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { 6293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData &MSD = UndefinedSymbolData[i]; 6303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSymbolData &Data = *MSD.SymbolData; 6317be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola WriteSymbol(SymtabF, ShndxF, MSD, Layout); 6322ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) 6333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LastLocalSymbolIndex++; 6343565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 6353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 6363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 6371f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindolaconst MCSymbol *ELFObjectWriter::SymbolToReloc(const MCAssembler &Asm, 6381f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCValue &Target, 6392684d9e3c702b2ef9fd430155d94671d12fa994fJim Grosbach const MCFragment &F, 640e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim const MCFixup &Fixup, 641e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim bool IsPCRel) const { 6421f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 64394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 64494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol *Renamed = Renames.lookup(&Symbol); 64594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbolData &SD = Asm.getSymbolData(Symbol); 64694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola 64794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (ASymbol.isUndefined()) { 64894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 64994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 650aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella return undefinedExplicitRelSym(Target, Fixup, IsPCRel); 6511f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 6521f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola 65394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (SD.isExternal()) { 65494ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 65594ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 65694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 65794ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6587eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 6597eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola const MCSectionELF &Section = 66094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola static_cast<const MCSectionELF&>(ASymbol.getSection()); 66125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola const SectionKind secKind = Section.getKind(); 6627eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 66325958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isBSS()) 664e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 6657eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 66625958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (secKind.isThreadLocal()) { 66725958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola if (Renamed) 66825958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return Renamed; 66925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola return &Symbol; 67025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 67125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 6728cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola MCSymbolRefExpr::VariantKind Kind = Target.getSymA()->getKind(); 6733729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola const MCSectionELF &Sec2 = 6743729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola static_cast<const MCSectionELF&>(F.getParent()->getSection()); 6753729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6768cecf253e45f144b9a7fd0ace85eeeeb0bebfc83Rafael Espindola if (&Sec2 != &Section && 677c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola (Kind == MCSymbolRefExpr::VK_PLT || 678c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola Kind == MCSymbolRefExpr::VK_GOTPCREL || 67925958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola Kind == MCSymbolRefExpr::VK_GOTOFF)) { 68094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 68194ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 68294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 68394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 6843729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 6851c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (Section.getFlags() & ELF::SHF_MERGE) { 68694ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Target.getConstant() == 0) 687e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 68894ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola if (Renamed) 68994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return Renamed; 69094ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola return &Symbol; 6911f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 692c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 693e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim return ExplicitRelSym(Asm, Target, F, Fixup, IsPCRel); 694e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 69573ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 69673ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 6973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 69856a399023aba6cf1348533df04732950c43eaca7Jason W Kimvoid ELFObjectWriter::RecordRelocation(const MCAssembler &Asm, 69956a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 70056a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 70156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFixup &Fixup, 70256a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCValue Target, 70356a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t &FixedValue) { 70456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Addend = 0; 70556a399023aba6cf1348533df04732950c43eaca7Jason W Kim int Index = 0; 70656a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t Value = Target.getConstant(); 70756a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol *RelocSymbol = NULL; 70856a399023aba6cf1348533df04732950c43eaca7Jason W Kim 709127a6a47bd779f0e1e5274422537cdaac3ab2ca7Rafael Espindola bool IsPCRel = isFixupKindPCRel(Asm, Fixup.getKind()); 71056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!Target.isAbsolute()) { 71156a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &Symbol = Target.getSymA()->getSymbol(); 71256a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &ASymbol = Symbol.AliasedSymbol(); 713e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim RelocSymbol = SymbolToReloc(Asm, Target, *Fragment, Fixup, IsPCRel); 71456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 71556a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 71656a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCSymbol &SymbolB = RefB->getSymbol(); 71756a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SDB = Asm.getSymbolData(SymbolB); 71856a399023aba6cf1348533df04732950c43eaca7Jason W Kim IsPCRel = true; 71956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72056a399023aba6cf1348533df04732950c43eaca7Jason W Kim // Offset of the symbol in the section 72156a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t a = Layout.getSymbolOffset(&SDB); 72256a399023aba6cf1348533df04732950c43eaca7Jason W Kim 723a0dd4cbc8739ab24535542b58c4c25e15146b44dBruno Cardoso Lopes // Offset of the relocation in the section 72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim int64_t b = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 72556a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value += b - a; 72656a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 72756a399023aba6cf1348533df04732950c43eaca7Jason W Kim 72856a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (!RelocSymbol) { 72956a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCSymbolData &SD = Asm.getSymbolData(ASymbol); 73056a399023aba6cf1348533df04732950c43eaca7Jason W Kim MCFragment *F = SD.getFragment(); 73156a399023aba6cf1348533df04732950c43eaca7Jason W Kim 732aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella if (F) { 733aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella Index = F->getParent()->getOrdinal() + 1; 734aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella // Offset of the symbol in the section 735aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella Value += Layout.getSymbolOffset(&SD); 736aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella } else { 737aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella Index = 0; 738aa71428378c1cb491ca60041d8ba7aa110bc963dAdhemerval Zanella } 73956a399023aba6cf1348533df04732950c43eaca7Jason W Kim } else { 74056a399023aba6cf1348533df04732950c43eaca7Jason W Kim if (Asm.getSymbolData(Symbol).getFlags() & ELF_Other_Weakref) 74156a399023aba6cf1348533df04732950c43eaca7Jason W Kim WeakrefUsedInReloc.insert(RelocSymbol); 74256a399023aba6cf1348533df04732950c43eaca7Jason W Kim else 74356a399023aba6cf1348533df04732950c43eaca7Jason W Kim UsedInReloc.insert(RelocSymbol); 74456a399023aba6cf1348533df04732950c43eaca7Jason W Kim Index = -1; 74556a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 74656a399023aba6cf1348533df04732950c43eaca7Jason W Kim Addend = Value; 747b21d9aebba7e45ddcbce61dd501000049cefb335Michael Liao if (hasRelocationAddend()) 74856a399023aba6cf1348533df04732950c43eaca7Jason W Kim Value = 0; 74956a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 75056a399023aba6cf1348533df04732950c43eaca7Jason W Kim 75156a399023aba6cf1348533df04732950c43eaca7Jason W Kim FixedValue = Value; 75256a399023aba6cf1348533df04732950c43eaca7Jason W Kim unsigned Type = GetRelocType(Target, Fixup, IsPCRel, 75356a399023aba6cf1348533df04732950c43eaca7Jason W Kim (RelocSymbol != 0), Addend); 754c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VariantKind Modifier = Target.isAbsolute() ? 755c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola MCSymbolRefExpr::VK_None : Target.getSymA()->getKind(); 756c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola if (RelocNeedsGOT(Modifier)) 757c677e790e5e8ff986ca84229f37751d26bf87f45Rafael Espindola NeedsGOT = true; 7582ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 75956a399023aba6cf1348533df04732950c43eaca7Jason W Kim uint64_t RelocOffset = Layout.getFragmentOffset(Fragment) + 76056a399023aba6cf1348533df04732950c43eaca7Jason W Kim Fixup.getOffset(); 7612a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 762bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (!hasRelocationAddend()) 763bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola Addend = 0; 764bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 765bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola if (is64Bit()) 766bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<64>(Addend)); 767bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola else 768bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola assert(isInt<32>(Addend)); 769bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 77000ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka ELFRelocationEntry ERE(RelocOffset, Index, Type, RelocSymbol, Addend, Fixup); 77156a399023aba6cf1348533df04732950c43eaca7Jason W Kim Relocations[Fragment->getParent()].push_back(ERE); 77256a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 77356a399023aba6cf1348533df04732950c43eaca7Jason W Kim 77456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 7750b6cbfe04cb36872255aff11a41a2b976ceba462Benjamin Krameruint64_t 776115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel DunbarELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, 777115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSymbol *S) { 7787b83c26051b0474fb5f8b73ba6e74bd4f40324baBenjamin Kramer MCSymbolData &SD = Asm.getSymbolData(*S); 779ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola return SD.getIndex(); 7803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 7813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7822ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isInSymtab(const MCAssembler &Asm, 7832ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSymbolData &Data, 7842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool Used, bool Renamed) { 785484291c27319668ad99cb87def000254357736fbRafael Espindola if (Data.getFlags() & ELF_Other_Weakref) 786484291c27319668ad99cb87def000254357736fbRafael Espindola return false; 787484291c27319668ad99cb87def000254357736fbRafael Espindola 788bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 789bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 790bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 79188182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 79288182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 79388182132470527e27231f09b25a885893e528c66Rafael Espindola 794737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 795a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 796d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") 797d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola return true; 798d179886f0595eb3564a9edfdfff79def130d89ccRafael Espindola 79994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &A = Symbol.AliasedSymbol(); 80021451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (Symbol.isVariable() && !A.isVariable() && A.isUndefined()) 80121451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola return false; 80221451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 8032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; 80421451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) 805a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 806a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 807737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (!Asm.isSymbolLinkerVisible(Symbol) && !Symbol.isUndefined()) 808737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 809737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 810bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 811737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 812737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 813737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 814737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 815737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 8162ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isSignature, 8172ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin bool isUsedInReloc) { 818737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola if (Data.isExternal()) 819737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 820737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 821737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola const MCSymbol &Symbol = Data.getSymbol(); 82294ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 8231f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8241f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (RefSymbol.isUndefined() && !RefSymbol.isVariable()) { 8251f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !isUsedInReloc) 8261f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola return true; 8271f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 828737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 8291f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 830737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 831737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 832737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 833737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 834115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeIndexMap(MCAssembler &Asm, 8357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 8367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 837bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola unsigned Index = 1; 838bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 839bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola ie = Asm.end(); it != ie; ++it) { 840bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 841bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (Section.getType() != ELF::SHT_GROUP) 8432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 8442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionIndexMap[&Section] = Index++; 8452ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 8462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 8472ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::iterator it = Asm.begin(), 8482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola ie = Asm.end(); it != ie; ++it) { 8492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 8502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 8517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP || 8527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_REL || 8537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 8542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 855bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMap[&Section] = Index++; 8567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelSection = RelMap.lookup(&Section); 8577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (RelSection) 8587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap[RelSection] = Index++; 859bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola } 860bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola} 861bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 862115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::ComputeSymbolTable(MCAssembler &Asm, 8631f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 8647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy RevGroupMap, 8657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections) { 8665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola // FIXME: Is this the correct place to do this? 867378e0ecf24cd980a4551299f0bd90725b479b401Rafael Espindola // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? 8685c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola if (NeedsGOT) { 86996f498bd9f140a98321c478f517877c4767b94faDmitri Gribenko StringRef Name = "_GLOBAL_OFFSET_TABLE_"; 8705c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); 8715c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); 8725c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola Data.setExternal(true); 8732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(Data, ELF::STB_GLOBAL); 8745c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola } 8755c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 8763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Index 0 is always the empty string. 8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringMap<uint64_t> StringIndexMap; 8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StringTable += '\x00'; 8793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 880d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // FIXME: We could optimize suffixes in strtab in the same way we 881d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola // optimize them in shstrtab. 882d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 883a0949b50dcea35c08b50542091f97275f401529dRafael Espindola // Add the data for the symbols. 8843565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (MCAssembler::symbol_iterator it = Asm.symbol_begin(), 8853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ie = Asm.symbol_end(); it != ie; ++it) { 8863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSymbol &Symbol = it->getSymbol(); 8873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 888484291c27319668ad99cb87def000254357736fbRafael Espindola bool Used = UsedInReloc.count(&Symbol); 889484291c27319668ad99cb87def000254357736fbRafael Espindola bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); 8901f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool isSignature = RevGroupMap.count(&Symbol); 8911f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (!isInSymtab(Asm, *it, 8931f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola Used || WeakrefUsed || isSignature, 89488182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 8953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 8963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 8973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 8983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MSD.SymbolData = it; 89994ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola const MCSymbol &RefSymbol = Symbol.AliasedSymbol(); 9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9011f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // Undefined symbols are global, but this is the first place we 9021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola // are able to set it. 9031f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola bool Local = isLocal(*it, isSignature, Used); 9042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin if (!Local && MCELF::GetBinding(*it) == ELF::STB_LOCAL) { 9051f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MCSymbolData &SD = Asm.getSymbolData(RefSymbol); 9062ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_GLOBAL); 9072ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(SD, ELF::STB_GLOBAL); 9081f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola } 9091f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 910484291c27319668ad99cb87def000254357736fbRafael Espindola if (RefSymbol.isUndefined() && !Used && WeakrefUsed) 9112ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin MCELF::SetBinding(*it, ELF::STB_WEAK); 912484291c27319668ad99cb87def000254357736fbRafael Espindola 913f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola if (it->isCommon()) { 914a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 915f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 916bf052ac5d1c8f21075bc675f629709c20791c5f7Rafael Espindola } else if (Symbol.isAbsolute() || RefSymbol.isVariable()) { 917a0949b50dcea35c08b50542091f97275f401529dRafael Espindola MSD.SectionIndex = ELF::SHN_ABS; 91888182132470527e27231f09b25a885893e528c66Rafael Espindola } else if (RefSymbol.isUndefined()) { 9191f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola if (isSignature && !Used) 9201f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap[&Symbol]); 9211f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola else 9221f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 9233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 924bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 925bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola static_cast<const MCSectionELF&>(RefSymbol.getSection()); 926bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 9277be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 9287be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola NeedsSymtabShndx = true; 9293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 9305df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 9315df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 93288182132470527e27231f09b25a885893e528c66Rafael Espindola // The @@@ in symbol version is replaced with @ in undefined symbols and 93388182132470527e27231f09b25a885893e528c66Rafael Espindola // @@ in defined ones. 93488182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 9351261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer SmallString<32> Buf; 9361261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer 93788182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = Name.find("@@@"); 93888182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos != StringRef::npos) { 9391261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(0, Pos); 9401261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 9411261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Buf += Name.substr(Pos + Skip); 9421261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer Name = Buf; 94388182132470527e27231f09b25a885893e528c66Rafael Espindola } 94488182132470527e27231f09b25a885893e528c66Rafael Espindola 9451261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer uint64_t &Entry = StringIndexMap[Name]; 946a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (!Entry) { 947a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola Entry = StringTable.size(); 9481261a2ff99299946952013f284615a06afa3dc50Benjamin Kramer StringTable += Name; 949a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola StringTable += '\x00'; 9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 951a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola MSD.StringIndex = Entry; 952a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola if (MSD.SectionIndex == ELF::SHN_UNDEF) 953a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola UndefinedSymbolData.push_back(MSD); 954a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else if (Local) 955a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 956a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 957a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 9583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 9593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 9613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 9623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 9633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); 9643565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 9663565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 967ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola unsigned Index = 1; 9683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) 9693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming LocalSymbolData[i].SymbolData->setIndex(Index++); 970ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 971ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola Index += NumRegularSections; 972ab4a7afe98fcd86418bd1672f880b7d3672f4543Rafael Espindola 9733565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) 9743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ExternalSymbolData[i].SymbolData->setIndex(Index++); 9753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) 9763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming UndefinedSymbolData[i].SymbolData->setIndex(Index++); 9777aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky 9787394c5a37ce5c0fb153cfc8ec5f32822d5bf8668Nick Lewycky if (Index >= ELF::SHN_LORESERVE) 9797aabcb1fc0a94becb437134747a63ff686c0661fNick Lewycky NeedsSymtabShndx = true; 9803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 9813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::CreateRelocationSections(MCAssembler &Asm, 9837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola MCAsmLayout &Layout, 9847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMapTy &RelMap) { 9857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 9867c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 9877c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 9887c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Relocations[&SD].empty()) 9897c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 9907c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 9913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 9923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const MCSectionELF &Section = 9933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming static_cast<const MCSectionELF&>(SD.getSection()); 9943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming const StringRef SectionName = Section.getSectionName(); 996bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 9973565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming RelaSectionName += SectionName; 998299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer 999299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer unsigned EntrySize; 1000bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1001bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 1002299fbe3a5aad8f08c52c488a9b28df70c7595e0dBenjamin Kramer else 1003bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 10043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1005f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover unsigned Flags = 0; 1006f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover StringRef Group = ""; 1007f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover if (Section.getFlags() & ELF::SHF_GROUP) { 1008f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover Flags = ELF::SHF_GROUP; 1009f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover Group = Section.getGroup()->getName(); 1010f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover } 1011f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover 10127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = 10137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Ctx.getELFSection(RelaSectionName, hasRelocationAddend() ? 1014f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover ELF::SHT_RELA : ELF::SHT_REL, Flags, 10157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionKind::getReadOnly(), 1016f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover EntrySize, Group); 10177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap[&Section] = RelaSection; 10187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Asm.getOrCreateSectionData(*RelaSection); 10197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 10207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 10217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 10227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout, 10237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 10247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 10257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 10267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = *it; 10277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 10287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF&>(SD.getSection()); 10293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *RelaSection = RelMap.lookup(&Section); 10317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (!RelaSection) 10327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola continue; 10333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &RelaSD = Asm.getOrCreateSectionData(*RelaSection); 1034bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola RelaSD.setAlignment(is64Bit() ? 8 : 4); 10353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10363565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F = new MCDataFragment(&RelaSD); 10377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocationsFragment(Asm, F, &*it); 10383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1041115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1042115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 1043115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1044115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 1045115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1046115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Name); // sh_name: index into string table 10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Type); // sh_type 10493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 10503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 10513565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 10523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 10533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Link); // sh_link 10543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming Write32(Info); // sh_info 10553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 10563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 10573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10583565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1059115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, 1060115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCDataFragment *F, 1061115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionData *SD) { 10623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; 106300ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka 106400ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // Sort the relocation entries. Most targets just sort by r_offset, but some 106500ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka // (e.g., MIPS) have additional constraints. 106600ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka TargetObjectWriter->sortRelocs(Asm, Relocs); 10673565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10683565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 10693565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFRelocationEntry entry = Relocs[e - i - 1]; 10703565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 107112203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola if (!entry.Index) 107212203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola ; 107312203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola else if (entry.Index < 0) 10748f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola entry.Index = getSymbolIndexInSymbolTable(Asm, entry.Symbol); 10758f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola else 107612203cc7c3f7392d62556946a10b2f10205ea63dRafael Espindola entry.Index += LocalSymbolData.size(); 1077bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 1078af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_offset); 107993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter if (TargetObjectWriter->isN64()) { 108093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String32(*F, entry.Index); 10815e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 108293ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRSsym(entry.Type)); 108393ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType3(entry.Type)); 108493ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType2(entry.Type)); 108593ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String8(*F, TargetObjectWriter->getRType(entry.Type)); 108693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 108793ee286e8d949147f8df7f093c9bd8529a99102dJack Carter else { 108893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter struct ELF::Elf64_Rela ERE64; 108993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter ERE64.setSymbolAndType(entry.Index, entry.Type); 109093ee286e8d949147f8df7f093c9bd8529a99102dJack Carter String64(*F, ERE64.r_info); 109193ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 1092bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1093af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String64(*F, entry.r_addend); 10945e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 1095af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_offset); 10965e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10978f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 10988f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola ERE32.setSymbolAndType(entry.Index, entry.Type); 1099af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, ERE32.r_info); 11005e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1101bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 1102af3d38f70ebba9fec0048c2540dbdf0168d280d2Rafael Espindola String32(*F, entry.r_addend); 11035e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 11043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 11053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 11063565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1107d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindolastatic int compareBySuffix(const void *a, const void *b) { 1108d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secA = *static_cast<const MCSectionELF* const *>(a); 1109d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF *secB = *static_cast<const MCSectionELF* const *>(b); 1110d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameA = secA->getSectionName(); 1111d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const StringRef &NameB = secB->getSectionName(); 1112d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeA = NameA.size(); 1113d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned sizeB = NameB.size(); 1114d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const unsigned len = std::min(sizeA, sizeB); 1115d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int i = 0; i < len; ++i) { 1116d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char ca = NameA[sizeA - i - 1]; 1117d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola char cb = NameB[sizeB - i - 1]; 1118d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (ca != cb) 1119d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return cb - ca; 1120d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1121d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1122d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola return sizeB - sizeA; 1123d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola} 1124d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 1125115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::CreateMetadataSections(MCAssembler &Asm, 1126115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar MCAsmLayout &Layout, 11277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 11287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 11293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCContext &Ctx = Asm.getContext(); 11303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCDataFragment *F; 11313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1132bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 11333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 113438738bf1a847292003a5495f17e42a75d1274bf7Rafael Espindola // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. 11354283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *ShstrtabSection = 11367be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0, 11373f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 113871859c640f6a36251aca223fd503c58dc314e296Rafael Espindola MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); 113971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola ShstrtabSD.setAlignment(1); 114071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11414283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabSection = 11427be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, 11437be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SectionKind::getReadOnly(), 11442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola EntrySize, ""); 11453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); 1146bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola SymtabSD.setAlignment(is64Bit() ? 8 : 4); 11477be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11487be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCSectionData *SymtabShndxSD = NULL; 11497be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 11507be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11514283f4b81e8c1cbf5c7a7b51e949e109ae25ff8cRafael Espindola const MCSectionELF *SymtabShndxSection = 11527be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola Ctx.getELFSection(".symtab_shndx", ELF::SHT_SYMTAB_SHNDX, 0, 11532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionKind::getReadOnly(), 4, ""); 11547be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD = &Asm.getOrCreateSectionData(*SymtabShndxSection); 11557be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola SymtabShndxSD->setAlignment(4); 11567be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11573565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF *StrtabSection; 11593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0, 11603f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 11613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); 11623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming StrtabSD.setAlignment(1); 11633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex = SectionIndexMap.lookup(ShstrtabSection); 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SymbolTableIndex = SectionIndexMap.lookup(SymtabSection); 11687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola StringTableIndex = SectionIndexMap.lookup(StrtabSection); 116971859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 117071859c640f6a36251aca223fd503c58dc314e296Rafael Espindola // Symbol table 117171859c640f6a36251aca223fd503c58dc314e296Rafael Espindola F = new MCDataFragment(&SymtabSD); 11727be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola MCDataFragment *ShndxF = NULL; 11737be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola if (NeedsSymtabShndx) { 11747be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola ShndxF = new MCDataFragment(SymtabShndxSD); 11757be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola } 11764beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola WriteSymbolTable(F, ShndxF, Asm, Layout, SectionIndexMap); 117771859c640f6a36251aca223fd503c58dc314e296Rafael Espindola 11783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&StrtabSD); 11793565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F->getContents().append(StringTable.begin(), StringTable.end()); 11803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 11813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming F = new MCDataFragment(&ShstrtabSD); 11823565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1183d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola std::vector<const MCSectionELF*> Sections; 1184d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), 1185d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola ie = Asm.end(); it != ie; ++it) { 1186d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = 1187d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 1188d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola Sections.push_back(&Section); 1189d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 1190d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola array_pod_sort(Sections.begin(), Sections.end(), compareBySuffix); 1191d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola 11923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Section header string table. 11933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 11943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // The first entry of a string table holds a null character so skip 11953565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // section 0. 11963565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Index = 1; 1197550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F->getContents().push_back('\x00'); 11983565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1199d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola for (unsigned int I = 0, E = Sections.size(); I != E; ++I) { 1200d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola const MCSectionELF &Section = *Sections[I]; 12013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12022ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola StringRef Name = Section.getSectionName(); 1203d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (I != 0) { 1204d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola StringRef PreviousName = Sections[I - 1]->getSectionName(); 1205d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola if (PreviousName.endswith(Name)) { 1206d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola SectionStringTableIndex[&Section] = Index - Name.size() - 1; 1207d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola continue; 1208d5321da8d22d60f528397a05dc10db4185fcb680Rafael Espindola } 12092ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the index into the string table so we can write it 12113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // into the sh_name field of the section header table. 12122ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionStringTableIndex[&Section] = Index; 12133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12142ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Index += Name.size() + 1; 1215550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F->getContents().append(Name.begin(), Name.end()); 1216550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky F->getContents().push_back('\x00'); 12173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12187070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola} 12197070387f08f7dc797b554ed8013cba9f8b74121aRafael Espindola 122096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindolavoid ELFObjectWriter::CreateIndexedSections(MCAssembler &Asm, 122196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCAsmLayout &Layout, 122296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola GroupMapTy &GroupMap, 12237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMapTy &RevGroupMap, 12247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMapTy &SectionIndexMap, 12257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const RelMapTy &RelMap) { 122696aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola // Create the .note.GNU-stack section if needed. 122796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola MCContext &Ctx = Asm.getContext(); 122896aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola if (Asm.getNoExecStack()) { 122996aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola const MCSectionELF *GnuStackSection = 123096aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Ctx.getELFSection(".note.GNU-stack", ELF::SHT_PROGBITS, 0, 123196aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola SectionKind::getReadOnly()); 123296aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Asm.getOrCreateSectionData(*GnuStackSection); 123396aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola } 123496aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola 12352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Build the groups 12362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola it != ie; ++it) { 12382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12401c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12412ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12422ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12432ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSymbol *SignatureSymbol = Section.getGroup(); 12442ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Asm.getOrCreateSymbolData(*SignatureSymbol); 12451f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; 12462ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola if (!Group) { 124796aa78c8c5ef1a5f268539c9edc86569b436d573Rafael Espindola Group = Ctx.CreateELFGroupSection(); 12482ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12492ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola Data.setAlignment(4); 12502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola String32(*F, ELF::GRP_COMDAT); 12522ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12532ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMap[Group] = SignatureSymbol; 12542ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12552ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 12567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeIndexMap(Asm, SectionIndexMap, RelMap); 12577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12582ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // Add sections to the groups 12592ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); 12607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola it != ie; ++it) { 12612ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = 12622ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola static_cast<const MCSectionELF&>(it->getSection()); 12631c13026e8f94bd332c0979baa9c777da99d48736Rafael Espindola if (!(Section.getFlags() & ELF::SHF_GROUP)) 12642ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola continue; 12651f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; 12662ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCSectionData &Data = Asm.getOrCreateSectionData(*Group); 12672ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola // FIXME: we could use the previous fragment 12682ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola MCDataFragment *F = new MCDataFragment(&Data); 12697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned Index = SectionIndexMap.lookup(&Section); 12707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola String32(*F, Index); 12712ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola } 12722ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 12732ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1274115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSection(MCAssembler &Asm, 1275115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const SectionIndexMapTy &SectionIndexMap, 1276115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t GroupSymbolIndex, 1277115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1278115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1279115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCSectionELF &Section) { 1280c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 1281c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 1282c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1283c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 1284c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 1285c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionStringTableIndex[&Section]; 1286c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = 0; 1287c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1288c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1289c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 1290c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 1291c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *SymtabSection; 1292c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola const MCSectionELF *InfoSection; 1293c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola SymtabSection = Asm.getContext().getELFSection(".symtab", ELF::SHT_SYMTAB, 1294c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 0, 12953f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1296c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SectionIndexMap.lookup(SymtabSection); 1297c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 1298c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1299c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Remove ".rel" and ".rela" prefixes. 1300c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola unsigned SecNameLen = (Section.getType() == ELF::SHT_REL) ? 4 : 5; 1301c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola StringRef SectionName = Section.getSectionName().substr(SecNameLen); 1302c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1303c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola InfoSection = Asm.getContext().getELFSection(SectionName, 1304c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola ELF::SHT_PROGBITS, 0, 13053f2d13c98eb04962bf6fcfdcc6f62789bc820d79Rafael Espindola SectionKind::getReadOnly()); 1306c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 1307c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1308c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1309c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1310c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 1311c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 1312c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 1313c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 1314c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1315c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1316c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 1317c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 1318c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1319c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1320c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_PROGBITS: 1321c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_STRTAB: 1322c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NOBITS: 132398976610d2c8067efe04042f17486a4b6c746b31Rafael Espindola case ELF::SHT_NOTE: 1324c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_NULL: 1325c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_ARM_ATTRIBUTES: 132686a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_INIT_ARRAY: 132786a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_FINI_ARRAY: 132886a97f2e4d0cde5e992f52ac287da0de687e0110Jason W Kim case ELF::SHT_PREINIT_ARRAY: 13290cf5e3d51dd455a174a8f00cfa6b63c11e535434Rafael Espindola case ELF::SHT_X86_64_UNWIND: 1330c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter case ELF::SHT_MIPS_REGINFO: 1331c91cbb9b0c90a480299cc7deaef166d47a61d9dfJack Carter case ELF::SHT_MIPS_OPTIONS: 1332c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola // Nothing to do. 1333c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1334c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13354a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 13362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 13372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 13382ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 13392ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 1340c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola default: 1341c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(0 && "FIXME: sh_type value not supported!"); 1342c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1343c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1344c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1345b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && 1346b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien Section.getType() == ELF::SHT_ARM_EXIDX) { 1347b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien StringRef SecName(Section.getSectionName()); 1348b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien if (SecName == ".ARM.exidx") { 1349b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien sh_link = SectionIndexMap.lookup( 1350b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien Asm.getContext().getELFSection(".text", 1351b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien ELF::SHT_PROGBITS, 1352b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 1353b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien SectionKind::getText())); 1354b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien } else if (SecName.startswith(".ARM.exidx")) { 1355b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien sh_link = SectionIndexMap.lookup( 1356b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien Asm.getContext().getELFSection(SecName.substr(sizeof(".ARM.exidx") - 1), 1357b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien ELF::SHT_PROGBITS, 1358b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien ELF::SHF_EXECINSTR | ELF::SHF_ALLOC, 1359b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien SectionKind::getText())); 1360b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien } 1361b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien } 1362b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien 1363c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola WriteSecHdrEntry(SectionStringTableIndex[&Section], Section.getType(), 1364c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Section.getFlags(), 0, Offset, Size, sh_link, sh_info, 1365c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola Alignment, Section.getEntrySize()); 1366c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola} 1367c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 13682ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { 1369f8803fe4177739f9a6900198f601808eb27934d9Rafael Espindola return SD.getOrdinal() == ~UINT32_C(0) && 13706db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola !SD.getSection().isVirtualSection(); 13716db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13726db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13732ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { 13746db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola uint64_t Ret = 0; 13756db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 13766db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola ++i) { 13776db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola const MCFragment &F = *i; 13786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola assert(F.getKind() == MCFragment::FT_Data); 13796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola Ret += cast<MCDataFragment>(F).getContents().size(); 13806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 13816db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Ret; 13826db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13836db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13842ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionFileSize(const MCAsmLayout &Layout, 13852ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 13886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return Layout.getSectionFileSize(&SD); 13896db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13906db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13912ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinuint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, 13922ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCSectionData &SD) { 13936db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola if (IsELFMetaDataSection(SD)) 13946db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola return DataSectionSize(SD); 139585f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola return Layout.getSectionAddressSize(&SD); 13966db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 13976db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 13987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteDataSectionData(MCAssembler &Asm, 13997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 14007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section) { 14017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1403263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); 14047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteZeros(Padding); 14057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (IsELFMetaDataSection(SD)) { 14077c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; 14087c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ++i) { 14097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCFragment &F = *i; 14107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola assert(F.getKind() == MCFragment::FT_Data); 1411550f0ade457c3b042fa099ecff2c022c7ab58b1eEli Bendersky WriteBytes(cast<MCDataFragment>(F).getContents()); 14127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } else { 1414f77d5b14af6b92403b93f7ed249f9023e99028ccJim Grosbach Asm.writeSectionData(&SD, Layout); 14157c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 14177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14187c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::WriteSectionHeader(MCAssembler &Asm, 14197c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const GroupMapTy &GroupMap, 14207c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCAsmLayout &Layout, 14217c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionIndexMapTy &SectionIndexMap, 14227c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const SectionOffsetMapTy &SectionOffsetMap) { 14237c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumSections = Asm.size() + 1; 14247c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> Sections; 14267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.resize(NumSections - 1); 14277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (SectionIndexMapTy::const_iterator i= 14297c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap.begin(), e = SectionIndexMap.end(); i != e; ++i) { 14307c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const std::pair<const MCSectionELF*, uint32_t> &p = *i; 14317c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections[p.second - 1] = p.first; 14327c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14337c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 14357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 14367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola NumSections >= ELF::SHN_LORESERVE ? NumSections : 0; 14377c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t FirstSectionLink = 14387c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; 14397c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); 14407c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14417c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumSections - 1; ++i) { 14427c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = *Sections[i]; 14437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 14447c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 14457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP) 14467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 14477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 14487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, 14497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupMap.lookup(&Section)); 14507c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14517c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t Size = GetSectionAddressSize(Layout, SD); 14527c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSection(Asm, SectionIndexMap, GroupSymbolIndex, 14547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap.lookup(&Section), Size, 14557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SD.getAlignment(), Section); 14567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14577c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 14587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindolavoid ELFObjectWriter::ComputeSectionOrder(MCAssembler &Asm, 14607c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola std::vector<const MCSectionELF*> &Sections) { 14617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14637c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_GROUP) 14667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14727c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() != ELF::SHT_GROUP && 14747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_REL && 14757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() != ELF::SHT_RELA) 14767c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14777c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola } 14787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (MCAssembler::iterator it = Asm.begin(), 14807c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ie = Asm.end(); it != ie; ++it) { 14817c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const MCSectionELF &Section = 14827c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola static_cast<const MCSectionELF &>(it->getSection()); 14837c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola if (Section.getType() == ELF::SHT_REL || 14847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Section.getType() == ELF::SHT_RELA) 14857c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola Sections.push_back(&Section); 14866db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 14876db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 14886db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 1489115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteObject(MCAssembler &Asm, 1490115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 14912ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola GroupMapTy GroupMap; 14921f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1493bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1494bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 14957c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumUserSections = Asm.size(); 14967c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 14977c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola DenseMap<const MCSectionELF*, const MCSectionELF*> RelMap; 14987c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateRelocationSections(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 14997c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15007c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumUserAndRelocSections = Asm.size(); 15017c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola CreateIndexedSections(Asm, const_cast<MCAsmLayout&>(Layout), GroupMap, 15027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RevGroupMap, SectionIndexMap, RelMap); 15037c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned AllSections = Asm.size(); 15047c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned NumIndexedSections = AllSections - NumUserAndRelocSections; 15057c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15067c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumRegularSections = NumUserSections + NumIndexedSections; 1507bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 15088f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola // Compute symbol table information. 15097c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSymbolTable(Asm, SectionIndexMap, RevGroupMap, NumRegularSections); 15107c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15117c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15127c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteRelocations(Asm, const_cast<MCAsmLayout&>(Layout), RelMap); 15138f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 15143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming CreateMetadataSections(const_cast<MCAssembler&>(Asm), 15154beee3d06bfebe3f3382893fcebc71d1aa3f290eRafael Espindola const_cast<MCAsmLayout&>(Layout), 15167c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionIndexMap, 15177c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola RelMap); 15181d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 1519bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 1520bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola uint64_t HeaderSize = is64Bit() ? sizeof(ELF::Elf64_Ehdr) : 1521bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola sizeof(ELF::Elf32_Ehdr); 1522a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer uint64_t FileOff = HeaderSize; 15233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15242ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola std::vector<const MCSectionELF*> Sections; 15257c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola ComputeSectionOrder(Asm, Sections); 15267c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola unsigned NumSections = Sections.size(); 15277c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMapTy SectionOffsetMap; 15287c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) { 15292ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 15302ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 15313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1532a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1533a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15347c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Remember the offset into the file for this section. 15357c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap[&Section] = FileOff; 15367c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Get the size of the section in the output file (including padding). 15386db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 15393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 15403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1541a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer FileOff = RoundUpToAlignment(FileOff, NaturalAlignment); 1542a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15437c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola const unsigned SectionHeaderOffset = FileOff - HeaderSize; 15443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15457c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t SectionHeaderEntrySize = is64Bit() ? 15467c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr); 15477c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff += (NumSections + 1) * SectionHeaderEntrySize; 15483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) { 15502ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionELF &Section = *Sections[i]; 15512ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola const MCSectionData &SD = Asm.getOrCreateSectionData(Section); 1552a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15537c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola FileOff = RoundUpToAlignment(FileOff, SD.getAlignment()); 1554a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 15562ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola SectionOffsetMap[&Section] = FileOff; 155744cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 15587c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Get the size of the section in the output file (including padding). 15596db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola FileOff += GetSectionFileSize(Layout, SD); 15603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 15613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 15627c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Write out the ELF header ... 15639a7bf438b50fed2c77f0e2bc835defa5b4728f82Jack Carter WriteHeader(Asm, SectionHeaderOffset, NumSections + 1); 15647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 15657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the regular sections ... 15667c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // + because of .shstrtab 15677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = 0; i < NumRegularSections + 1; ++i) 15687c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15697c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1570263109d822314305822796a2cc05e98304793051Benjamin Kramer uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); 1571a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer WriteZeros(Padding); 1572a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 15737c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 15747c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteSectionHeader(Asm, GroupMap, Layout, SectionIndexMap, 15757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola SectionOffsetMap); 15763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1577aaae3f6bc1b7ab3475d7399915a887b42f6365bcNick Lewycky // ... and then the remaining sections ... 15787c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola for (unsigned i = NumRegularSections + 1; i < NumSections; ++i) 15797c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola WriteDataSectionData(Asm, Layout, *Sections[i]); 15803565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 15813565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 158278c1e1781cf36dd19988047eac8f664873d35237Eli Friedmanbool 158378c1e1781cf36dd19988047eac8f664873d35237Eli FriedmanELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 158478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCSymbolData &DataA, 158578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman const MCFragment &FB, 158678c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool InSet, 158778c1e1781cf36dd19988047eac8f664873d35237Eli Friedman bool IsPCRel) const { 158878c1e1781cf36dd19988047eac8f664873d35237Eli Friedman if (DataA.getFlags() & ELF_STB_Weak) 158978c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return false; 159078c1e1781cf36dd19988047eac8f664873d35237Eli Friedman return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( 159178c1e1781cf36dd19988047eac8f664873d35237Eli Friedman Asm, DataA, FB,InSet, IsPCRel); 159278c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 159378c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 15946024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 15956024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael Espindola raw_ostream &OS, 1596bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 15977bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola return new ELFObjectWriter(MOTW, OS, IsLittleEndian); 1598edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola} 1599