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" 15d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/ADT/STLExtras.h" 163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallPtrSet.h" 173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/ADT/SmallString.h" 183565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/ADT/StringMap.h" 1978c10eeaa57d1c6c4b7781d3c0bcb0cfbbc43b5cEvan Cheng#include "llvm/MC/MCAsmBackend.h" 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/MC/MCAsmInfo.h" 213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCAsmLayout.h" 223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola#include "llvm/MC/MCAssembler.h" 233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCContext.h" 243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCExpr.h" 25f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCFixupKindInfo.h" 26f1d0f7781e766df878bec4e7977fa3204374f394Craig Topper#include "llvm/MC/MCObjectWriter.h" 273565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCSectionELF.h" 286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar#include "llvm/MC/MCSymbolELF.h" 293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/MC/MCValue.h" 30c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines#include "llvm/MC/StringTableBuilder.h" 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/Compression.h" 323565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/Debug.h" 333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include "llvm/Support/ELF.h" 34ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/Support/Endian.h" 35d04a8d4b33ff316ca4cf961e06c9e312eff8e64fChandler Carruth#include "llvm/Support/ErrorHandling.h" 36cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar#include "llvm/Support/StringSaver.h" 373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming#include <vector> 383565a06ebf44a193a8b333cbeff2ee154298d450Matt Flemingusing namespace llvm; 393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 40e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#undef DEBUG_TYPE 41e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim#define DEBUG_TYPE "reloc-info" 42e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 433963d617b3709c510003ac816fb42f28539fc62bRafael Espindolanamespace { 4436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinestypedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy; 4636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarclass ELFObjectWriter; 486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 4936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesclass SymbolTableWriter { 506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ELFObjectWriter &EWriter; 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool Is64Bit; 5236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // indexes we are going to write to .symtab_shndx. 546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<uint32_t> ShndxIndexes; 5536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The numbel of symbols written so far. 5736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned NumWritten; 5836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 5936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void createSymtabShndx(); 6036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar template <typename T> void write(T Value); 6236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinespublic: 646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit); 6536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, 6736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t other, uint32_t shndx, bool Reserved); 686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; } 7036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}; 7136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 723963d617b3709c510003ac816fb42f28539fc62bRafael Espindolaclass ELFObjectWriter : public MCObjectWriter { 733963d617b3709c510003ac816fb42f28539fc62bRafael Espindola static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); 746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout); 756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol, 763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool Used, bool Renamed); 773963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 780c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar /// Helper struct for containing some precomputed information on symbols. 793963d617b3709c510003ac816fb42f28539fc62bRafael Espindola struct ELFSymbolData { 806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolELF *Symbol; 813963d617b3709c510003ac816fb42f28539fc62bRafael Espindola uint32_t SectionIndex; 82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef Name; 833963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 843963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // Support lexicographic sorting. 853963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool operator<(const ELFSymbolData &RHS) const { 866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned LHSType = Symbol->getType(); 876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned RHSType = RHS.Symbol->getType(); 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) 8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return false; 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) 9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return true; 9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION) 9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines return SectionIndex < RHS.SectionIndex; 94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return Name < RHS.Name; 953963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 973963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 983963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// The target specific ELF writer instance. 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter; 1003963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames; 1023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Relocations; 1053963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1063963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 1073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @name Symbol Table Data 1083963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @{ 1093963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 110cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar BumpPtrAllocator Alloc; 111cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StringSaver VersionSymSaver{Alloc}; 112cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StringTableBuilder StrTabBuilder{StringTableBuilder::ELF}; 1133963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// @} 1153963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1163963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the symbol table index of the last local symbol. 1173963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned LastLocalSymbolIndex; 1183963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .strtab section index. 1193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned StringTableIndex; 1203963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // This holds the .symtab section index. 1213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned SymbolTableIndex; 1223963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Sections in the order they are to be output in the section table. 1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<const MCSectionELF *> SectionTable; 1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned addToSectionTable(const MCSectionELF *Sec); 1263963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola // TargetObjectWriter wrappers. 1283963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool is64Bit() const { return TargetObjectWriter->is64Bit(); } 1293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola bool hasRelocationAddend() const { 1303963d617b3709c510003ac816fb42f28539fc62bRafael Espindola return TargetObjectWriter->hasRelocationAddend(); 1313963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1323963d617b3709c510003ac816fb42f28539fc62bRafael Espindola unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsPCRel) const { 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel); 1353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void align(unsigned Alignment); 1386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1393963d617b3709c510003ac816fb42f28539fc62bRafael Espindola public: 1400c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, 14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool IsLittleEndian) 1426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {} 1433963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar void reset() override { 1454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Renames.clear(); 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Relocations.clear(); 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar StrTabBuilder.clear(); 1486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionTable.clear(); 1494c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar MCObjectWriter::reset(); 1504c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1514c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1520c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar ~ELFObjectWriter() override; 1533963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1543963d617b3709c510003ac816fb42f28539fc62bRafael Espindola void WriteWord(uint64_t W) { 1553963d617b3709c510003ac816fb42f28539fc62bRafael Espindola if (is64Bit()) 1566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write64(W); 1573963d617b3709c510003ac816fb42f28539fc62bRafael Espindola else 1586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(W); 1593963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1603963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar template <typename T> void write(T Val) { 1626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (IsLittleEndian) 163cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar support::endian::Writer<support::little>(getStream()).write(Val); 1646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else 165cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar support::endian::Writer<support::big>(getStream()).write(Val); 1663963d617b3709c510003ac816fb42f28539fc62bRafael Espindola } 1673963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeHeader(const MCAssembler &Asm); 1693963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex, 1716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ELFSymbolData &MSD, const MCAsmLayout &Layout); 1723963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Start and end offset of each section 1746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>> 1756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsetsTy; 1763963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool shouldRelocateWithSymbol(const MCAssembler &Asm, 178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbolRefExpr *RefA, 1796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbol *Sym, uint64_t C, 18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Type) const; 18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, 18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCFragment *Fragment, const MCFixup &Fixup, 18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCValue Target, bool &IsPCRel, 18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t &FixedValue) override; 1863963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 1876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Map from a signature symbol to the group section index 1886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy; 1893963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// Compute the symbol table data 1913963d617b3709c510003ac816fb42f28539fc62bRafael Espindola /// 192828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param Asm - The assembler. 193828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param SectionIndexMap - Maps a section to its index. 194828ea3849a8c799651a6c33cdc5d92a6923bf95aRafael Espindola /// \param RevGroupMap - Maps a signature symbol to the group section. 19536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, 1963963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const SectionIndexMapTy &SectionIndexMap, 1976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const RevGroupMapTy &RevGroupMap, 1986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsetsTy &SectionOffsets); 1996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 2006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *createRelocationSection(MCContext &Ctx, 2016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF &Sec); 2023963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF *createStringTable(MCContext &Ctx); 2043963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void executePostLayoutBinding(MCAssembler &Asm, 2066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAsmLayout &Layout) override; 2073963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeSectionHeader(const MCAsmLayout &Layout, 2096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const SectionIndexMapTy &SectionIndexMap, 2106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const SectionOffsetsTy &SectionOffsets); 211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 2126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeSectionData(const MCAssembler &Asm, MCSection &Sec, 2136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAsmLayout &Layout); 2143963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, 2166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t Address, uint64_t Offset, uint64_t Size, 2176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t Link, uint32_t Info, uint64_t Alignment, 2186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t EntrySize); 2193963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec); 2213963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, 2236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbol &SymA, 2246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCFragment &FB, 2256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool InSet, 2266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool IsPCRel) const override; 2273963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool isWeak(const MCSymbol &Sym) const override; 2293963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; 2316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void writeSection(const SectionIndexMapTy &SectionIndexMap, 2326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size, 2333963d617b3709c510003ac816fb42f28539fc62bRafael Espindola const MCSectionELF &Section); 2343963d617b3709c510003ac816fb42f28539fc62bRafael Espindola }; 2353963d617b3709c510003ac816fb42f28539fc62bRafael Espindola} 2363963d617b3709c510003ac816fb42f28539fc62bRafael Espindola 2376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::align(unsigned Alignment) { 238cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment); 2396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar WriteZeros(Padding); 2406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar} 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarunsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) { 2436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionTable.push_back(Sec); 2446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StrTabBuilder.add(Sec->getSectionName()); 2456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return SectionTable.size(); 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SymbolTableWriter::createSymtabShndx() { 2496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!ShndxIndexes.empty()) 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ShndxIndexes.resize(NumWritten); 25336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 25436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainartemplate <typename T> void SymbolTableWriter::write(T Value) { 2566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar EWriter.write(Value); 25736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 25836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarSymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit) 2606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {} 26136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t size, uint8_t other, 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint32_t shndx, bool Reserved) { 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LargeIndex) 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines createSymtabShndx(); 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!ShndxIndexes.empty()) { 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (LargeIndex) 2726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ShndxIndexes.push_back(shndx); 27336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 2746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ShndxIndexes.push_back(0); 27536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; 27836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Is64Bit) { 2806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(name); // st_name 2816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(info); // st_info 2826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(other); // st_other 2836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(Index); // st_shndx 2846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(value); // st_value 2856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(size); // st_size 28636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(name); // st_name 2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(value)); // st_value 2896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(size)); // st_size 2906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(info); // st_info 2916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(other); // st_other 2926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(Index); // st_shndx 29336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 29436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++NumWritten; 29636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 29736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 2982ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödinbool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { 2992ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin const MCFixupKindInfo &FKI = 3002ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); 3012ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 3022ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; 3032ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin} 3042ddfd95d40e07f5fdf179a16e15a5d7c131837d8Jan Sjödin 305d3443e99e43945fdb0742177da06a32fa225740dJason W KimELFObjectWriter::~ELFObjectWriter() 306d3443e99e43945fdb0742177da06a32fa225740dJason W Kim{} 307d3443e99e43945fdb0742177da06a32fa225740dJason W Kim 3083565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming// Emit the ELF header. 3096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeHeader(const MCAssembler &Asm) { 3103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ELF Header 3113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---------- 3123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 3133565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Note 3143565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // ---- 3153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // emitWord method behaves differently for ELF32 and ELF64, writing 3163565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // 4 bytes in the former and 8 in the latter. 3173565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3] 3193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] 3213565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3223565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ident[EI_DATA] 3236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); 3243565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] 3265baf79edc067a4b17d024cc10324ac88c17e3e43Roman Divacky // e_ident[EI_OSABI] 3276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write8(TargetObjectWriter->getOSABI()); 3286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write8(0); // e_ident[EI_ABIVERSION] 3293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); 3313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(ELF::ET_REL); // e_type 3333565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(TargetObjectWriter->getEMachine()); // e_machine = target 3353565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(ELF::EV_CURRENT); // e_version 3373565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_entry, no entry point in .o file 3383565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(0); // e_phoff, no program header for .o 3390c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar WriteWord(0); // e_shoff = sec hdr table off in bytes 3403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3412d7a53aec2c6426eba9e5dd6462cc9e86432b410Jason W Kim // e_flags = whatever the target wants 3426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(Asm.getELFHeaderEFlags()); 3433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_ehsize = ELF header size 3456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); 3463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(0); // e_phentsize = prog header entry size 3486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(0); // e_phnum = # prog header entries = 0 3493565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shentsize = Section header entry size 3516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); 3523565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3533565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shnum = # of section header ents 3546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(0); 3553565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3563565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // e_shstrndx = Section # of '.shstrtab' 3576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(StringTableIndex < ELF::SHN_LORESERVE); 3586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write16(StringTableIndex); 3593565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 3603565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 3616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainaruint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym, 36236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCAsmLayout &Layout) { 3636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Sym.isCommon() && Sym.isExternal()) 3646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Sym.getCommonAlignment(); 3653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 366dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines uint64_t Res; 3676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!Layout.getSymbolOffset(Sym, Res)) 368dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return 0; 369d149186e156fdd44e3cca988949cf3e5e6940863Roman Divacky 3706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Layout.getAssembler().isThumbFunc(&Sym)) 37136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Res |= 1; 3722c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 37336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Res; 3742c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola} 3752c6ec31df6c6c45ad735892eedab78612ac2847bRafael Espindola 3766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm, 37785f2ecc697a8ca6c8cf08093054cbbb9d2060ccfRafael Espindola const MCAsmLayout &Layout) { 37888182132470527e27231f09b25a885893e528c66Rafael Espindola // The presence of symbol versions causes undefined symbols and 37988182132470527e27231f09b25a885893e528c66Rafael Espindola // versions declared with @@@ to be renamed. 38088182132470527e27231f09b25a885893e528c66Rafael Espindola 3816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MCSymbol &A : Asm.symbols()) { 3826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Alias = cast<MCSymbolELF>(A); 383f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Not an alias. 384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Alias.isVariable()) 385dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines continue; 386dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue()); 387dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Ref) 388f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola continue; 3896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol()); 390f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 39107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef AliasName = Alias.getName(); 39288182132470527e27231f09b25a885893e528c66Rafael Espindola size_t Pos = AliasName.find('@'); 39388182132470527e27231f09b25a885893e528c66Rafael Espindola if (Pos == StringRef::npos) 39488182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 39588182132470527e27231f09b25a885893e528c66Rafael Espindola 396f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // Aliases defined with .symvar copy the binding from the symbol they alias. 397f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola // This is the first place we are able to copy this information. 3986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Alias.setExternal(Symbol.isExternal()); 3996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Alias.setBinding(Symbol.getBinding()); 400f571f9a8fe764d5010970e45203415cb00eab739Rafael Espindola 40107ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer StringRef Rest = AliasName.substr(Pos); 40288182132470527e27231f09b25a885893e528c66Rafael Espindola if (!Symbol.isUndefined() && !Rest.startswith("@@@")) 40388182132470527e27231f09b25a885893e528c66Rafael Espindola continue; 40488182132470527e27231f09b25a885893e528c66Rafael Espindola 40583ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola // FIXME: produce a better error message. 40683ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola if (Symbol.isUndefined() && Rest.startswith("@@") && 40783ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola !Rest.startswith("@@@")) 40883ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola report_fatal_error("A @@ version cannot be undefined"); 40983ff4d2b0d6133d48055a27fe25c5d241bca7e9bRafael Espindola 41007ee63283cc2b9a4d6c98ecd30d1b721fe3cb29aBenjamin Kramer Renames.insert(std::make_pair(&Symbol, &Alias)); 41188182132470527e27231f09b25a885893e528c66Rafael Espindola } 41288182132470527e27231f09b25a885893e528c66Rafael Espindola} 41388182132470527e27231f09b25a885893e528c66Rafael Espindola 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesstatic uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint8_t Type = newType; 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 41736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Propagation rules: 41836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // IFUNC > FUNC > OBJECT > NOTYPE 41936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // TLS_OBJECT > OBJECT > NOTYPE 42036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // 42136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // dont let the new type degrade the old type 42236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (origType) { 42336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 42436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 42536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STT_GNU_IFUNC: 42636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || 42736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) 42836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type = ELF::STT_GNU_IFUNC; 42936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STT_FUNC: 43136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 43236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type == ELF::STT_TLS) 43336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type = ELF::STT_FUNC; 43436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 43536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STT_OBJECT: 43636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type == ELF::STT_NOTYPE) 43736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type = ELF::STT_OBJECT; 43836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 43936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STT_TLS: 44036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || 44136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) 44236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Type = ELF::STT_TLS; 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 44436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 44536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 44636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return Type; 44736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 44836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 4496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer, 4506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t StringIndex, ELFSymbolData &MSD, 451115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 4526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol); 4536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolELF *Base = 4546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol)); 455152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // This has to be in sync with when computeSymbolTable uses SHN_ABS or 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // SHN_COMMON. 4586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool IsReserved = !Base || Symbol.isCommon(); 4597be2c33193aeada8c0ff3555ea54b930f204132aRafael Espindola 46077afbdce53aa740777486b0cc4e9df151ae65468Jack Carter // Binding and Type share the same byte as upper and lower nibbles 4616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint8_t Binding = Symbol.getBinding(); 4626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint8_t Type = Symbol.getType(); 46336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Base) { 4646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Type = mergeTypeForSet(Type, Base->getType()); 46536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 4666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint8_t Info = (Binding << 4) | Type; 46777afbdce53aa740777486b0cc4e9df151ae65468Jack Carter 46872580780a98cb8b0019b7ec4ed88e3f3328b9969Joerg Sonnenberger // Other and Visibility share the same byte with Visibility using the lower 46977afbdce53aa740777486b0cc4e9df151ae65468Jack Carter // 2 bits 4706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint8_t Visibility = Symbol.getVisibility(); 4716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint8_t Other = Symbol.getOther() | Visibility; 472152c1061e0b4ad379eec5fa38ee0091fc11ff936Rafael Espindola 4736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t Value = SymbolValue(*MSD.Symbol, Layout); 4743565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming uint64_t Size = 0; 4753565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCExpr *ESize = MSD.Symbol->getSize(); 47736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!ESize && Base) 4786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ESize = Base->getSize(); 479f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola 480f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola if (ESize) { 481f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola int64_t Res; 4820c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (!ESize->evaluateKnownAbsolute(Res, Layout)) 483f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola report_fatal_error("Size expression must be absolute."); 484f01212489be07e261a0302744f878a54a39f05a5Rafael Espindola Size = Res; 4853565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 4863565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 4873565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Write out the symbol table entry 4886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex, 4896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar IsReserved); 4903565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 4913565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 49236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// It is always valid to create a relocation with a symbol. It is preferable 49336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// to use a relocation with a section if that is possible. Using the section 49436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines// allows us to omit some local symbols from the symbol table. 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, 496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const MCSymbolRefExpr *RefA, 4976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbol *S, uint64_t C, 49836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Type) const { 4996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto *Sym = cast_or_null<MCSymbolELF>(S); 50036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // A PCRel relocation to an absolute value has no symbol (or section). We 50136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // represent that with a relocation to a null section. 50236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!RefA) 50336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 5047eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); 50636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (Kind) { 50736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 50836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 50936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The .odp creation emits a relocation against the symbol ".TOC." which 51036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // create a R_PPC64_TOC relocation. However the relocation symbol name 51136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // in final object creation should be NULL, since the symbol does not 51236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // really exist, it is just the reference to TOC base for the current 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // object file. Since the symbol is undefined, returning false results 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // in a relocation with a null section which is the desired result. 51536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_PPC_TOCBASE: 51636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 5177eae36b38b874f417fa191fc1cfec22c100f164dRafael Espindola 51836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // These VariantKind cause the relocation to refer to something other than 51936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the symbol itself, like a linker generated table. Since the address of 52036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // symbol is not relevant, we cannot replace the symbol with the 52136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // section and patch the difference in the addend. 52236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_GOT: 52336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_PLT: 52436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_GOTPCREL: 52536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_Mips_GOT: 52636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_PPC_GOT_LO: 52736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_PPC_GOT_HI: 52836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case MCSymbolRefExpr::VK_PPC_GOT_HA: 52936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 53025958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola } 53125958730dffe0a16f9c251a1fa317799b8419a1fRafael Espindola 53236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // An undefined symbol is not in any section, so the relocation has to point 53336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // to the symbol itself. 5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(Sym && "Expected a symbol"); 5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Sym->isUndefined()) 53636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 5373729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 5386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Binding = Sym->getBinding(); 53936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch(Binding) { 54036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines default: 54136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines llvm_unreachable("Invalid Binding"); 54236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STB_LOCAL: 54336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 54436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STB_WEAK: 54536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If the symbol is weak, it might be overridden by a symbol in another 54636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // file. The relocation has to point to the symbol so that the linker 54736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // can update it. 54836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 54936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case ELF::STB_GLOBAL: 55036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Global ELF symbols can be preempted by the dynamic linker. The relocation 55136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // has to point to the symbol for a reason analogous to the STB_WEAK case. 55236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 55394ed5fca3f5ab5acb74e70b8393b837131e7110cRafael Espindola } 5543729d0052bda365d04fee900c6f3d09460f1e108Rafael Espindola 55536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If a relocation points to a mergeable section, we have to be careful. 55636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If the offset is zero, a relocation with the section will encode the 55736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // same information. With a non-zero offset, the situation is different. 55836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // For example, a relocation can point 42 bytes past the end of a string. 55936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If we change such a relocation to use the section, the linker would think 56036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // that it pointed to another string and subtracting 42 at runtime will 56136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // produce the wrong value. 5626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar auto &Sec = cast<MCSectionELF>(Sym->getSection()); 56336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Flags = Sec.getFlags(); 56436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Flags & ELF::SHF_MERGE) { 56536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (C != 0) 56636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 56736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 56836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // It looks like gold has a bug (http://sourceware.org/PR16794) and can 56936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // only handle section relocations to mergeable sections if using RELA. 57036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!hasRelocationAddend()) 57136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 5721f52dfe69ee7d0a49a6bfe6dfec6aeb8e416e313Rafael Espindola } 573c97f80efc80030c7544a9903c79d2dccd197a0ffRafael Espindola 57436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Most TLS relocations use a got, so they need the symbol. Even those that 57537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // are just an offset (@tpoff), require a symbol in gold versions before 57637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed 57737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // http://sourceware.org/PR16773. 57836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Flags & ELF::SHF_TLS) 57936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 580e964d1192a82cf8c1371a7440667de67595d6d35Jason W Kim 581dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // If the symbol is a thumb function the final relocation must set the lowest 582dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // bit. With a symbol that is done by just having the symbol have that bit 583dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // set, so we would lose the bit if we relocated with the section. 584dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // FIXME: We could use the section but add the bit to the relocation value. 5856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Asm.isThumbFunc(Sym)) 586dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 587dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 5886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type)) 58936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return true; 59036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 59173ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola} 59273ffea47d20bc9f559b4ce0c60166ee504073832Rafael Espindola 5936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// True if the assembler knows nothing about the final value of the symbol. 5946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// This doesn't cover the comdat issues, since in those cases the assembler 5956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar// can at least know that all symbols in the section will move together. 5966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarstatic bool isWeak(const MCSymbolELF &Sym) { 5976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Sym.getType() == ELF::STT_GNU_IFUNC) 5986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 599dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 6006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar switch (Sym.getBinding()) { 6016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar default: 6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm_unreachable("Unknown binding"); 6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ELF::STB_LOCAL: 6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ELF::STB_GLOBAL: 6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ELF::STB_WEAK: 6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar case ELF::STB_GNU_UNIQUE: 6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 6124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::recordRelocation(MCAssembler &Asm, 61456a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCAsmLayout &Layout, 61556a399023aba6cf1348533df04732950c43eaca7Jason W Kim const MCFragment *Fragment, 616ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const MCFixup &Fixup, MCValue Target, 617ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool &IsPCRel, uint64_t &FixedValue) { 6186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent()); 61936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t C = Target.getConstant(); 62036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); 62136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 62236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const MCSymbolRefExpr *RefB = Target.getSymB()) { 62336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(RefB->getKind() == MCSymbolRefExpr::VK_None && 62436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Should not have constructed this"); 62536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 62636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Let A, B and C being the components of Target and R be the location of 62736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). 62836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // If it is pcrel, we want to compute (A - B + C - R). 62936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 63036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // In general, ELF has no relocations for -B. It can only represent (A + C) 63136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // or (A + C - R). If B = R + K and the relocation is not pcrel, we can 63236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // replace B to implement it: (A - R - K + C) 633cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (IsPCRel) { 634cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Asm.getContext().reportError( 63536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixup.getLoc(), 63636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "No relocation available to represent this relative expression"); 637cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return; 638cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 63936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 6406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol()); 64136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 642cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (SymB.isUndefined()) { 643cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Asm.getContext().reportError( 64436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixup.getLoc(), 64536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Twine("symbol '") + SymB.getName() + 64636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "' can not be undefined in a subtraction expression"); 647cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return; 648cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 64936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 65036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!SymB.isAbsolute() && "Should have been folded"); 65136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSection &SecB = SymB.getSection(); 652cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (&SecB != &FixupSection) { 653cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Asm.getContext().reportError( 65436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Fixup.getLoc(), "Cannot represent a difference across sections"); 655cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return; 656cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 65736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 658cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (::isWeak(SymB)) { 659cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Asm.getContext().reportError( 6604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); 661cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar return; 662cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 6634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 6646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t SymBOffset = Layout.getSymbolOffset(SymB); 66536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t K = SymBOffset - FixupOffset; 66636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines IsPCRel = true; 66736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines C -= K; 66836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 66956a399023aba6cf1348533df04732950c43eaca7Jason W Kim 67036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We either rejected the fixup or folded B into C at this point. 67136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSymbolRefExpr *RefA = Target.getSymA(); 6726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr; 6736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 6746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool ViaWeakRef = false; 6756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (SymA && SymA->isVariable()) { 6766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCExpr *Expr = SymA->getVariableValue(); 6776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) { 6786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) { 6796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymA = cast<MCSymbolELF>(&Inner->getSymbol()); 6806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ViaWeakRef = true; 6816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 6836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 68456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 68536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Type = GetRelocType(Target, Fixup, IsPCRel); 6866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type); 68736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) 6886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar C += Layout.getSymbolOffset(*SymA); 68936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t Addend = 0; 69136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (hasRelocationAddend()) { 69236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Addend = C; 69336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines C = 0; 69456a399023aba6cf1348533df04732950c43eaca7Jason W Kim } 69556a399023aba6cf1348533df04732950c43eaca7Jason W Kim 69636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FixedValue = C; 69736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 69836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (!RelocateWithSymbol) { 69936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCSection *SecA = 70036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; 70137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines auto *ELFSec = cast_or_null<MCSectionELF>(SecA); 7026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto *SectionSymbol = 7036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ELFSec ? cast<MCSymbolELF>(ELFSec->getBeginSymbol()) : nullptr; 7046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (SectionSymbol) 7056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionSymbol->setUsedInReloc(); 70637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); 7076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Relocations[&FixupSection].push_back(Rec); 70836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 70936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 7102a66cea1b82b82c7bf19e232aed741331377ad30Roman Divacky 71136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (SymA) { 7126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (const MCSymbolELF *R = Renames.lookup(SymA)) 71336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines SymA = R; 714bbf9c4a14edbdbc384a452377d60bad8f6d8a78eRafael Espindola 7156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ViaWeakRef) 7166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymA->setIsWeakrefUsedInReloc(); 71736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines else 7186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymA->setUsedInReloc(); 71936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 72036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend); 7216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Relocations[&FixupSection].push_back(Rec); 72236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return; 72356a399023aba6cf1348533df04732950c43eaca7Jason W Kim} 72456a399023aba6cf1348533df04732950c43eaca7Jason W Kim 725dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, 7266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolELF &Symbol, bool Used, 727dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines bool Renamed) { 72836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Symbol.isVariable()) { 72936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MCExpr *Expr = Symbol.getVariableValue(); 73036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { 73136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) 73236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return false; 73336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 73436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 735484291c27319668ad99cb87def000254357736fbRafael Espindola 736bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Used) 737bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola return true; 738bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola 73988182132470527e27231f09b25a885893e528c66Rafael Espindola if (Renamed) 74088182132470527e27231f09b25a885893e528c66Rafael Espindola return false; 74188182132470527e27231f09b25a885893e528c66Rafael Espindola 7426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Symbol.isVariable() && Symbol.isUndefined()) { 7436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // FIXME: this is here just to diagnose the case of a var = commmon_sym. 7446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Layout.getBaseSymbol(Symbol); 7456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 746dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 74721451e533f4c46cdb38d338cfed26cece1d7be54Rafael Espindola 7486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Symbol.isUndefined() && !Symbol.isBindingSet()) 749a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola return false; 750a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola 751bd70118f163f94a4d77eb036e6f83dd0bfcb6268Rafael Espindola if (Symbol.isTemporary()) 752737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 753737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 7546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Symbol.getType() == ELF::STT_SECTION) 755737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return false; 756737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 757737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola return true; 758737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola} 759737cd213e359c2862253c3a1ee443419566e90b9Rafael Espindola 7600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainarvoid ELFObjectWriter::computeSymbolTable( 7610c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar MCAssembler &Asm, const MCAsmLayout &Layout, 7626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap, 7636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsetsTy &SectionOffsets) { 7646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCContext &Ctx = Asm.getContext(); 7656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymbolTableWriter Writer(*this, is64Bit()); 7665c77c16f311d702a315547c0eb32b7a34a9d55c8Rafael Espindola 7676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Symbol table 7686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; 7696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *SymtabSection = 7706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, ""); 7716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymtabSection->setAlignment(is64Bit() ? 8 : 4); 7726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymbolTableIndex = addToSectionTable(SymtabSection); 7736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar align(SymtabSection->getAlignment()); 775cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecStart = getStream().tell(); 7763565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 7776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // The first entry is the undefined symbol entry. 7786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); 7791f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 7806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<ELFSymbolData> LocalSymbolData; 7816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<ELFSymbolData> ExternalSymbolData; 7826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Add the data for the symbols. 7846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool HasLargeSectionIndex = false; 7856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MCSymbol &S : Asm.symbols()) { 7866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Symbol = cast<MCSymbolELF>(S); 7876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool Used = Symbol.isUsedInReloc(); 7886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool WeakrefUsed = Symbol.isWeakrefUsedInReloc(); 7896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool isSignature = Symbol.isSignature(); 7906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 7916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature, 79288182132470527e27231f09b25a885893e528c66Rafael Espindola Renames.count(&Symbol))) 7933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming continue; 7943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 795cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Symbol.isTemporary() && Symbol.isUndefined()) { 796cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Ctx.reportError(SMLoc(), "Undefined temporary symbol"); 797cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar continue; 798cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 799cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 8003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming ELFSymbolData MSD; 8016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MSD.Symbol = cast<MCSymbolELF>(&Symbol); 8021f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola 8036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool Local = Symbol.getBinding() == ELF::STB_LOCAL; 804cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar assert(Local || !Symbol.isTemporary()); 805cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 8066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Symbol.isAbsolute()) { 80736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MSD.SectionIndex = ELF::SHN_ABS; 8086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (Symbol.isCommon()) { 809a0949b50dcea35c08b50542091f97275f401529dRafael Espindola assert(!Local); 810f7c10a3cff61c70efe8e405d9bdc5386e8e3fc0aRafael Espindola MSD.SectionIndex = ELF::SHN_COMMON; 8116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else if (Symbol.isUndefined()) { 8126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (isSignature && !Used) { 8136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MSD.SectionIndex = RevGroupMap.lookup(&Symbol); 8146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 8156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar HasLargeSectionIndex = true; 8166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } else { 8171f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola MSD.SectionIndex = ELF::SHN_UNDEF; 8186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 8193565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } else { 820bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola const MCSectionELF &Section = 8216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar static_cast<const MCSectionELF &>(Symbol.getSection()); 822bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola MSD.SectionIndex = SectionIndexMap.lookup(&Section); 8233565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming assert(MSD.SectionIndex && "Invalid section index!"); 8246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (MSD.SectionIndex >= ELF::SHN_LORESERVE) 8256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar HasLargeSectionIndex = true; 8265df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola } 8275df0b65e8f5ef55f0b515a0b24879f5d117d6042Rafael Espindola 828ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The @@@ in symbol version is replaced with @ in undefined symbols and @@ 829ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // in defined ones. 830ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 831ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // FIXME: All name handling should be done before we get to the writer, 832ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // including dealing with GNU-style version suffixes. Fixing this isn't 833ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // trivial. 834ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 835ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We thus have to be careful to not perform the symbol version replacement 836ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // blindly: 837ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 838ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // The ELF format is used on Windows by the MCJIT engine. Thus, on 839ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Windows, the ELFObjectWriter can encounter symbols mangled using the MS 840ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC 841ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // C++ name mangling can legally have "@@@" as a sub-string. In that case, 842ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // the EFLObjectWriter should not interpret the "@@@" sub-string as 843ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // specifying GNU-style symbol versioning. The ELFObjectWriter therefore 844ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // checks for the MSVC C++ name mangling prefix which is either "?", "@?", 845ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // "__imp_?" or "__imp_@?". 846ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // 847ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // It would have been interesting to perform the MS mangling prefix check 848ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // only when the target triple is of the form *-pc-windows-elf. But, it 849ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // seems that this information is not easily accessible from the 850ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // ELFObjectWriter. 85188182132470527e27231f09b25a885893e528c66Rafael Espindola StringRef Name = Symbol.getName(); 852cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallString<32> Buf; 853ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Name.startswith("?") && !Name.startswith("@?") && 854ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) { 855ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // This symbol isn't following the MSVC C++ name mangling convention. We 856ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // can thus safely interpret the @@@ in symbol names as specifying symbol 857ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // versioning. 858ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines size_t Pos = Name.find("@@@"); 859ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (Pos != StringRef::npos) { 860ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Buf += Name.substr(0, Pos); 861ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; 862ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Buf += Name.substr(Pos + Skip); 863cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Name = VersionSymSaver.save(Buf.c_str()); 864ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 86588182132470527e27231f09b25a885893e528c66Rafael Espindola } 86637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 86737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // Sections have their own string table 868cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar if (Symbol.getType() != ELF::STT_SECTION) { 869cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar MSD.Name = Name; 870cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StrTabBuilder.add(Name); 871cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar } 87288182132470527e27231f09b25a885893e528c66Rafael Espindola 8736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Local) 874a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola LocalSymbolData.push_back(MSD); 875a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola else 876a6866969ba3b12901b412bb53ba8c61a9991b8adRafael Espindola ExternalSymbolData.push_back(MSD); 8773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 8783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 879cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // This holds the .symtab_shndx section index. 880cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar unsigned SymtabShndxSectionIndex = 0; 881cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 8826948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (HasLargeSectionIndex) { 8836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *SymtabShndxSection = 8846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); 8856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection); 8866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SymtabShndxSection->setAlignment(4); 8876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 888dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 8896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<std::string> FileNames = Asm.getFileNames(); 8906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const std::string &Name : FileNames) 8916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StrTabBuilder.add(Name); 892dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 893cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar StrTabBuilder.finalize(); 894dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 8956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const std::string &Name : FileNames) 8966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Writer.writeSymbol(StrTabBuilder.getOffset(Name), 8976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT, 8986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ELF::SHN_ABS, true); 899dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 9003565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Symbols are required to be in lexicographic order. 9013565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); 9023565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); 9033565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9043565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Set the symbol indices. Local symbols must come before all other 9053565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // symbols with non-local bindings. 9066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Index = FileNames.size() + 1; 9076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (ELFSymbolData &MSD : LocalSymbolData) { 9096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION 9106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ? 0 9116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : StrTabBuilder.getOffset(MSD.Name); 9126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MSD.Symbol->setIndex(Index++); 9136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeSymbol(Writer, StringIndex, MSD, Layout); 9146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 9156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Write the symbol table entries. 9176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar LastLocalSymbolIndex = Index; 9186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (ELFSymbolData &MSD : ExternalSymbolData) { 9206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name); 9216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MSD.Symbol->setIndex(Index++); 9226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeSymbol(Writer, StringIndex, MSD, Layout); 9236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL); 9246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 9256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 926cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecEnd = getStream().tell(); 9276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd); 9286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 9296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes(); 9306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (ShndxIndexes.empty()) { 9316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(SymtabShndxSectionIndex == 0); 9326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 9336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 9346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(SymtabShndxSectionIndex != 0); 9356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 936cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SecStart = getStream().tell(); 9376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF *SymtabShndxSection = 9386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionTable[SymtabShndxSectionIndex - 1]; 9396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (uint32_t Index : ShndxIndexes) 9406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(Index); 941cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SecEnd = getStream().tell(); 9426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd); 9433565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 9443565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarMCSectionELF * 9466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarELFObjectWriter::createRelocationSection(MCContext &Ctx, 9476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF &Sec) { 9486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Relocations[&Sec].empty()) 949ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 9503565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 9516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const StringRef SectionName = Sec.getSectionName(); 952ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; 953ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RelaSectionName += SectionName; 9543565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 955ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned EntrySize; 956ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (hasRelocationAddend()) 957ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); 958ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines else 959ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); 960f5b1c5043de4d485ff17d8b2aad709c63a5a9ff3Tim Northover 961ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned Flags = 0; 9626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Sec.getFlags() & ELF::SHF_GROUP) 963ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Flags = ELF::SHF_GROUP; 964ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 9656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *RelaSection = Ctx.createELFRelSection( 966ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL, 9676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Flags, EntrySize, Sec.getGroup(), &Sec); 9686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar RelaSection->setAlignment(is64Bit() ? 8 : 4); 9696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return RelaSection; 9707c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 9717c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 972dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// Include the debug info compression header: 973dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// "ZLIB" followed by 8 bytes representing the uncompressed size of the section, 974dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines// useful for consumers to preallocate a buffer to decompress into. 975dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesstatic bool 976dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesprependCompressionHeader(uint64_t Size, 977dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines SmallVectorImpl<char> &CompressedContents) { 9784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const StringRef Magic = "ZLIB"; 979dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) 980dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return false; 981dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (sys::IsLittleEndianHost) 982c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines sys::swapByteOrder(Size); 983dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CompressedContents.insert(CompressedContents.begin(), 984dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Magic.size() + sizeof(Size), 0); 985dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); 986dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::copy(reinterpret_cast<char *>(&Size), 987dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines reinterpret_cast<char *>(&Size + 1), 988dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CompressedContents.begin() + Magic.size()); 989dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return true; 990dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 991dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 9926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec, 9936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAsmLayout &Layout) { 9946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 9956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StringRef SectionName = Section.getSectionName(); 996dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 9976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Compressing debug_frame requires handling alignment fragments which is 9986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow 9996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // for writing to arbitrary buffers) for little benefit. 10006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!Asm.getContext().getAsmInfo()->compressDebugSections() || 10016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar !SectionName.startswith(".debug_") || SectionName == ".debug_frame") { 10026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm.writeSectionData(&Section, Layout); 10036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 10046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 10056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1006cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar SmallVector<char, 128> UncompressedData; 1007cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar raw_svector_ostream VecOS(UncompressedData); 1008cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar raw_pwrite_stream &OldStream = getStream(); 1009cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar setStream(VecOS); 1010cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar Asm.writeSectionData(&Section, Layout); 1011cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar setStream(OldStream); 1012dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 10136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SmallVector<char, 128> CompressedContents; 1014dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines zlib::Status Success = zlib::compress( 1015dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StringRef(UncompressedData.data(), UncompressedData.size()), 1016dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CompressedContents); 10176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Success != zlib::StatusOK) { 1018cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream() << UncompressedData; 10196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return; 1020dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 1021dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 10226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) { 1023cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream() << UncompressedData; 1024dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 10256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 1026dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines Asm.getContext().renameELFSection(&Section, 1027dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines (".z" + SectionName.drop_front(1)).str()); 1028cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream() << CompressedContents; 10293565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10303565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1031115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbarvoid ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, 1032115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Flags, uint64_t Address, 1033115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Offset, uint64_t Size, 1034115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint32_t Link, uint32_t Info, 1035115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t Alignment, 1036115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar uint64_t EntrySize) { 10376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(Name); // sh_name: index into string table 10386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(Type); // sh_type 10393565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Flags); // sh_flags 10403565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Address); // sh_addr 10413565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Offset); // sh_offset 10423565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Size); // sh_size 10436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(Link); // sh_link 10446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write32(Info); // sh_info 10453565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(Alignment); // sh_addralign 10463565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming WriteWord(EntrySize); // sh_entsize 10473565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10483565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeRelocations(const MCAssembler &Asm, 10506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF &Sec) { 10516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec]; 105200ca888cccd130dd3ebcfc02cf2b9187b54d116eAkira Hatanaka 1053cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // We record relocations by pushing to the end of a vector. Reverse the vector 1054cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // to get the relocations in the order they were created. 1055cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // In most cases that is not important, but it can be for special sections 1056cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // (.eh_frame) or specific relocations (TLS optimizations on SystemZ). 1057cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar std::reverse(Relocs.begin(), Relocs.end()); 1058cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar 1059cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar // Sort the relocation entries. MIPS needs this. 10600c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar TargetObjectWriter->sortRelocs(Asm, Relocs); 10613565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10623565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { 106336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const ELFRelocationEntry &Entry = Relocs[e - i - 1]; 10646948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0; 10653565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1066bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (is64Bit()) { 10676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(Entry.Offset); 106893ee286e8d949147f8df7f093c9bd8529a99102dJack Carter if (TargetObjectWriter->isN64()) { 10696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(Index)); 10705e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(TargetObjectWriter->getRSsym(Entry.Type)); 10726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(TargetObjectWriter->getRType3(Entry.Type)); 10736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(TargetObjectWriter->getRType2(Entry.Type)); 10746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(TargetObjectWriter->getRType(Entry.Type)); 107536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } else { 107693ee286e8d949147f8df7f093c9bd8529a99102dJack Carter struct ELF::Elf64_Rela ERE64; 107736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ERE64.setSymbolAndType(Index, Entry.Type); 10786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(ERE64.r_info); 107993ee286e8d949147f8df7f093c9bd8529a99102dJack Carter } 1080bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 10816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(Entry.Addend); 10825e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } else { 10836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(Entry.Offset)); 10845e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 10858f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola struct ELF::Elf32_Rela ERE32; 108636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ERE32.setSymbolAndType(Index, Entry.Type); 10876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(ERE32.r_info); 10885e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer 1089bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola if (hasRelocationAddend()) 10906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(Entry.Addend)); 10915e492e8d42fa1f2940165a937d3d613c61b57708Benjamin Kramer } 10923565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 10933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 10943565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 10956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarconst MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) { 10966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1]; 1097cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream() << StrTabBuilder.data(); 10986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return StrtabSection; 10992ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola} 11002ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola 11016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap, 11026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t GroupSymbolIndex, uint64_t Offset, 11036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t Size, const MCSectionELF &Section) { 1104c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_link = 0; 1105c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola uint64_t sh_info = 0; 1106c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1107c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola switch(Section.getType()) { 11080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar default: 11090c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar // Nothing to do. 11100c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar break; 11110c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 1112c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNAMIC: 11136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar llvm_unreachable("SHT_DYNAMIC in a relocatable object"); 1114c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1115c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_REL: 1116c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_RELA: { 1117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines sh_link = SymbolTableIndex; 1118c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola assert(sh_link && ".symtab not found"); 11190c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar const MCSectionELF *InfoSection = Section.getAssociatedSection(); 1120c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = SectionIndexMap.lookup(InfoSection); 1121c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1122c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1123c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1124c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB: 1125c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_DYNSYM: 1126c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = StringTableIndex; 1127c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_info = LastLocalSymbolIndex; 1128c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1129c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1130c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola case ELF::SHT_SYMTAB_SHNDX: 1131c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola sh_link = SymbolTableIndex; 1132c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola break; 1133c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 11344a8d43e9a793324eee49758dc160a4e5d8eaa9a4Nick Lewycky case ELF::SHT_GROUP: 11352ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_link = SymbolTableIndex; 11362ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola sh_info = GroupSymbolIndex; 11372ff9e83a826c1c2ee0f1c6072d3d97d5b10678eeRafael Espindola break; 1138c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola } 1139c87a94a94254f45220255938f14321b6ec35fcfeRafael Espindola 1140b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && 11410c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar Section.getType() == ELF::SHT_ARM_EXIDX) 11420c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); 1143b0c899666a6c5397cf35fffd0f8d93749cb2cb38Logan Chien 11446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()), 11456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Section.getType(), Section.getFlags(), 0, Offset, Size, 11466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar sh_link, sh_info, Section.getAlignment(), 11476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Section.getEntrySize()); 11487c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola} 11497c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 1150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid ELFObjectWriter::writeSectionHeader( 11516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap, 11526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const SectionOffsetsTy &SectionOffsets) { 11536948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const unsigned NumSections = SectionTable.size(); 11547c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11557c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // Null section first. 11567c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint64_t FirstSectionSize = 11570c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; 11586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0); 11597c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MCSectionELF *Section : SectionTable) { 11617c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola uint32_t GroupSymbolIndex; 11626948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned Type = Section->getType(); 11636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Type != ELF::SHT_GROUP) 11647c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola GroupSymbolIndex = 0; 11657c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola else 11666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar GroupSymbolIndex = Section->getGroup()->getIndex(); 11677c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11686948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const std::pair<uint64_t, uint64_t> &Offsets = 11696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets.find(Section)->second; 11706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint64_t Size; 11716948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Type == ELF::SHT_NOBITS) 11726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Size = Layout.getSectionAddressSize(Section); 11736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar else 11746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Size = Offsets.second - Offsets.first; 11757c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 11766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size, 11776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar *Section); 11786db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola } 11796db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola} 11806db8a9f3fabefeb00163295f0611d09134651f3fRafael Espindola 11816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarvoid ELFObjectWriter::writeObject(MCAssembler &Asm, 1182115a3dd066c277c5417f4d9b9f642b732b76f4e7Daniel Dunbar const MCAsmLayout &Layout) { 11836948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCContext &Ctx = Asm.getContext(); 11846948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *StrtabSection = 11856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); 11866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar StringTableIndex = addToSectionTable(StrtabSection); 11876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11881f4f9e3d35a2264d86f97dfb6d1e4ccb434f449bRafael Espindola RevGroupMapTy RevGroupMap; 1189bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola SectionIndexMapTy SectionIndexMap; 1190bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers; 1192bab2a80525956b03b5f9126e1496785493326c37Rafael Espindola 11936948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Write out the ELF header ... 11946948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeHeader(Asm); 11956948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 11966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // ... then the sections ... 11976948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsetsTy SectionOffsets; 11986948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<MCSectionELF *> Groups; 11996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<MCSectionELF *> Relocations; 12006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSection &Sec : Asm) { 12016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF &Section = static_cast<MCSectionELF &>(Sec); 12027c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar align(Section.getAlignment()); 12048f413fa9c00dbaea000ddfe265ab5edd285ea3abRafael Espindola 12056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Remember the offset into the file for this section. 1206cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecStart = getStream().tell(); 12071d739a010d49914eae7b6c415dd6de76ca142030Rafael Espindola 12086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbolELF *SignatureSymbol = Section.getGroup(); 12096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeSectionData(Asm, Section, Layout); 12103565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 1211cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecEnd = getStream().tell(); 12126948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd); 12137c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola 12146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *RelSection = createRelocationSection(Ctx, Section); 12153565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (SignatureSymbol) { 12176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Asm.registerSymbol(*SignatureSymbol); 12186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned &GroupIdx = RevGroupMap[SignatureSymbol]; 12196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!GroupIdx) { 12206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol); 12216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar GroupIdx = addToSectionTable(Group); 12226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Group->setAlignment(4); 12236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Groups.push_back(Group); 12246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar std::vector<const MCSectionELF *> &Members = 12266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar GroupMembers[SignatureSymbol]; 12276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Members.push_back(&Section); 12286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (RelSection) 12296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Members.push_back(RelSection); 12306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12313565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionIndexMap[&Section] = addToSectionTable(&Section); 12336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (RelSection) { 12346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionIndexMap[RelSection] = addToSectionTable(RelSection); 12356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Relocations.push_back(RelSection); 12366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSectionELF *Group : Groups) { 12406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar align(Group->getAlignment()); 12416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Remember the offset into the file for this section. 1243cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecStart = getStream().tell(); 12446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSymbol *SignatureSymbol = Group->getGroup(); 12466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(SignatureSymbol); 12476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(uint32_t(ELF::GRP_COMDAT)); 12486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) { 12496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint32_t SecIndex = SectionIndexMap.lookup(Member); 12506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar write(SecIndex); 12516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1253cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecEnd = getStream().tell(); 12546948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[Group] = std::make_pair(SecStart, SecEnd); 12556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 12566948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12576948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // Compute symbol table information. 12586948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets); 12596948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12606948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar for (MCSectionELF *RelSection : Relocations) { 12616948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar align(RelSection->getAlignment()); 1262a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 12633565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming // Remember the offset into the file for this section. 1264cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecStart = getStream().tell(); 12656948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12666948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeRelocations(Asm, *RelSection->getAssociatedSection()); 12676948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1268cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecEnd = getStream().tell(); 12696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd); 12706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 127144cbde85badb60c7078e37e14575c15e671521b1Benjamin Kramer 12726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar { 1273cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecStart = getStream().tell(); 12746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCSectionELF *Sec = createStringTable(Ctx); 1275cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar uint64_t SecEnd = getStream().tell(); 12766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd); 12773565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming } 12783565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12790c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar uint64_t NaturalAlignment = is64Bit() ? 8 : 4; 12806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar align(NaturalAlignment); 1281a9eadca2fdf48e3228521f25b415b68219bcee31Benjamin Kramer 1282cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar const unsigned SectionHeaderOffset = getStream().tell(); 12830c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar 12847c18fa87a4d4ed8b0cfe1ec65597c748c6d91ca9Rafael Espindola // ... then the section header table ... 12856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar writeSectionHeader(Layout, SectionIndexMap, SectionOffsets); 12866948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 12876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) 12886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar ? (uint16_t)ELF::SHN_UNDEF 12896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar : SectionTable.size() + 1; 12906948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (sys::IsLittleEndianHost != IsLittleEndian) 12916948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar sys::swapByteOrder(NumSections); 12926948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar unsigned NumSectionsOffset; 12933565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 12940c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (is64Bit()) { 12950c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar uint64_t Val = SectionHeaderOffset; 12960c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (sys::IsLittleEndianHost != IsLittleEndian) 12970c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar sys::swapByteOrder(Val); 1298cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 1299cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar offsetof(ELF::Elf64_Ehdr, e_shoff)); 13006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum); 13010c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } else { 13020c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar uint32_t Val = SectionHeaderOffset; 13030c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar if (sys::IsLittleEndianHost != IsLittleEndian) 13040c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar sys::swapByteOrder(Val); 1305cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), 1306cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar offsetof(ELF::Elf32_Ehdr, e_shoff)); 13076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum); 13080c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar } 1309cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar getStream().pwrite(reinterpret_cast<char *>(&NumSections), 1310cddc3e03e4ec99c0268c03a126195173e519ed58Pirama Arumuga Nainar sizeof(NumSections), NumSectionsOffset); 13113565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming} 13123565a06ebf44a193a8b333cbeff2ee154298d450Matt Fleming 13136948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl( 13146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB, 13156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar bool InSet, bool IsPCRel) const { 13166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &SymA = cast<MCSymbolELF>(SA); 13176948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (IsPCRel) { 13186948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar assert(!InSet); 13196948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (::isWeak(SymA)) 13206948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 13216948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 13226948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB, 13236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar InSet, IsPCRel); 132478c1e1781cf36dd19988047eac8f664873d35237Eli Friedman} 132578c1e1781cf36dd19988047eac8f664873d35237Eli Friedman 13266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainarbool ELFObjectWriter::isWeak(const MCSymbol &S) const { 13276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Sym = cast<MCSymbolELF>(S); 13286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (::isWeak(Sym)) 13296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return true; 13306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // It is invalid to replace a reference to a global in a comdat 13326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // with a reference to a local since out of comdat references 13336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // to a local are forbidden. 13346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // We could try to return false for more cases, like the reference 13356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // being in the same comdat or Sym being an alias to another global, 13366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar // but it is not clear if it is worth the effort. 13376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (Sym.getBinding() != ELF::STB_GLOBAL) 13386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 13396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar if (!Sym.isInSection()) 13416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return false; 13426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 13436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const auto &Sec = cast<MCSectionELF>(Sym.getSection()); 13446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar return Sec.getGroup(); 13454c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 13464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 13476024c97ffa15766bc0f200ffd309d9e017ae0d4bRafael EspindolaMCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, 13480c7f116bb6950ef819323d855415b2f2b0aad987Pirama Arumuga Nainar raw_pwrite_stream &OS, 1349bff66a86e6e44dc7424cd2d7719ac80630b3a5f8Rafael Espindola bool IsLittleEndian) { 13507bd278019d745d8b339f6b896926ce32ce118db7Rafael Espindola return new ELFObjectWriter(MOTW, OS, IsLittleEndian); 1351edae8e1e4d5bd9b59f18ecef04a248be95d8ca46Rafael Espindola} 1352