1*9880d681SAndroid Build Coastguard Worker //===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements ELF object file writer information.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCELFObjectWriter.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/STLExtras.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallPtrSet.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/SmallString.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringMap.h"
19*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmBackend.h"
20*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
21*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmLayout.h"
22*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAssembler.h"
23*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCContext.h"
24*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCExpr.h"
25*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCFixupKindInfo.h"
26*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCObjectWriter.h"
27*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSectionELF.h"
28*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCSymbolELF.h"
29*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCValue.h"
30*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/StringTableBuilder.h"
31*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Compression.h"
32*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Debug.h"
33*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ELF.h"
34*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/Endian.h"
35*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/ErrorHandling.h"
36*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/StringSaver.h"
37*9880d681SAndroid Build Coastguard Worker #include <vector>
38*9880d681SAndroid Build Coastguard Worker
39*9880d681SAndroid Build Coastguard Worker using namespace llvm;
40*9880d681SAndroid Build Coastguard Worker
41*9880d681SAndroid Build Coastguard Worker #undef DEBUG_TYPE
42*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "reloc-info"
43*9880d681SAndroid Build Coastguard Worker
44*9880d681SAndroid Build Coastguard Worker namespace {
45*9880d681SAndroid Build Coastguard Worker typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy;
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker class ELFObjectWriter;
48*9880d681SAndroid Build Coastguard Worker
49*9880d681SAndroid Build Coastguard Worker class SymbolTableWriter {
50*9880d681SAndroid Build Coastguard Worker ELFObjectWriter &EWriter;
51*9880d681SAndroid Build Coastguard Worker bool Is64Bit;
52*9880d681SAndroid Build Coastguard Worker
53*9880d681SAndroid Build Coastguard Worker // indexes we are going to write to .symtab_shndx.
54*9880d681SAndroid Build Coastguard Worker std::vector<uint32_t> ShndxIndexes;
55*9880d681SAndroid Build Coastguard Worker
56*9880d681SAndroid Build Coastguard Worker // The numbel of symbols written so far.
57*9880d681SAndroid Build Coastguard Worker unsigned NumWritten;
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker void createSymtabShndx();
60*9880d681SAndroid Build Coastguard Worker
61*9880d681SAndroid Build Coastguard Worker template <typename T> void write(T Value);
62*9880d681SAndroid Build Coastguard Worker
63*9880d681SAndroid Build Coastguard Worker public:
64*9880d681SAndroid Build Coastguard Worker SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit);
65*9880d681SAndroid Build Coastguard Worker
66*9880d681SAndroid Build Coastguard Worker void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
67*9880d681SAndroid Build Coastguard Worker uint8_t other, uint32_t shndx, bool Reserved);
68*9880d681SAndroid Build Coastguard Worker
getShndxIndexes() const69*9880d681SAndroid Build Coastguard Worker ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
70*9880d681SAndroid Build Coastguard Worker };
71*9880d681SAndroid Build Coastguard Worker
72*9880d681SAndroid Build Coastguard Worker class ELFObjectWriter : public MCObjectWriter {
73*9880d681SAndroid Build Coastguard Worker static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
74*9880d681SAndroid Build Coastguard Worker static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
75*9880d681SAndroid Build Coastguard Worker bool Used, bool Renamed);
76*9880d681SAndroid Build Coastguard Worker
77*9880d681SAndroid Build Coastguard Worker /// Helper struct for containing some precomputed information on symbols.
78*9880d681SAndroid Build Coastguard Worker struct ELFSymbolData {
79*9880d681SAndroid Build Coastguard Worker const MCSymbolELF *Symbol;
80*9880d681SAndroid Build Coastguard Worker uint32_t SectionIndex;
81*9880d681SAndroid Build Coastguard Worker StringRef Name;
82*9880d681SAndroid Build Coastguard Worker
83*9880d681SAndroid Build Coastguard Worker // Support lexicographic sorting.
operator <__anon741e0e120111::ELFObjectWriter::ELFSymbolData84*9880d681SAndroid Build Coastguard Worker bool operator<(const ELFSymbolData &RHS) const {
85*9880d681SAndroid Build Coastguard Worker unsigned LHSType = Symbol->getType();
86*9880d681SAndroid Build Coastguard Worker unsigned RHSType = RHS.Symbol->getType();
87*9880d681SAndroid Build Coastguard Worker if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
88*9880d681SAndroid Build Coastguard Worker return false;
89*9880d681SAndroid Build Coastguard Worker if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
90*9880d681SAndroid Build Coastguard Worker return true;
91*9880d681SAndroid Build Coastguard Worker if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
92*9880d681SAndroid Build Coastguard Worker return SectionIndex < RHS.SectionIndex;
93*9880d681SAndroid Build Coastguard Worker return Name < RHS.Name;
94*9880d681SAndroid Build Coastguard Worker }
95*9880d681SAndroid Build Coastguard Worker };
96*9880d681SAndroid Build Coastguard Worker
97*9880d681SAndroid Build Coastguard Worker /// The target specific ELF writer instance.
98*9880d681SAndroid Build Coastguard Worker std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
99*9880d681SAndroid Build Coastguard Worker
100*9880d681SAndroid Build Coastguard Worker DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker llvm::DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>>
103*9880d681SAndroid Build Coastguard Worker Relocations;
104*9880d681SAndroid Build Coastguard Worker
105*9880d681SAndroid Build Coastguard Worker /// @}
106*9880d681SAndroid Build Coastguard Worker /// @name Symbol Table Data
107*9880d681SAndroid Build Coastguard Worker /// @{
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker BumpPtrAllocator Alloc;
110*9880d681SAndroid Build Coastguard Worker StringSaver VersionSymSaver{Alloc};
111*9880d681SAndroid Build Coastguard Worker StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
112*9880d681SAndroid Build Coastguard Worker
113*9880d681SAndroid Build Coastguard Worker /// @}
114*9880d681SAndroid Build Coastguard Worker
115*9880d681SAndroid Build Coastguard Worker // This holds the symbol table index of the last local symbol.
116*9880d681SAndroid Build Coastguard Worker unsigned LastLocalSymbolIndex;
117*9880d681SAndroid Build Coastguard Worker // This holds the .strtab section index.
118*9880d681SAndroid Build Coastguard Worker unsigned StringTableIndex;
119*9880d681SAndroid Build Coastguard Worker // This holds the .symtab section index.
120*9880d681SAndroid Build Coastguard Worker unsigned SymbolTableIndex;
121*9880d681SAndroid Build Coastguard Worker
122*9880d681SAndroid Build Coastguard Worker // Sections in the order they are to be output in the section table.
123*9880d681SAndroid Build Coastguard Worker std::vector<const MCSectionELF *> SectionTable;
124*9880d681SAndroid Build Coastguard Worker unsigned addToSectionTable(const MCSectionELF *Sec);
125*9880d681SAndroid Build Coastguard Worker
126*9880d681SAndroid Build Coastguard Worker // TargetObjectWriter wrappers.
is64Bit() const127*9880d681SAndroid Build Coastguard Worker bool is64Bit() const { return TargetObjectWriter->is64Bit(); }
hasRelocationAddend() const128*9880d681SAndroid Build Coastguard Worker bool hasRelocationAddend() const {
129*9880d681SAndroid Build Coastguard Worker return TargetObjectWriter->hasRelocationAddend();
130*9880d681SAndroid Build Coastguard Worker }
getRelocType(MCContext & Ctx,const MCValue & Target,const MCFixup & Fixup,bool IsPCRel) const131*9880d681SAndroid Build Coastguard Worker unsigned getRelocType(MCContext &Ctx, const MCValue &Target,
132*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup, bool IsPCRel) const {
133*9880d681SAndroid Build Coastguard Worker return TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
134*9880d681SAndroid Build Coastguard Worker }
135*9880d681SAndroid Build Coastguard Worker
136*9880d681SAndroid Build Coastguard Worker void align(unsigned Alignment);
137*9880d681SAndroid Build Coastguard Worker
138*9880d681SAndroid Build Coastguard Worker bool maybeWriteCompression(uint64_t Size,
139*9880d681SAndroid Build Coastguard Worker SmallVectorImpl<char> &CompressedContents,
140*9880d681SAndroid Build Coastguard Worker bool ZLibStyle, unsigned Alignment);
141*9880d681SAndroid Build Coastguard Worker
142*9880d681SAndroid Build Coastguard Worker public:
ELFObjectWriter(MCELFObjectTargetWriter * MOTW,raw_pwrite_stream & OS,bool IsLittleEndian)143*9880d681SAndroid Build Coastguard Worker ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS,
144*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian)
145*9880d681SAndroid Build Coastguard Worker : MCObjectWriter(OS, IsLittleEndian), TargetObjectWriter(MOTW) {}
146*9880d681SAndroid Build Coastguard Worker
reset()147*9880d681SAndroid Build Coastguard Worker void reset() override {
148*9880d681SAndroid Build Coastguard Worker Renames.clear();
149*9880d681SAndroid Build Coastguard Worker Relocations.clear();
150*9880d681SAndroid Build Coastguard Worker StrTabBuilder.clear();
151*9880d681SAndroid Build Coastguard Worker SectionTable.clear();
152*9880d681SAndroid Build Coastguard Worker MCObjectWriter::reset();
153*9880d681SAndroid Build Coastguard Worker }
154*9880d681SAndroid Build Coastguard Worker
155*9880d681SAndroid Build Coastguard Worker ~ELFObjectWriter() override;
156*9880d681SAndroid Build Coastguard Worker
WriteWord(uint64_t W)157*9880d681SAndroid Build Coastguard Worker void WriteWord(uint64_t W) {
158*9880d681SAndroid Build Coastguard Worker if (is64Bit())
159*9880d681SAndroid Build Coastguard Worker write64(W);
160*9880d681SAndroid Build Coastguard Worker else
161*9880d681SAndroid Build Coastguard Worker write32(W);
162*9880d681SAndroid Build Coastguard Worker }
163*9880d681SAndroid Build Coastguard Worker
write(T Val)164*9880d681SAndroid Build Coastguard Worker template <typename T> void write(T Val) {
165*9880d681SAndroid Build Coastguard Worker if (IsLittleEndian)
166*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::little>(getStream()).write(Val);
167*9880d681SAndroid Build Coastguard Worker else
168*9880d681SAndroid Build Coastguard Worker support::endian::Writer<support::big>(getStream()).write(Val);
169*9880d681SAndroid Build Coastguard Worker }
170*9880d681SAndroid Build Coastguard Worker
171*9880d681SAndroid Build Coastguard Worker void writeHeader(const MCAssembler &Asm);
172*9880d681SAndroid Build Coastguard Worker
173*9880d681SAndroid Build Coastguard Worker void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
174*9880d681SAndroid Build Coastguard Worker ELFSymbolData &MSD, const MCAsmLayout &Layout);
175*9880d681SAndroid Build Coastguard Worker
176*9880d681SAndroid Build Coastguard Worker // Start and end offset of each section
177*9880d681SAndroid Build Coastguard Worker typedef std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>
178*9880d681SAndroid Build Coastguard Worker SectionOffsetsTy;
179*9880d681SAndroid Build Coastguard Worker
180*9880d681SAndroid Build Coastguard Worker bool shouldRelocateWithSymbol(const MCAssembler &Asm,
181*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *RefA,
182*9880d681SAndroid Build Coastguard Worker const MCSymbol *Sym, uint64_t C,
183*9880d681SAndroid Build Coastguard Worker unsigned Type) const;
184*9880d681SAndroid Build Coastguard Worker
185*9880d681SAndroid Build Coastguard Worker void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
186*9880d681SAndroid Build Coastguard Worker const MCFragment *Fragment, const MCFixup &Fixup,
187*9880d681SAndroid Build Coastguard Worker MCValue Target, bool &IsPCRel,
188*9880d681SAndroid Build Coastguard Worker uint64_t &FixedValue) override;
189*9880d681SAndroid Build Coastguard Worker
190*9880d681SAndroid Build Coastguard Worker // Map from a signature symbol to the group section index
191*9880d681SAndroid Build Coastguard Worker typedef DenseMap<const MCSymbol *, unsigned> RevGroupMapTy;
192*9880d681SAndroid Build Coastguard Worker
193*9880d681SAndroid Build Coastguard Worker /// Compute the symbol table data
194*9880d681SAndroid Build Coastguard Worker ///
195*9880d681SAndroid Build Coastguard Worker /// \param Asm - The assembler.
196*9880d681SAndroid Build Coastguard Worker /// \param SectionIndexMap - Maps a section to its index.
197*9880d681SAndroid Build Coastguard Worker /// \param RevGroupMap - Maps a signature symbol to the group section.
198*9880d681SAndroid Build Coastguard Worker void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
199*9880d681SAndroid Build Coastguard Worker const SectionIndexMapTy &SectionIndexMap,
200*9880d681SAndroid Build Coastguard Worker const RevGroupMapTy &RevGroupMap,
201*9880d681SAndroid Build Coastguard Worker SectionOffsetsTy &SectionOffsets);
202*9880d681SAndroid Build Coastguard Worker
203*9880d681SAndroid Build Coastguard Worker MCSectionELF *createRelocationSection(MCContext &Ctx,
204*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Sec);
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker const MCSectionELF *createStringTable(MCContext &Ctx);
207*9880d681SAndroid Build Coastguard Worker
208*9880d681SAndroid Build Coastguard Worker void executePostLayoutBinding(MCAssembler &Asm,
209*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) override;
210*9880d681SAndroid Build Coastguard Worker
211*9880d681SAndroid Build Coastguard Worker void writeSectionHeader(const MCAsmLayout &Layout,
212*9880d681SAndroid Build Coastguard Worker const SectionIndexMapTy &SectionIndexMap,
213*9880d681SAndroid Build Coastguard Worker const SectionOffsetsTy &SectionOffsets);
214*9880d681SAndroid Build Coastguard Worker
215*9880d681SAndroid Build Coastguard Worker void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
216*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout);
217*9880d681SAndroid Build Coastguard Worker
218*9880d681SAndroid Build Coastguard Worker void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
219*9880d681SAndroid Build Coastguard Worker uint64_t Address, uint64_t Offset, uint64_t Size,
220*9880d681SAndroid Build Coastguard Worker uint32_t Link, uint32_t Info, uint64_t Alignment,
221*9880d681SAndroid Build Coastguard Worker uint64_t EntrySize);
222*9880d681SAndroid Build Coastguard Worker
223*9880d681SAndroid Build Coastguard Worker void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
224*9880d681SAndroid Build Coastguard Worker
225*9880d681SAndroid Build Coastguard Worker bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
226*9880d681SAndroid Build Coastguard Worker const MCSymbol &SymA,
227*9880d681SAndroid Build Coastguard Worker const MCFragment &FB, bool InSet,
228*9880d681SAndroid Build Coastguard Worker bool IsPCRel) const override;
229*9880d681SAndroid Build Coastguard Worker
230*9880d681SAndroid Build Coastguard Worker bool isWeak(const MCSymbol &Sym) const override;
231*9880d681SAndroid Build Coastguard Worker
232*9880d681SAndroid Build Coastguard Worker void writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override;
233*9880d681SAndroid Build Coastguard Worker void writeSection(const SectionIndexMapTy &SectionIndexMap,
234*9880d681SAndroid Build Coastguard Worker uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
235*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Section);
236*9880d681SAndroid Build Coastguard Worker };
237*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
238*9880d681SAndroid Build Coastguard Worker
align(unsigned Alignment)239*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::align(unsigned Alignment) {
240*9880d681SAndroid Build Coastguard Worker uint64_t Padding = OffsetToAlignment(getStream().tell(), Alignment);
241*9880d681SAndroid Build Coastguard Worker WriteZeros(Padding);
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker
addToSectionTable(const MCSectionELF * Sec)244*9880d681SAndroid Build Coastguard Worker unsigned ELFObjectWriter::addToSectionTable(const MCSectionELF *Sec) {
245*9880d681SAndroid Build Coastguard Worker SectionTable.push_back(Sec);
246*9880d681SAndroid Build Coastguard Worker StrTabBuilder.add(Sec->getSectionName());
247*9880d681SAndroid Build Coastguard Worker return SectionTable.size();
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
createSymtabShndx()250*9880d681SAndroid Build Coastguard Worker void SymbolTableWriter::createSymtabShndx() {
251*9880d681SAndroid Build Coastguard Worker if (!ShndxIndexes.empty())
252*9880d681SAndroid Build Coastguard Worker return;
253*9880d681SAndroid Build Coastguard Worker
254*9880d681SAndroid Build Coastguard Worker ShndxIndexes.resize(NumWritten);
255*9880d681SAndroid Build Coastguard Worker }
256*9880d681SAndroid Build Coastguard Worker
write(T Value)257*9880d681SAndroid Build Coastguard Worker template <typename T> void SymbolTableWriter::write(T Value) {
258*9880d681SAndroid Build Coastguard Worker EWriter.write(Value);
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker
SymbolTableWriter(ELFObjectWriter & EWriter,bool Is64Bit)261*9880d681SAndroid Build Coastguard Worker SymbolTableWriter::SymbolTableWriter(ELFObjectWriter &EWriter, bool Is64Bit)
262*9880d681SAndroid Build Coastguard Worker : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
263*9880d681SAndroid Build Coastguard Worker
writeSymbol(uint32_t name,uint8_t info,uint64_t value,uint64_t size,uint8_t other,uint32_t shndx,bool Reserved)264*9880d681SAndroid Build Coastguard Worker void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
265*9880d681SAndroid Build Coastguard Worker uint64_t size, uint8_t other,
266*9880d681SAndroid Build Coastguard Worker uint32_t shndx, bool Reserved) {
267*9880d681SAndroid Build Coastguard Worker bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
268*9880d681SAndroid Build Coastguard Worker
269*9880d681SAndroid Build Coastguard Worker if (LargeIndex)
270*9880d681SAndroid Build Coastguard Worker createSymtabShndx();
271*9880d681SAndroid Build Coastguard Worker
272*9880d681SAndroid Build Coastguard Worker if (!ShndxIndexes.empty()) {
273*9880d681SAndroid Build Coastguard Worker if (LargeIndex)
274*9880d681SAndroid Build Coastguard Worker ShndxIndexes.push_back(shndx);
275*9880d681SAndroid Build Coastguard Worker else
276*9880d681SAndroid Build Coastguard Worker ShndxIndexes.push_back(0);
277*9880d681SAndroid Build Coastguard Worker }
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
280*9880d681SAndroid Build Coastguard Worker
281*9880d681SAndroid Build Coastguard Worker if (Is64Bit) {
282*9880d681SAndroid Build Coastguard Worker write(name); // st_name
283*9880d681SAndroid Build Coastguard Worker write(info); // st_info
284*9880d681SAndroid Build Coastguard Worker write(other); // st_other
285*9880d681SAndroid Build Coastguard Worker write(Index); // st_shndx
286*9880d681SAndroid Build Coastguard Worker write(value); // st_value
287*9880d681SAndroid Build Coastguard Worker write(size); // st_size
288*9880d681SAndroid Build Coastguard Worker } else {
289*9880d681SAndroid Build Coastguard Worker write(name); // st_name
290*9880d681SAndroid Build Coastguard Worker write(uint32_t(value)); // st_value
291*9880d681SAndroid Build Coastguard Worker write(uint32_t(size)); // st_size
292*9880d681SAndroid Build Coastguard Worker write(info); // st_info
293*9880d681SAndroid Build Coastguard Worker write(other); // st_other
294*9880d681SAndroid Build Coastguard Worker write(Index); // st_shndx
295*9880d681SAndroid Build Coastguard Worker }
296*9880d681SAndroid Build Coastguard Worker
297*9880d681SAndroid Build Coastguard Worker ++NumWritten;
298*9880d681SAndroid Build Coastguard Worker }
299*9880d681SAndroid Build Coastguard Worker
~ELFObjectWriter()300*9880d681SAndroid Build Coastguard Worker ELFObjectWriter::~ELFObjectWriter()
301*9880d681SAndroid Build Coastguard Worker {}
302*9880d681SAndroid Build Coastguard Worker
303*9880d681SAndroid Build Coastguard Worker // Emit the ELF header.
writeHeader(const MCAssembler & Asm)304*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeHeader(const MCAssembler &Asm) {
305*9880d681SAndroid Build Coastguard Worker // ELF Header
306*9880d681SAndroid Build Coastguard Worker // ----------
307*9880d681SAndroid Build Coastguard Worker //
308*9880d681SAndroid Build Coastguard Worker // Note
309*9880d681SAndroid Build Coastguard Worker // ----
310*9880d681SAndroid Build Coastguard Worker // emitWord method behaves differently for ELF32 and ELF64, writing
311*9880d681SAndroid Build Coastguard Worker // 4 bytes in the former and 8 in the latter.
312*9880d681SAndroid Build Coastguard Worker
313*9880d681SAndroid Build Coastguard Worker writeBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3]
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
316*9880d681SAndroid Build Coastguard Worker
317*9880d681SAndroid Build Coastguard Worker // e_ident[EI_DATA]
318*9880d681SAndroid Build Coastguard Worker write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB);
319*9880d681SAndroid Build Coastguard Worker
320*9880d681SAndroid Build Coastguard Worker write8(ELF::EV_CURRENT); // e_ident[EI_VERSION]
321*9880d681SAndroid Build Coastguard Worker // e_ident[EI_OSABI]
322*9880d681SAndroid Build Coastguard Worker write8(TargetObjectWriter->getOSABI());
323*9880d681SAndroid Build Coastguard Worker write8(0); // e_ident[EI_ABIVERSION]
324*9880d681SAndroid Build Coastguard Worker
325*9880d681SAndroid Build Coastguard Worker WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD);
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker write16(ELF::ET_REL); // e_type
328*9880d681SAndroid Build Coastguard Worker
329*9880d681SAndroid Build Coastguard Worker write16(TargetObjectWriter->getEMachine()); // e_machine = target
330*9880d681SAndroid Build Coastguard Worker
331*9880d681SAndroid Build Coastguard Worker write32(ELF::EV_CURRENT); // e_version
332*9880d681SAndroid Build Coastguard Worker WriteWord(0); // e_entry, no entry point in .o file
333*9880d681SAndroid Build Coastguard Worker WriteWord(0); // e_phoff, no program header for .o
334*9880d681SAndroid Build Coastguard Worker WriteWord(0); // e_shoff = sec hdr table off in bytes
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker // e_flags = whatever the target wants
337*9880d681SAndroid Build Coastguard Worker write32(Asm.getELFHeaderEFlags());
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker // e_ehsize = ELF header size
340*9880d681SAndroid Build Coastguard Worker write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr));
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker write16(0); // e_phentsize = prog header entry size
343*9880d681SAndroid Build Coastguard Worker write16(0); // e_phnum = # prog header entries = 0
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker // e_shentsize = Section header entry size
346*9880d681SAndroid Build Coastguard Worker write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr));
347*9880d681SAndroid Build Coastguard Worker
348*9880d681SAndroid Build Coastguard Worker // e_shnum = # of section header ents
349*9880d681SAndroid Build Coastguard Worker write16(0);
350*9880d681SAndroid Build Coastguard Worker
351*9880d681SAndroid Build Coastguard Worker // e_shstrndx = Section # of '.shstrtab'
352*9880d681SAndroid Build Coastguard Worker assert(StringTableIndex < ELF::SHN_LORESERVE);
353*9880d681SAndroid Build Coastguard Worker write16(StringTableIndex);
354*9880d681SAndroid Build Coastguard Worker }
355*9880d681SAndroid Build Coastguard Worker
SymbolValue(const MCSymbol & Sym,const MCAsmLayout & Layout)356*9880d681SAndroid Build Coastguard Worker uint64_t ELFObjectWriter::SymbolValue(const MCSymbol &Sym,
357*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) {
358*9880d681SAndroid Build Coastguard Worker if (Sym.isCommon() && Sym.isExternal())
359*9880d681SAndroid Build Coastguard Worker return Sym.getCommonAlignment();
360*9880d681SAndroid Build Coastguard Worker
361*9880d681SAndroid Build Coastguard Worker uint64_t Res;
362*9880d681SAndroid Build Coastguard Worker if (!Layout.getSymbolOffset(Sym, Res))
363*9880d681SAndroid Build Coastguard Worker return 0;
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker if (Layout.getAssembler().isThumbFunc(&Sym))
366*9880d681SAndroid Build Coastguard Worker Res |= 1;
367*9880d681SAndroid Build Coastguard Worker
368*9880d681SAndroid Build Coastguard Worker return Res;
369*9880d681SAndroid Build Coastguard Worker }
370*9880d681SAndroid Build Coastguard Worker
executePostLayoutBinding(MCAssembler & Asm,const MCAsmLayout & Layout)371*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
372*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) {
373*9880d681SAndroid Build Coastguard Worker // Section symbols are used as definitions for undefined symbols with matching
374*9880d681SAndroid Build Coastguard Worker // names. If there are multiple sections with the same name, the first one is
375*9880d681SAndroid Build Coastguard Worker // used.
376*9880d681SAndroid Build Coastguard Worker for (const MCSection &Sec : Asm) {
377*9880d681SAndroid Build Coastguard Worker const MCSymbol *Begin = Sec.getBeginSymbol();
378*9880d681SAndroid Build Coastguard Worker if (!Begin)
379*9880d681SAndroid Build Coastguard Worker continue;
380*9880d681SAndroid Build Coastguard Worker
381*9880d681SAndroid Build Coastguard Worker const MCSymbol *Alias = Asm.getContext().lookupSymbol(Begin->getName());
382*9880d681SAndroid Build Coastguard Worker if (!Alias || !Alias->isUndefined())
383*9880d681SAndroid Build Coastguard Worker continue;
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker Renames.insert(
386*9880d681SAndroid Build Coastguard Worker std::make_pair(cast<MCSymbolELF>(Alias), cast<MCSymbolELF>(Begin)));
387*9880d681SAndroid Build Coastguard Worker }
388*9880d681SAndroid Build Coastguard Worker
389*9880d681SAndroid Build Coastguard Worker // The presence of symbol versions causes undefined symbols and
390*9880d681SAndroid Build Coastguard Worker // versions declared with @@@ to be renamed.
391*9880d681SAndroid Build Coastguard Worker for (const MCSymbol &A : Asm.symbols()) {
392*9880d681SAndroid Build Coastguard Worker const auto &Alias = cast<MCSymbolELF>(A);
393*9880d681SAndroid Build Coastguard Worker // Not an alias.
394*9880d681SAndroid Build Coastguard Worker if (!Alias.isVariable())
395*9880d681SAndroid Build Coastguard Worker continue;
396*9880d681SAndroid Build Coastguard Worker auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue());
397*9880d681SAndroid Build Coastguard Worker if (!Ref)
398*9880d681SAndroid Build Coastguard Worker continue;
399*9880d681SAndroid Build Coastguard Worker const auto &Symbol = cast<MCSymbolELF>(Ref->getSymbol());
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker StringRef AliasName = Alias.getName();
402*9880d681SAndroid Build Coastguard Worker size_t Pos = AliasName.find('@');
403*9880d681SAndroid Build Coastguard Worker if (Pos == StringRef::npos)
404*9880d681SAndroid Build Coastguard Worker continue;
405*9880d681SAndroid Build Coastguard Worker
406*9880d681SAndroid Build Coastguard Worker // Aliases defined with .symvar copy the binding from the symbol they alias.
407*9880d681SAndroid Build Coastguard Worker // This is the first place we are able to copy this information.
408*9880d681SAndroid Build Coastguard Worker Alias.setExternal(Symbol.isExternal());
409*9880d681SAndroid Build Coastguard Worker Alias.setBinding(Symbol.getBinding());
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker StringRef Rest = AliasName.substr(Pos);
412*9880d681SAndroid Build Coastguard Worker if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
413*9880d681SAndroid Build Coastguard Worker continue;
414*9880d681SAndroid Build Coastguard Worker
415*9880d681SAndroid Build Coastguard Worker // FIXME: produce a better error message.
416*9880d681SAndroid Build Coastguard Worker if (Symbol.isUndefined() && Rest.startswith("@@") &&
417*9880d681SAndroid Build Coastguard Worker !Rest.startswith("@@@"))
418*9880d681SAndroid Build Coastguard Worker report_fatal_error("A @@ version cannot be undefined");
419*9880d681SAndroid Build Coastguard Worker
420*9880d681SAndroid Build Coastguard Worker Renames.insert(std::make_pair(&Symbol, &Alias));
421*9880d681SAndroid Build Coastguard Worker }
422*9880d681SAndroid Build Coastguard Worker }
423*9880d681SAndroid Build Coastguard Worker
mergeTypeForSet(uint8_t origType,uint8_t newType)424*9880d681SAndroid Build Coastguard Worker static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
425*9880d681SAndroid Build Coastguard Worker uint8_t Type = newType;
426*9880d681SAndroid Build Coastguard Worker
427*9880d681SAndroid Build Coastguard Worker // Propagation rules:
428*9880d681SAndroid Build Coastguard Worker // IFUNC > FUNC > OBJECT > NOTYPE
429*9880d681SAndroid Build Coastguard Worker // TLS_OBJECT > OBJECT > NOTYPE
430*9880d681SAndroid Build Coastguard Worker //
431*9880d681SAndroid Build Coastguard Worker // dont let the new type degrade the old type
432*9880d681SAndroid Build Coastguard Worker switch (origType) {
433*9880d681SAndroid Build Coastguard Worker default:
434*9880d681SAndroid Build Coastguard Worker break;
435*9880d681SAndroid Build Coastguard Worker case ELF::STT_GNU_IFUNC:
436*9880d681SAndroid Build Coastguard Worker if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
437*9880d681SAndroid Build Coastguard Worker Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
438*9880d681SAndroid Build Coastguard Worker Type = ELF::STT_GNU_IFUNC;
439*9880d681SAndroid Build Coastguard Worker break;
440*9880d681SAndroid Build Coastguard Worker case ELF::STT_FUNC:
441*9880d681SAndroid Build Coastguard Worker if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
442*9880d681SAndroid Build Coastguard Worker Type == ELF::STT_TLS)
443*9880d681SAndroid Build Coastguard Worker Type = ELF::STT_FUNC;
444*9880d681SAndroid Build Coastguard Worker break;
445*9880d681SAndroid Build Coastguard Worker case ELF::STT_OBJECT:
446*9880d681SAndroid Build Coastguard Worker if (Type == ELF::STT_NOTYPE)
447*9880d681SAndroid Build Coastguard Worker Type = ELF::STT_OBJECT;
448*9880d681SAndroid Build Coastguard Worker break;
449*9880d681SAndroid Build Coastguard Worker case ELF::STT_TLS:
450*9880d681SAndroid Build Coastguard Worker if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
451*9880d681SAndroid Build Coastguard Worker Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
452*9880d681SAndroid Build Coastguard Worker Type = ELF::STT_TLS;
453*9880d681SAndroid Build Coastguard Worker break;
454*9880d681SAndroid Build Coastguard Worker }
455*9880d681SAndroid Build Coastguard Worker
456*9880d681SAndroid Build Coastguard Worker return Type;
457*9880d681SAndroid Build Coastguard Worker }
458*9880d681SAndroid Build Coastguard Worker
writeSymbol(SymbolTableWriter & Writer,uint32_t StringIndex,ELFSymbolData & MSD,const MCAsmLayout & Layout)459*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeSymbol(SymbolTableWriter &Writer,
460*9880d681SAndroid Build Coastguard Worker uint32_t StringIndex, ELFSymbolData &MSD,
461*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) {
462*9880d681SAndroid Build Coastguard Worker const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
463*9880d681SAndroid Build Coastguard Worker const MCSymbolELF *Base =
464*9880d681SAndroid Build Coastguard Worker cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
465*9880d681SAndroid Build Coastguard Worker
466*9880d681SAndroid Build Coastguard Worker // This has to be in sync with when computeSymbolTable uses SHN_ABS or
467*9880d681SAndroid Build Coastguard Worker // SHN_COMMON.
468*9880d681SAndroid Build Coastguard Worker bool IsReserved = !Base || Symbol.isCommon();
469*9880d681SAndroid Build Coastguard Worker
470*9880d681SAndroid Build Coastguard Worker // Binding and Type share the same byte as upper and lower nibbles
471*9880d681SAndroid Build Coastguard Worker uint8_t Binding = Symbol.getBinding();
472*9880d681SAndroid Build Coastguard Worker uint8_t Type = Symbol.getType();
473*9880d681SAndroid Build Coastguard Worker if (Base) {
474*9880d681SAndroid Build Coastguard Worker Type = mergeTypeForSet(Type, Base->getType());
475*9880d681SAndroid Build Coastguard Worker }
476*9880d681SAndroid Build Coastguard Worker uint8_t Info = (Binding << 4) | Type;
477*9880d681SAndroid Build Coastguard Worker
478*9880d681SAndroid Build Coastguard Worker // Other and Visibility share the same byte with Visibility using the lower
479*9880d681SAndroid Build Coastguard Worker // 2 bits
480*9880d681SAndroid Build Coastguard Worker uint8_t Visibility = Symbol.getVisibility();
481*9880d681SAndroid Build Coastguard Worker uint8_t Other = Symbol.getOther() | Visibility;
482*9880d681SAndroid Build Coastguard Worker
483*9880d681SAndroid Build Coastguard Worker uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
484*9880d681SAndroid Build Coastguard Worker uint64_t Size = 0;
485*9880d681SAndroid Build Coastguard Worker
486*9880d681SAndroid Build Coastguard Worker const MCExpr *ESize = MSD.Symbol->getSize();
487*9880d681SAndroid Build Coastguard Worker if (!ESize && Base)
488*9880d681SAndroid Build Coastguard Worker ESize = Base->getSize();
489*9880d681SAndroid Build Coastguard Worker
490*9880d681SAndroid Build Coastguard Worker if (ESize) {
491*9880d681SAndroid Build Coastguard Worker int64_t Res;
492*9880d681SAndroid Build Coastguard Worker if (!ESize->evaluateKnownAbsolute(Res, Layout))
493*9880d681SAndroid Build Coastguard Worker report_fatal_error("Size expression must be absolute.");
494*9880d681SAndroid Build Coastguard Worker Size = Res;
495*9880d681SAndroid Build Coastguard Worker }
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker // Write out the symbol table entry
498*9880d681SAndroid Build Coastguard Worker Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
499*9880d681SAndroid Build Coastguard Worker IsReserved);
500*9880d681SAndroid Build Coastguard Worker }
501*9880d681SAndroid Build Coastguard Worker
502*9880d681SAndroid Build Coastguard Worker // It is always valid to create a relocation with a symbol. It is preferable
503*9880d681SAndroid Build Coastguard Worker // to use a relocation with a section if that is possible. Using the section
504*9880d681SAndroid Build Coastguard Worker // allows us to omit some local symbols from the symbol table.
shouldRelocateWithSymbol(const MCAssembler & Asm,const MCSymbolRefExpr * RefA,const MCSymbol * S,uint64_t C,unsigned Type) const505*9880d681SAndroid Build Coastguard Worker bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
506*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *RefA,
507*9880d681SAndroid Build Coastguard Worker const MCSymbol *S, uint64_t C,
508*9880d681SAndroid Build Coastguard Worker unsigned Type) const {
509*9880d681SAndroid Build Coastguard Worker const auto *Sym = cast_or_null<MCSymbolELF>(S);
510*9880d681SAndroid Build Coastguard Worker // A PCRel relocation to an absolute value has no symbol (or section). We
511*9880d681SAndroid Build Coastguard Worker // represent that with a relocation to a null section.
512*9880d681SAndroid Build Coastguard Worker if (!RefA)
513*9880d681SAndroid Build Coastguard Worker return false;
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
516*9880d681SAndroid Build Coastguard Worker switch (Kind) {
517*9880d681SAndroid Build Coastguard Worker default:
518*9880d681SAndroid Build Coastguard Worker break;
519*9880d681SAndroid Build Coastguard Worker // The .odp creation emits a relocation against the symbol ".TOC." which
520*9880d681SAndroid Build Coastguard Worker // create a R_PPC64_TOC relocation. However the relocation symbol name
521*9880d681SAndroid Build Coastguard Worker // in final object creation should be NULL, since the symbol does not
522*9880d681SAndroid Build Coastguard Worker // really exist, it is just the reference to TOC base for the current
523*9880d681SAndroid Build Coastguard Worker // object file. Since the symbol is undefined, returning false results
524*9880d681SAndroid Build Coastguard Worker // in a relocation with a null section which is the desired result.
525*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_TOCBASE:
526*9880d681SAndroid Build Coastguard Worker return false;
527*9880d681SAndroid Build Coastguard Worker
528*9880d681SAndroid Build Coastguard Worker // These VariantKind cause the relocation to refer to something other than
529*9880d681SAndroid Build Coastguard Worker // the symbol itself, like a linker generated table. Since the address of
530*9880d681SAndroid Build Coastguard Worker // symbol is not relevant, we cannot replace the symbol with the
531*9880d681SAndroid Build Coastguard Worker // section and patch the difference in the addend.
532*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_GOT:
533*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PLT:
534*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_GOTPCREL:
535*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_LO:
536*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_HI:
537*9880d681SAndroid Build Coastguard Worker case MCSymbolRefExpr::VK_PPC_GOT_HA:
538*9880d681SAndroid Build Coastguard Worker return true;
539*9880d681SAndroid Build Coastguard Worker }
540*9880d681SAndroid Build Coastguard Worker
541*9880d681SAndroid Build Coastguard Worker // An undefined symbol is not in any section, so the relocation has to point
542*9880d681SAndroid Build Coastguard Worker // to the symbol itself.
543*9880d681SAndroid Build Coastguard Worker assert(Sym && "Expected a symbol");
544*9880d681SAndroid Build Coastguard Worker if (Sym->isUndefined())
545*9880d681SAndroid Build Coastguard Worker return true;
546*9880d681SAndroid Build Coastguard Worker
547*9880d681SAndroid Build Coastguard Worker unsigned Binding = Sym->getBinding();
548*9880d681SAndroid Build Coastguard Worker switch(Binding) {
549*9880d681SAndroid Build Coastguard Worker default:
550*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Invalid Binding");
551*9880d681SAndroid Build Coastguard Worker case ELF::STB_LOCAL:
552*9880d681SAndroid Build Coastguard Worker break;
553*9880d681SAndroid Build Coastguard Worker case ELF::STB_WEAK:
554*9880d681SAndroid Build Coastguard Worker // If the symbol is weak, it might be overridden by a symbol in another
555*9880d681SAndroid Build Coastguard Worker // file. The relocation has to point to the symbol so that the linker
556*9880d681SAndroid Build Coastguard Worker // can update it.
557*9880d681SAndroid Build Coastguard Worker return true;
558*9880d681SAndroid Build Coastguard Worker case ELF::STB_GLOBAL:
559*9880d681SAndroid Build Coastguard Worker // Global ELF symbols can be preempted by the dynamic linker. The relocation
560*9880d681SAndroid Build Coastguard Worker // has to point to the symbol for a reason analogous to the STB_WEAK case.
561*9880d681SAndroid Build Coastguard Worker return true;
562*9880d681SAndroid Build Coastguard Worker }
563*9880d681SAndroid Build Coastguard Worker
564*9880d681SAndroid Build Coastguard Worker // If a relocation points to a mergeable section, we have to be careful.
565*9880d681SAndroid Build Coastguard Worker // If the offset is zero, a relocation with the section will encode the
566*9880d681SAndroid Build Coastguard Worker // same information. With a non-zero offset, the situation is different.
567*9880d681SAndroid Build Coastguard Worker // For example, a relocation can point 42 bytes past the end of a string.
568*9880d681SAndroid Build Coastguard Worker // If we change such a relocation to use the section, the linker would think
569*9880d681SAndroid Build Coastguard Worker // that it pointed to another string and subtracting 42 at runtime will
570*9880d681SAndroid Build Coastguard Worker // produce the wrong value.
571*9880d681SAndroid Build Coastguard Worker auto &Sec = cast<MCSectionELF>(Sym->getSection());
572*9880d681SAndroid Build Coastguard Worker unsigned Flags = Sec.getFlags();
573*9880d681SAndroid Build Coastguard Worker if (Flags & ELF::SHF_MERGE) {
574*9880d681SAndroid Build Coastguard Worker if (C != 0)
575*9880d681SAndroid Build Coastguard Worker return true;
576*9880d681SAndroid Build Coastguard Worker
577*9880d681SAndroid Build Coastguard Worker // It looks like gold has a bug (http://sourceware.org/PR16794) and can
578*9880d681SAndroid Build Coastguard Worker // only handle section relocations to mergeable sections if using RELA.
579*9880d681SAndroid Build Coastguard Worker if (!hasRelocationAddend())
580*9880d681SAndroid Build Coastguard Worker return true;
581*9880d681SAndroid Build Coastguard Worker }
582*9880d681SAndroid Build Coastguard Worker
583*9880d681SAndroid Build Coastguard Worker // Most TLS relocations use a got, so they need the symbol. Even those that
584*9880d681SAndroid Build Coastguard Worker // are just an offset (@tpoff), require a symbol in gold versions before
585*9880d681SAndroid Build Coastguard Worker // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
586*9880d681SAndroid Build Coastguard Worker // http://sourceware.org/PR16773.
587*9880d681SAndroid Build Coastguard Worker if (Flags & ELF::SHF_TLS)
588*9880d681SAndroid Build Coastguard Worker return true;
589*9880d681SAndroid Build Coastguard Worker
590*9880d681SAndroid Build Coastguard Worker // If the symbol is a thumb function the final relocation must set the lowest
591*9880d681SAndroid Build Coastguard Worker // bit. With a symbol that is done by just having the symbol have that bit
592*9880d681SAndroid Build Coastguard Worker // set, so we would lose the bit if we relocated with the section.
593*9880d681SAndroid Build Coastguard Worker // FIXME: We could use the section but add the bit to the relocation value.
594*9880d681SAndroid Build Coastguard Worker if (Asm.isThumbFunc(Sym))
595*9880d681SAndroid Build Coastguard Worker return true;
596*9880d681SAndroid Build Coastguard Worker
597*9880d681SAndroid Build Coastguard Worker if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
598*9880d681SAndroid Build Coastguard Worker return true;
599*9880d681SAndroid Build Coastguard Worker return false;
600*9880d681SAndroid Build Coastguard Worker }
601*9880d681SAndroid Build Coastguard Worker
602*9880d681SAndroid Build Coastguard Worker // True if the assembler knows nothing about the final value of the symbol.
603*9880d681SAndroid Build Coastguard Worker // This doesn't cover the comdat issues, since in those cases the assembler
604*9880d681SAndroid Build Coastguard Worker // can at least know that all symbols in the section will move together.
isWeak(const MCSymbolELF & Sym)605*9880d681SAndroid Build Coastguard Worker static bool isWeak(const MCSymbolELF &Sym) {
606*9880d681SAndroid Build Coastguard Worker if (Sym.getType() == ELF::STT_GNU_IFUNC)
607*9880d681SAndroid Build Coastguard Worker return true;
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker switch (Sym.getBinding()) {
610*9880d681SAndroid Build Coastguard Worker default:
611*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Unknown binding");
612*9880d681SAndroid Build Coastguard Worker case ELF::STB_LOCAL:
613*9880d681SAndroid Build Coastguard Worker return false;
614*9880d681SAndroid Build Coastguard Worker case ELF::STB_GLOBAL:
615*9880d681SAndroid Build Coastguard Worker return false;
616*9880d681SAndroid Build Coastguard Worker case ELF::STB_WEAK:
617*9880d681SAndroid Build Coastguard Worker case ELF::STB_GNU_UNIQUE:
618*9880d681SAndroid Build Coastguard Worker return true;
619*9880d681SAndroid Build Coastguard Worker }
620*9880d681SAndroid Build Coastguard Worker }
621*9880d681SAndroid Build Coastguard Worker
recordRelocation(MCAssembler & Asm,const MCAsmLayout & Layout,const MCFragment * Fragment,const MCFixup & Fixup,MCValue Target,bool & IsPCRel,uint64_t & FixedValue)622*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
623*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout,
624*9880d681SAndroid Build Coastguard Worker const MCFragment *Fragment,
625*9880d681SAndroid Build Coastguard Worker const MCFixup &Fixup, MCValue Target,
626*9880d681SAndroid Build Coastguard Worker bool &IsPCRel, uint64_t &FixedValue) {
627*9880d681SAndroid Build Coastguard Worker const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
628*9880d681SAndroid Build Coastguard Worker uint64_t C = Target.getConstant();
629*9880d681SAndroid Build Coastguard Worker uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
630*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = Asm.getContext();
631*9880d681SAndroid Build Coastguard Worker
632*9880d681SAndroid Build Coastguard Worker if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
633*9880d681SAndroid Build Coastguard Worker assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&
634*9880d681SAndroid Build Coastguard Worker "Should not have constructed this");
635*9880d681SAndroid Build Coastguard Worker
636*9880d681SAndroid Build Coastguard Worker // Let A, B and C being the components of Target and R be the location of
637*9880d681SAndroid Build Coastguard Worker // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
638*9880d681SAndroid Build Coastguard Worker // If it is pcrel, we want to compute (A - B + C - R).
639*9880d681SAndroid Build Coastguard Worker
640*9880d681SAndroid Build Coastguard Worker // In general, ELF has no relocations for -B. It can only represent (A + C)
641*9880d681SAndroid Build Coastguard Worker // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
642*9880d681SAndroid Build Coastguard Worker // replace B to implement it: (A - R - K + C)
643*9880d681SAndroid Build Coastguard Worker if (IsPCRel) {
644*9880d681SAndroid Build Coastguard Worker Ctx.reportError(
645*9880d681SAndroid Build Coastguard Worker Fixup.getLoc(),
646*9880d681SAndroid Build Coastguard Worker "No relocation available to represent this relative expression");
647*9880d681SAndroid Build Coastguard Worker return;
648*9880d681SAndroid Build Coastguard Worker }
649*9880d681SAndroid Build Coastguard Worker
650*9880d681SAndroid Build Coastguard Worker const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
651*9880d681SAndroid Build Coastguard Worker
652*9880d681SAndroid Build Coastguard Worker if (SymB.isUndefined()) {
653*9880d681SAndroid Build Coastguard Worker Ctx.reportError(Fixup.getLoc(),
654*9880d681SAndroid Build Coastguard Worker Twine("symbol '") + SymB.getName() +
655*9880d681SAndroid Build Coastguard Worker "' can not be undefined in a subtraction expression");
656*9880d681SAndroid Build Coastguard Worker return;
657*9880d681SAndroid Build Coastguard Worker }
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker assert(!SymB.isAbsolute() && "Should have been folded");
660*9880d681SAndroid Build Coastguard Worker const MCSection &SecB = SymB.getSection();
661*9880d681SAndroid Build Coastguard Worker if (&SecB != &FixupSection) {
662*9880d681SAndroid Build Coastguard Worker Ctx.reportError(Fixup.getLoc(),
663*9880d681SAndroid Build Coastguard Worker "Cannot represent a difference across sections");
664*9880d681SAndroid Build Coastguard Worker return;
665*9880d681SAndroid Build Coastguard Worker }
666*9880d681SAndroid Build Coastguard Worker
667*9880d681SAndroid Build Coastguard Worker uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
668*9880d681SAndroid Build Coastguard Worker uint64_t K = SymBOffset - FixupOffset;
669*9880d681SAndroid Build Coastguard Worker IsPCRel = true;
670*9880d681SAndroid Build Coastguard Worker C -= K;
671*9880d681SAndroid Build Coastguard Worker }
672*9880d681SAndroid Build Coastguard Worker
673*9880d681SAndroid Build Coastguard Worker // We either rejected the fixup or folded B into C at this point.
674*9880d681SAndroid Build Coastguard Worker const MCSymbolRefExpr *RefA = Target.getSymA();
675*9880d681SAndroid Build Coastguard Worker const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
676*9880d681SAndroid Build Coastguard Worker
677*9880d681SAndroid Build Coastguard Worker bool ViaWeakRef = false;
678*9880d681SAndroid Build Coastguard Worker if (SymA && SymA->isVariable()) {
679*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = SymA->getVariableValue();
680*9880d681SAndroid Build Coastguard Worker if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
681*9880d681SAndroid Build Coastguard Worker if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
682*9880d681SAndroid Build Coastguard Worker SymA = cast<MCSymbolELF>(&Inner->getSymbol());
683*9880d681SAndroid Build Coastguard Worker ViaWeakRef = true;
684*9880d681SAndroid Build Coastguard Worker }
685*9880d681SAndroid Build Coastguard Worker }
686*9880d681SAndroid Build Coastguard Worker }
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker unsigned Type = getRelocType(Ctx, Target, Fixup, IsPCRel);
689*9880d681SAndroid Build Coastguard Worker uint64_t OriginalC = C;
690*9880d681SAndroid Build Coastguard Worker bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
691*9880d681SAndroid Build Coastguard Worker if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
692*9880d681SAndroid Build Coastguard Worker C += Layout.getSymbolOffset(*SymA);
693*9880d681SAndroid Build Coastguard Worker
694*9880d681SAndroid Build Coastguard Worker uint64_t Addend = 0;
695*9880d681SAndroid Build Coastguard Worker if (hasRelocationAddend()) {
696*9880d681SAndroid Build Coastguard Worker Addend = C;
697*9880d681SAndroid Build Coastguard Worker C = 0;
698*9880d681SAndroid Build Coastguard Worker }
699*9880d681SAndroid Build Coastguard Worker
700*9880d681SAndroid Build Coastguard Worker FixedValue = C;
701*9880d681SAndroid Build Coastguard Worker
702*9880d681SAndroid Build Coastguard Worker if (!RelocateWithSymbol) {
703*9880d681SAndroid Build Coastguard Worker const MCSection *SecA =
704*9880d681SAndroid Build Coastguard Worker (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
705*9880d681SAndroid Build Coastguard Worker auto *ELFSec = cast_or_null<MCSectionELF>(SecA);
706*9880d681SAndroid Build Coastguard Worker const auto *SectionSymbol =
707*9880d681SAndroid Build Coastguard Worker ELFSec ? cast<MCSymbolELF>(ELFSec->getBeginSymbol()) : nullptr;
708*9880d681SAndroid Build Coastguard Worker if (SectionSymbol)
709*9880d681SAndroid Build Coastguard Worker SectionSymbol->setUsedInReloc();
710*9880d681SAndroid Build Coastguard Worker ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA,
711*9880d681SAndroid Build Coastguard Worker OriginalC);
712*9880d681SAndroid Build Coastguard Worker Relocations[&FixupSection].push_back(Rec);
713*9880d681SAndroid Build Coastguard Worker return;
714*9880d681SAndroid Build Coastguard Worker }
715*9880d681SAndroid Build Coastguard Worker
716*9880d681SAndroid Build Coastguard Worker const auto *RenamedSymA = SymA;
717*9880d681SAndroid Build Coastguard Worker if (SymA) {
718*9880d681SAndroid Build Coastguard Worker if (const MCSymbolELF *R = Renames.lookup(SymA))
719*9880d681SAndroid Build Coastguard Worker RenamedSymA = R;
720*9880d681SAndroid Build Coastguard Worker
721*9880d681SAndroid Build Coastguard Worker if (ViaWeakRef)
722*9880d681SAndroid Build Coastguard Worker RenamedSymA->setIsWeakrefUsedInReloc();
723*9880d681SAndroid Build Coastguard Worker else
724*9880d681SAndroid Build Coastguard Worker RenamedSymA->setUsedInReloc();
725*9880d681SAndroid Build Coastguard Worker }
726*9880d681SAndroid Build Coastguard Worker ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA,
727*9880d681SAndroid Build Coastguard Worker OriginalC);
728*9880d681SAndroid Build Coastguard Worker Relocations[&FixupSection].push_back(Rec);
729*9880d681SAndroid Build Coastguard Worker }
730*9880d681SAndroid Build Coastguard Worker
isInSymtab(const MCAsmLayout & Layout,const MCSymbolELF & Symbol,bool Used,bool Renamed)731*9880d681SAndroid Build Coastguard Worker bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout,
732*9880d681SAndroid Build Coastguard Worker const MCSymbolELF &Symbol, bool Used,
733*9880d681SAndroid Build Coastguard Worker bool Renamed) {
734*9880d681SAndroid Build Coastguard Worker if (Symbol.isVariable()) {
735*9880d681SAndroid Build Coastguard Worker const MCExpr *Expr = Symbol.getVariableValue();
736*9880d681SAndroid Build Coastguard Worker if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
737*9880d681SAndroid Build Coastguard Worker if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
738*9880d681SAndroid Build Coastguard Worker return false;
739*9880d681SAndroid Build Coastguard Worker }
740*9880d681SAndroid Build Coastguard Worker }
741*9880d681SAndroid Build Coastguard Worker
742*9880d681SAndroid Build Coastguard Worker if (Used)
743*9880d681SAndroid Build Coastguard Worker return true;
744*9880d681SAndroid Build Coastguard Worker
745*9880d681SAndroid Build Coastguard Worker if (Renamed)
746*9880d681SAndroid Build Coastguard Worker return false;
747*9880d681SAndroid Build Coastguard Worker
748*9880d681SAndroid Build Coastguard Worker if (Symbol.isVariable() && Symbol.isUndefined()) {
749*9880d681SAndroid Build Coastguard Worker // FIXME: this is here just to diagnose the case of a var = commmon_sym.
750*9880d681SAndroid Build Coastguard Worker Layout.getBaseSymbol(Symbol);
751*9880d681SAndroid Build Coastguard Worker return false;
752*9880d681SAndroid Build Coastguard Worker }
753*9880d681SAndroid Build Coastguard Worker
754*9880d681SAndroid Build Coastguard Worker if (Symbol.isUndefined() && !Symbol.isBindingSet())
755*9880d681SAndroid Build Coastguard Worker return false;
756*9880d681SAndroid Build Coastguard Worker
757*9880d681SAndroid Build Coastguard Worker if (Symbol.isTemporary())
758*9880d681SAndroid Build Coastguard Worker return false;
759*9880d681SAndroid Build Coastguard Worker
760*9880d681SAndroid Build Coastguard Worker if (Symbol.getType() == ELF::STT_SECTION)
761*9880d681SAndroid Build Coastguard Worker return false;
762*9880d681SAndroid Build Coastguard Worker
763*9880d681SAndroid Build Coastguard Worker return true;
764*9880d681SAndroid Build Coastguard Worker }
765*9880d681SAndroid Build Coastguard Worker
computeSymbolTable(MCAssembler & Asm,const MCAsmLayout & Layout,const SectionIndexMapTy & SectionIndexMap,const RevGroupMapTy & RevGroupMap,SectionOffsetsTy & SectionOffsets)766*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::computeSymbolTable(
767*9880d681SAndroid Build Coastguard Worker MCAssembler &Asm, const MCAsmLayout &Layout,
768*9880d681SAndroid Build Coastguard Worker const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
769*9880d681SAndroid Build Coastguard Worker SectionOffsetsTy &SectionOffsets) {
770*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = Asm.getContext();
771*9880d681SAndroid Build Coastguard Worker SymbolTableWriter Writer(*this, is64Bit());
772*9880d681SAndroid Build Coastguard Worker
773*9880d681SAndroid Build Coastguard Worker // Symbol table
774*9880d681SAndroid Build Coastguard Worker unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
775*9880d681SAndroid Build Coastguard Worker MCSectionELF *SymtabSection =
776*9880d681SAndroid Build Coastguard Worker Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
777*9880d681SAndroid Build Coastguard Worker SymtabSection->setAlignment(is64Bit() ? 8 : 4);
778*9880d681SAndroid Build Coastguard Worker SymbolTableIndex = addToSectionTable(SymtabSection);
779*9880d681SAndroid Build Coastguard Worker
780*9880d681SAndroid Build Coastguard Worker align(SymtabSection->getAlignment());
781*9880d681SAndroid Build Coastguard Worker uint64_t SecStart = getStream().tell();
782*9880d681SAndroid Build Coastguard Worker
783*9880d681SAndroid Build Coastguard Worker // The first entry is the undefined symbol entry.
784*9880d681SAndroid Build Coastguard Worker Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
785*9880d681SAndroid Build Coastguard Worker
786*9880d681SAndroid Build Coastguard Worker std::vector<ELFSymbolData> LocalSymbolData;
787*9880d681SAndroid Build Coastguard Worker std::vector<ELFSymbolData> ExternalSymbolData;
788*9880d681SAndroid Build Coastguard Worker
789*9880d681SAndroid Build Coastguard Worker // Add the data for the symbols.
790*9880d681SAndroid Build Coastguard Worker bool HasLargeSectionIndex = false;
791*9880d681SAndroid Build Coastguard Worker for (const MCSymbol &S : Asm.symbols()) {
792*9880d681SAndroid Build Coastguard Worker const auto &Symbol = cast<MCSymbolELF>(S);
793*9880d681SAndroid Build Coastguard Worker bool Used = Symbol.isUsedInReloc();
794*9880d681SAndroid Build Coastguard Worker bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
795*9880d681SAndroid Build Coastguard Worker bool isSignature = Symbol.isSignature();
796*9880d681SAndroid Build Coastguard Worker
797*9880d681SAndroid Build Coastguard Worker if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
798*9880d681SAndroid Build Coastguard Worker Renames.count(&Symbol)))
799*9880d681SAndroid Build Coastguard Worker continue;
800*9880d681SAndroid Build Coastguard Worker
801*9880d681SAndroid Build Coastguard Worker if (Symbol.isTemporary() && Symbol.isUndefined()) {
802*9880d681SAndroid Build Coastguard Worker Ctx.reportError(SMLoc(), "Undefined temporary symbol");
803*9880d681SAndroid Build Coastguard Worker continue;
804*9880d681SAndroid Build Coastguard Worker }
805*9880d681SAndroid Build Coastguard Worker
806*9880d681SAndroid Build Coastguard Worker ELFSymbolData MSD;
807*9880d681SAndroid Build Coastguard Worker MSD.Symbol = cast<MCSymbolELF>(&Symbol);
808*9880d681SAndroid Build Coastguard Worker
809*9880d681SAndroid Build Coastguard Worker bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
810*9880d681SAndroid Build Coastguard Worker assert(Local || !Symbol.isTemporary());
811*9880d681SAndroid Build Coastguard Worker
812*9880d681SAndroid Build Coastguard Worker if (Symbol.isAbsolute()) {
813*9880d681SAndroid Build Coastguard Worker MSD.SectionIndex = ELF::SHN_ABS;
814*9880d681SAndroid Build Coastguard Worker } else if (Symbol.isCommon()) {
815*9880d681SAndroid Build Coastguard Worker assert(!Local);
816*9880d681SAndroid Build Coastguard Worker MSD.SectionIndex = ELF::SHN_COMMON;
817*9880d681SAndroid Build Coastguard Worker } else if (Symbol.isUndefined()) {
818*9880d681SAndroid Build Coastguard Worker if (isSignature && !Used) {
819*9880d681SAndroid Build Coastguard Worker MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
820*9880d681SAndroid Build Coastguard Worker if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
821*9880d681SAndroid Build Coastguard Worker HasLargeSectionIndex = true;
822*9880d681SAndroid Build Coastguard Worker } else {
823*9880d681SAndroid Build Coastguard Worker MSD.SectionIndex = ELF::SHN_UNDEF;
824*9880d681SAndroid Build Coastguard Worker }
825*9880d681SAndroid Build Coastguard Worker } else {
826*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Section =
827*9880d681SAndroid Build Coastguard Worker static_cast<const MCSectionELF &>(Symbol.getSection());
828*9880d681SAndroid Build Coastguard Worker MSD.SectionIndex = SectionIndexMap.lookup(&Section);
829*9880d681SAndroid Build Coastguard Worker assert(MSD.SectionIndex && "Invalid section index!");
830*9880d681SAndroid Build Coastguard Worker if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
831*9880d681SAndroid Build Coastguard Worker HasLargeSectionIndex = true;
832*9880d681SAndroid Build Coastguard Worker }
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker // The @@@ in symbol version is replaced with @ in undefined symbols and @@
835*9880d681SAndroid Build Coastguard Worker // in defined ones.
836*9880d681SAndroid Build Coastguard Worker //
837*9880d681SAndroid Build Coastguard Worker // FIXME: All name handling should be done before we get to the writer,
838*9880d681SAndroid Build Coastguard Worker // including dealing with GNU-style version suffixes. Fixing this isn't
839*9880d681SAndroid Build Coastguard Worker // trivial.
840*9880d681SAndroid Build Coastguard Worker //
841*9880d681SAndroid Build Coastguard Worker // We thus have to be careful to not perform the symbol version replacement
842*9880d681SAndroid Build Coastguard Worker // blindly:
843*9880d681SAndroid Build Coastguard Worker //
844*9880d681SAndroid Build Coastguard Worker // The ELF format is used on Windows by the MCJIT engine. Thus, on
845*9880d681SAndroid Build Coastguard Worker // Windows, the ELFObjectWriter can encounter symbols mangled using the MS
846*9880d681SAndroid Build Coastguard Worker // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC
847*9880d681SAndroid Build Coastguard Worker // C++ name mangling can legally have "@@@" as a sub-string. In that case,
848*9880d681SAndroid Build Coastguard Worker // the EFLObjectWriter should not interpret the "@@@" sub-string as
849*9880d681SAndroid Build Coastguard Worker // specifying GNU-style symbol versioning. The ELFObjectWriter therefore
850*9880d681SAndroid Build Coastguard Worker // checks for the MSVC C++ name mangling prefix which is either "?", "@?",
851*9880d681SAndroid Build Coastguard Worker // "__imp_?" or "__imp_@?".
852*9880d681SAndroid Build Coastguard Worker //
853*9880d681SAndroid Build Coastguard Worker // It would have been interesting to perform the MS mangling prefix check
854*9880d681SAndroid Build Coastguard Worker // only when the target triple is of the form *-pc-windows-elf. But, it
855*9880d681SAndroid Build Coastguard Worker // seems that this information is not easily accessible from the
856*9880d681SAndroid Build Coastguard Worker // ELFObjectWriter.
857*9880d681SAndroid Build Coastguard Worker StringRef Name = Symbol.getName();
858*9880d681SAndroid Build Coastguard Worker SmallString<32> Buf;
859*9880d681SAndroid Build Coastguard Worker if (!Name.startswith("?") && !Name.startswith("@?") &&
860*9880d681SAndroid Build Coastguard Worker !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) {
861*9880d681SAndroid Build Coastguard Worker // This symbol isn't following the MSVC C++ name mangling convention. We
862*9880d681SAndroid Build Coastguard Worker // can thus safely interpret the @@@ in symbol names as specifying symbol
863*9880d681SAndroid Build Coastguard Worker // versioning.
864*9880d681SAndroid Build Coastguard Worker size_t Pos = Name.find("@@@");
865*9880d681SAndroid Build Coastguard Worker if (Pos != StringRef::npos) {
866*9880d681SAndroid Build Coastguard Worker Buf += Name.substr(0, Pos);
867*9880d681SAndroid Build Coastguard Worker unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1;
868*9880d681SAndroid Build Coastguard Worker Buf += Name.substr(Pos + Skip);
869*9880d681SAndroid Build Coastguard Worker Name = VersionSymSaver.save(Buf.c_str());
870*9880d681SAndroid Build Coastguard Worker }
871*9880d681SAndroid Build Coastguard Worker }
872*9880d681SAndroid Build Coastguard Worker
873*9880d681SAndroid Build Coastguard Worker // Sections have their own string table
874*9880d681SAndroid Build Coastguard Worker if (Symbol.getType() != ELF::STT_SECTION) {
875*9880d681SAndroid Build Coastguard Worker MSD.Name = Name;
876*9880d681SAndroid Build Coastguard Worker StrTabBuilder.add(Name);
877*9880d681SAndroid Build Coastguard Worker }
878*9880d681SAndroid Build Coastguard Worker
879*9880d681SAndroid Build Coastguard Worker if (Local)
880*9880d681SAndroid Build Coastguard Worker LocalSymbolData.push_back(MSD);
881*9880d681SAndroid Build Coastguard Worker else
882*9880d681SAndroid Build Coastguard Worker ExternalSymbolData.push_back(MSD);
883*9880d681SAndroid Build Coastguard Worker }
884*9880d681SAndroid Build Coastguard Worker
885*9880d681SAndroid Build Coastguard Worker // This holds the .symtab_shndx section index.
886*9880d681SAndroid Build Coastguard Worker unsigned SymtabShndxSectionIndex = 0;
887*9880d681SAndroid Build Coastguard Worker
888*9880d681SAndroid Build Coastguard Worker if (HasLargeSectionIndex) {
889*9880d681SAndroid Build Coastguard Worker MCSectionELF *SymtabShndxSection =
890*9880d681SAndroid Build Coastguard Worker Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
891*9880d681SAndroid Build Coastguard Worker SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
892*9880d681SAndroid Build Coastguard Worker SymtabShndxSection->setAlignment(4);
893*9880d681SAndroid Build Coastguard Worker }
894*9880d681SAndroid Build Coastguard Worker
895*9880d681SAndroid Build Coastguard Worker ArrayRef<std::string> FileNames = Asm.getFileNames();
896*9880d681SAndroid Build Coastguard Worker for (const std::string &Name : FileNames)
897*9880d681SAndroid Build Coastguard Worker StrTabBuilder.add(Name);
898*9880d681SAndroid Build Coastguard Worker
899*9880d681SAndroid Build Coastguard Worker StrTabBuilder.finalize();
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker for (const std::string &Name : FileNames)
902*9880d681SAndroid Build Coastguard Worker Writer.writeSymbol(StrTabBuilder.getOffset(Name),
903*9880d681SAndroid Build Coastguard Worker ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
904*9880d681SAndroid Build Coastguard Worker ELF::SHN_ABS, true);
905*9880d681SAndroid Build Coastguard Worker
906*9880d681SAndroid Build Coastguard Worker // Symbols are required to be in lexicographic order.
907*9880d681SAndroid Build Coastguard Worker array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
908*9880d681SAndroid Build Coastguard Worker array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
909*9880d681SAndroid Build Coastguard Worker
910*9880d681SAndroid Build Coastguard Worker // Set the symbol indices. Local symbols must come before all other
911*9880d681SAndroid Build Coastguard Worker // symbols with non-local bindings.
912*9880d681SAndroid Build Coastguard Worker unsigned Index = FileNames.size() + 1;
913*9880d681SAndroid Build Coastguard Worker
914*9880d681SAndroid Build Coastguard Worker for (ELFSymbolData &MSD : LocalSymbolData) {
915*9880d681SAndroid Build Coastguard Worker unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
916*9880d681SAndroid Build Coastguard Worker ? 0
917*9880d681SAndroid Build Coastguard Worker : StrTabBuilder.getOffset(MSD.Name);
918*9880d681SAndroid Build Coastguard Worker MSD.Symbol->setIndex(Index++);
919*9880d681SAndroid Build Coastguard Worker writeSymbol(Writer, StringIndex, MSD, Layout);
920*9880d681SAndroid Build Coastguard Worker }
921*9880d681SAndroid Build Coastguard Worker
922*9880d681SAndroid Build Coastguard Worker // Write the symbol table entries.
923*9880d681SAndroid Build Coastguard Worker LastLocalSymbolIndex = Index;
924*9880d681SAndroid Build Coastguard Worker
925*9880d681SAndroid Build Coastguard Worker for (ELFSymbolData &MSD : ExternalSymbolData) {
926*9880d681SAndroid Build Coastguard Worker unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
927*9880d681SAndroid Build Coastguard Worker MSD.Symbol->setIndex(Index++);
928*9880d681SAndroid Build Coastguard Worker writeSymbol(Writer, StringIndex, MSD, Layout);
929*9880d681SAndroid Build Coastguard Worker assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
930*9880d681SAndroid Build Coastguard Worker }
931*9880d681SAndroid Build Coastguard Worker
932*9880d681SAndroid Build Coastguard Worker uint64_t SecEnd = getStream().tell();
933*9880d681SAndroid Build Coastguard Worker SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
934*9880d681SAndroid Build Coastguard Worker
935*9880d681SAndroid Build Coastguard Worker ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
936*9880d681SAndroid Build Coastguard Worker if (ShndxIndexes.empty()) {
937*9880d681SAndroid Build Coastguard Worker assert(SymtabShndxSectionIndex == 0);
938*9880d681SAndroid Build Coastguard Worker return;
939*9880d681SAndroid Build Coastguard Worker }
940*9880d681SAndroid Build Coastguard Worker assert(SymtabShndxSectionIndex != 0);
941*9880d681SAndroid Build Coastguard Worker
942*9880d681SAndroid Build Coastguard Worker SecStart = getStream().tell();
943*9880d681SAndroid Build Coastguard Worker const MCSectionELF *SymtabShndxSection =
944*9880d681SAndroid Build Coastguard Worker SectionTable[SymtabShndxSectionIndex - 1];
945*9880d681SAndroid Build Coastguard Worker for (uint32_t Index : ShndxIndexes)
946*9880d681SAndroid Build Coastguard Worker write(Index);
947*9880d681SAndroid Build Coastguard Worker SecEnd = getStream().tell();
948*9880d681SAndroid Build Coastguard Worker SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
949*9880d681SAndroid Build Coastguard Worker }
950*9880d681SAndroid Build Coastguard Worker
951*9880d681SAndroid Build Coastguard Worker MCSectionELF *
createRelocationSection(MCContext & Ctx,const MCSectionELF & Sec)952*9880d681SAndroid Build Coastguard Worker ELFObjectWriter::createRelocationSection(MCContext &Ctx,
953*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Sec) {
954*9880d681SAndroid Build Coastguard Worker if (Relocations[&Sec].empty())
955*9880d681SAndroid Build Coastguard Worker return nullptr;
956*9880d681SAndroid Build Coastguard Worker
957*9880d681SAndroid Build Coastguard Worker const StringRef SectionName = Sec.getSectionName();
958*9880d681SAndroid Build Coastguard Worker std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
959*9880d681SAndroid Build Coastguard Worker RelaSectionName += SectionName;
960*9880d681SAndroid Build Coastguard Worker
961*9880d681SAndroid Build Coastguard Worker unsigned EntrySize;
962*9880d681SAndroid Build Coastguard Worker if (hasRelocationAddend())
963*9880d681SAndroid Build Coastguard Worker EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
964*9880d681SAndroid Build Coastguard Worker else
965*9880d681SAndroid Build Coastguard Worker EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
966*9880d681SAndroid Build Coastguard Worker
967*9880d681SAndroid Build Coastguard Worker unsigned Flags = 0;
968*9880d681SAndroid Build Coastguard Worker if (Sec.getFlags() & ELF::SHF_GROUP)
969*9880d681SAndroid Build Coastguard Worker Flags = ELF::SHF_GROUP;
970*9880d681SAndroid Build Coastguard Worker
971*9880d681SAndroid Build Coastguard Worker MCSectionELF *RelaSection = Ctx.createELFRelSection(
972*9880d681SAndroid Build Coastguard Worker RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
973*9880d681SAndroid Build Coastguard Worker Flags, EntrySize, Sec.getGroup(), &Sec);
974*9880d681SAndroid Build Coastguard Worker RelaSection->setAlignment(is64Bit() ? 8 : 4);
975*9880d681SAndroid Build Coastguard Worker return RelaSection;
976*9880d681SAndroid Build Coastguard Worker }
977*9880d681SAndroid Build Coastguard Worker
978*9880d681SAndroid Build Coastguard Worker // Include the debug info compression header.
maybeWriteCompression(uint64_t Size,SmallVectorImpl<char> & CompressedContents,bool ZLibStyle,unsigned Alignment)979*9880d681SAndroid Build Coastguard Worker bool ELFObjectWriter::maybeWriteCompression(
980*9880d681SAndroid Build Coastguard Worker uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
981*9880d681SAndroid Build Coastguard Worker unsigned Alignment) {
982*9880d681SAndroid Build Coastguard Worker if (ZLibStyle) {
983*9880d681SAndroid Build Coastguard Worker uint64_t HdrSize =
984*9880d681SAndroid Build Coastguard Worker is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
985*9880d681SAndroid Build Coastguard Worker if (Size <= HdrSize + CompressedContents.size())
986*9880d681SAndroid Build Coastguard Worker return false;
987*9880d681SAndroid Build Coastguard Worker // Platform specific header is followed by compressed data.
988*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
989*9880d681SAndroid Build Coastguard Worker // Write Elf64_Chdr header.
990*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB));
991*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
992*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf64_Xword>(Size));
993*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf64_Xword>(Alignment));
994*9880d681SAndroid Build Coastguard Worker } else {
995*9880d681SAndroid Build Coastguard Worker // Write Elf32_Chdr header otherwise.
996*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB));
997*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf32_Word>(Size));
998*9880d681SAndroid Build Coastguard Worker write(static_cast<ELF::Elf32_Word>(Alignment));
999*9880d681SAndroid Build Coastguard Worker }
1000*9880d681SAndroid Build Coastguard Worker return true;
1001*9880d681SAndroid Build Coastguard Worker }
1002*9880d681SAndroid Build Coastguard Worker
1003*9880d681SAndroid Build Coastguard Worker // "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
1004*9880d681SAndroid Build Coastguard Worker // useful for consumers to preallocate a buffer to decompress into.
1005*9880d681SAndroid Build Coastguard Worker const StringRef Magic = "ZLIB";
1006*9880d681SAndroid Build Coastguard Worker if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
1007*9880d681SAndroid Build Coastguard Worker return false;
1008*9880d681SAndroid Build Coastguard Worker write(ArrayRef<char>(Magic.begin(), Magic.size()));
1009*9880d681SAndroid Build Coastguard Worker writeBE64(Size);
1010*9880d681SAndroid Build Coastguard Worker return true;
1011*9880d681SAndroid Build Coastguard Worker }
1012*9880d681SAndroid Build Coastguard Worker
writeSectionData(const MCAssembler & Asm,MCSection & Sec,const MCAsmLayout & Layout)1013*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
1014*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) {
1015*9880d681SAndroid Build Coastguard Worker MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1016*9880d681SAndroid Build Coastguard Worker StringRef SectionName = Section.getSectionName();
1017*9880d681SAndroid Build Coastguard Worker
1018*9880d681SAndroid Build Coastguard Worker // Compressing debug_frame requires handling alignment fragments which is
1019*9880d681SAndroid Build Coastguard Worker // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
1020*9880d681SAndroid Build Coastguard Worker // for writing to arbitrary buffers) for little benefit.
1021*9880d681SAndroid Build Coastguard Worker bool CompressionEnabled =
1022*9880d681SAndroid Build Coastguard Worker Asm.getContext().getAsmInfo()->compressDebugSections() !=
1023*9880d681SAndroid Build Coastguard Worker DebugCompressionType::DCT_None;
1024*9880d681SAndroid Build Coastguard Worker if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
1025*9880d681SAndroid Build Coastguard Worker SectionName == ".debug_frame") {
1026*9880d681SAndroid Build Coastguard Worker Asm.writeSectionData(&Section, Layout);
1027*9880d681SAndroid Build Coastguard Worker return;
1028*9880d681SAndroid Build Coastguard Worker }
1029*9880d681SAndroid Build Coastguard Worker
1030*9880d681SAndroid Build Coastguard Worker SmallVector<char, 128> UncompressedData;
1031*9880d681SAndroid Build Coastguard Worker raw_svector_ostream VecOS(UncompressedData);
1032*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream &OldStream = getStream();
1033*9880d681SAndroid Build Coastguard Worker setStream(VecOS);
1034*9880d681SAndroid Build Coastguard Worker Asm.writeSectionData(&Section, Layout);
1035*9880d681SAndroid Build Coastguard Worker setStream(OldStream);
1036*9880d681SAndroid Build Coastguard Worker
1037*9880d681SAndroid Build Coastguard Worker SmallVector<char, 128> CompressedContents;
1038*9880d681SAndroid Build Coastguard Worker zlib::Status Success = zlib::compress(
1039*9880d681SAndroid Build Coastguard Worker StringRef(UncompressedData.data(), UncompressedData.size()),
1040*9880d681SAndroid Build Coastguard Worker CompressedContents);
1041*9880d681SAndroid Build Coastguard Worker if (Success != zlib::StatusOK) {
1042*9880d681SAndroid Build Coastguard Worker getStream() << UncompressedData;
1043*9880d681SAndroid Build Coastguard Worker return;
1044*9880d681SAndroid Build Coastguard Worker }
1045*9880d681SAndroid Build Coastguard Worker
1046*9880d681SAndroid Build Coastguard Worker bool ZlibStyle = Asm.getContext().getAsmInfo()->compressDebugSections() ==
1047*9880d681SAndroid Build Coastguard Worker DebugCompressionType::DCT_Zlib;
1048*9880d681SAndroid Build Coastguard Worker if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
1049*9880d681SAndroid Build Coastguard Worker ZlibStyle, Sec.getAlignment())) {
1050*9880d681SAndroid Build Coastguard Worker getStream() << UncompressedData;
1051*9880d681SAndroid Build Coastguard Worker return;
1052*9880d681SAndroid Build Coastguard Worker }
1053*9880d681SAndroid Build Coastguard Worker
1054*9880d681SAndroid Build Coastguard Worker if (ZlibStyle)
1055*9880d681SAndroid Build Coastguard Worker // Set the compressed flag. That is zlib style.
1056*9880d681SAndroid Build Coastguard Worker Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
1057*9880d681SAndroid Build Coastguard Worker else
1058*9880d681SAndroid Build Coastguard Worker // Add "z" prefix to section name. This is zlib-gnu style.
1059*9880d681SAndroid Build Coastguard Worker Asm.getContext().renameELFSection(&Section,
1060*9880d681SAndroid Build Coastguard Worker (".z" + SectionName.drop_front(1)).str());
1061*9880d681SAndroid Build Coastguard Worker getStream() << CompressedContents;
1062*9880d681SAndroid Build Coastguard Worker }
1063*9880d681SAndroid Build Coastguard Worker
WriteSecHdrEntry(uint32_t Name,uint32_t Type,uint64_t Flags,uint64_t Address,uint64_t Offset,uint64_t Size,uint32_t Link,uint32_t Info,uint64_t Alignment,uint64_t EntrySize)1064*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type,
1065*9880d681SAndroid Build Coastguard Worker uint64_t Flags, uint64_t Address,
1066*9880d681SAndroid Build Coastguard Worker uint64_t Offset, uint64_t Size,
1067*9880d681SAndroid Build Coastguard Worker uint32_t Link, uint32_t Info,
1068*9880d681SAndroid Build Coastguard Worker uint64_t Alignment,
1069*9880d681SAndroid Build Coastguard Worker uint64_t EntrySize) {
1070*9880d681SAndroid Build Coastguard Worker write32(Name); // sh_name: index into string table
1071*9880d681SAndroid Build Coastguard Worker write32(Type); // sh_type
1072*9880d681SAndroid Build Coastguard Worker WriteWord(Flags); // sh_flags
1073*9880d681SAndroid Build Coastguard Worker WriteWord(Address); // sh_addr
1074*9880d681SAndroid Build Coastguard Worker WriteWord(Offset); // sh_offset
1075*9880d681SAndroid Build Coastguard Worker WriteWord(Size); // sh_size
1076*9880d681SAndroid Build Coastguard Worker write32(Link); // sh_link
1077*9880d681SAndroid Build Coastguard Worker write32(Info); // sh_info
1078*9880d681SAndroid Build Coastguard Worker WriteWord(Alignment); // sh_addralign
1079*9880d681SAndroid Build Coastguard Worker WriteWord(EntrySize); // sh_entsize
1080*9880d681SAndroid Build Coastguard Worker }
1081*9880d681SAndroid Build Coastguard Worker
writeRelocations(const MCAssembler & Asm,const MCSectionELF & Sec)1082*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeRelocations(const MCAssembler &Asm,
1083*9880d681SAndroid Build Coastguard Worker const MCSectionELF &Sec) {
1084*9880d681SAndroid Build Coastguard Worker std::vector<ELFRelocationEntry> &Relocs = Relocations[&Sec];
1085*9880d681SAndroid Build Coastguard Worker
1086*9880d681SAndroid Build Coastguard Worker // We record relocations by pushing to the end of a vector. Reverse the vector
1087*9880d681SAndroid Build Coastguard Worker // to get the relocations in the order they were created.
1088*9880d681SAndroid Build Coastguard Worker // In most cases that is not important, but it can be for special sections
1089*9880d681SAndroid Build Coastguard Worker // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
1090*9880d681SAndroid Build Coastguard Worker std::reverse(Relocs.begin(), Relocs.end());
1091*9880d681SAndroid Build Coastguard Worker
1092*9880d681SAndroid Build Coastguard Worker // Sort the relocation entries. MIPS needs this.
1093*9880d681SAndroid Build Coastguard Worker TargetObjectWriter->sortRelocs(Asm, Relocs);
1094*9880d681SAndroid Build Coastguard Worker
1095*9880d681SAndroid Build Coastguard Worker for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
1096*9880d681SAndroid Build Coastguard Worker const ELFRelocationEntry &Entry = Relocs[e - i - 1];
1097*9880d681SAndroid Build Coastguard Worker unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
1098*9880d681SAndroid Build Coastguard Worker
1099*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
1100*9880d681SAndroid Build Coastguard Worker write(Entry.Offset);
1101*9880d681SAndroid Build Coastguard Worker if (TargetObjectWriter->isN64()) {
1102*9880d681SAndroid Build Coastguard Worker write(uint32_t(Index));
1103*9880d681SAndroid Build Coastguard Worker
1104*9880d681SAndroid Build Coastguard Worker write(TargetObjectWriter->getRSsym(Entry.Type));
1105*9880d681SAndroid Build Coastguard Worker write(TargetObjectWriter->getRType3(Entry.Type));
1106*9880d681SAndroid Build Coastguard Worker write(TargetObjectWriter->getRType2(Entry.Type));
1107*9880d681SAndroid Build Coastguard Worker write(TargetObjectWriter->getRType(Entry.Type));
1108*9880d681SAndroid Build Coastguard Worker } else {
1109*9880d681SAndroid Build Coastguard Worker struct ELF::Elf64_Rela ERE64;
1110*9880d681SAndroid Build Coastguard Worker ERE64.setSymbolAndType(Index, Entry.Type);
1111*9880d681SAndroid Build Coastguard Worker write(ERE64.r_info);
1112*9880d681SAndroid Build Coastguard Worker }
1113*9880d681SAndroid Build Coastguard Worker if (hasRelocationAddend())
1114*9880d681SAndroid Build Coastguard Worker write(Entry.Addend);
1115*9880d681SAndroid Build Coastguard Worker } else {
1116*9880d681SAndroid Build Coastguard Worker write(uint32_t(Entry.Offset));
1117*9880d681SAndroid Build Coastguard Worker
1118*9880d681SAndroid Build Coastguard Worker struct ELF::Elf32_Rela ERE32;
1119*9880d681SAndroid Build Coastguard Worker ERE32.setSymbolAndType(Index, Entry.Type);
1120*9880d681SAndroid Build Coastguard Worker write(ERE32.r_info);
1121*9880d681SAndroid Build Coastguard Worker
1122*9880d681SAndroid Build Coastguard Worker if (hasRelocationAddend())
1123*9880d681SAndroid Build Coastguard Worker write(uint32_t(Entry.Addend));
1124*9880d681SAndroid Build Coastguard Worker }
1125*9880d681SAndroid Build Coastguard Worker }
1126*9880d681SAndroid Build Coastguard Worker }
1127*9880d681SAndroid Build Coastguard Worker
createStringTable(MCContext & Ctx)1128*9880d681SAndroid Build Coastguard Worker const MCSectionELF *ELFObjectWriter::createStringTable(MCContext &Ctx) {
1129*9880d681SAndroid Build Coastguard Worker const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
1130*9880d681SAndroid Build Coastguard Worker getStream() << StrTabBuilder.data();
1131*9880d681SAndroid Build Coastguard Worker return StrtabSection;
1132*9880d681SAndroid Build Coastguard Worker }
1133*9880d681SAndroid Build Coastguard Worker
writeSection(const SectionIndexMapTy & SectionIndexMap,uint32_t GroupSymbolIndex,uint64_t Offset,uint64_t Size,const MCSectionELF & Section)1134*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
1135*9880d681SAndroid Build Coastguard Worker uint32_t GroupSymbolIndex, uint64_t Offset,
1136*9880d681SAndroid Build Coastguard Worker uint64_t Size, const MCSectionELF &Section) {
1137*9880d681SAndroid Build Coastguard Worker uint64_t sh_link = 0;
1138*9880d681SAndroid Build Coastguard Worker uint64_t sh_info = 0;
1139*9880d681SAndroid Build Coastguard Worker
1140*9880d681SAndroid Build Coastguard Worker switch(Section.getType()) {
1141*9880d681SAndroid Build Coastguard Worker default:
1142*9880d681SAndroid Build Coastguard Worker // Nothing to do.
1143*9880d681SAndroid Build Coastguard Worker break;
1144*9880d681SAndroid Build Coastguard Worker
1145*9880d681SAndroid Build Coastguard Worker case ELF::SHT_DYNAMIC:
1146*9880d681SAndroid Build Coastguard Worker llvm_unreachable("SHT_DYNAMIC in a relocatable object");
1147*9880d681SAndroid Build Coastguard Worker
1148*9880d681SAndroid Build Coastguard Worker case ELF::SHT_REL:
1149*9880d681SAndroid Build Coastguard Worker case ELF::SHT_RELA: {
1150*9880d681SAndroid Build Coastguard Worker sh_link = SymbolTableIndex;
1151*9880d681SAndroid Build Coastguard Worker assert(sh_link && ".symtab not found");
1152*9880d681SAndroid Build Coastguard Worker const MCSectionELF *InfoSection = Section.getAssociatedSection();
1153*9880d681SAndroid Build Coastguard Worker sh_info = SectionIndexMap.lookup(InfoSection);
1154*9880d681SAndroid Build Coastguard Worker break;
1155*9880d681SAndroid Build Coastguard Worker }
1156*9880d681SAndroid Build Coastguard Worker
1157*9880d681SAndroid Build Coastguard Worker case ELF::SHT_SYMTAB:
1158*9880d681SAndroid Build Coastguard Worker case ELF::SHT_DYNSYM:
1159*9880d681SAndroid Build Coastguard Worker sh_link = StringTableIndex;
1160*9880d681SAndroid Build Coastguard Worker sh_info = LastLocalSymbolIndex;
1161*9880d681SAndroid Build Coastguard Worker break;
1162*9880d681SAndroid Build Coastguard Worker
1163*9880d681SAndroid Build Coastguard Worker case ELF::SHT_SYMTAB_SHNDX:
1164*9880d681SAndroid Build Coastguard Worker sh_link = SymbolTableIndex;
1165*9880d681SAndroid Build Coastguard Worker break;
1166*9880d681SAndroid Build Coastguard Worker
1167*9880d681SAndroid Build Coastguard Worker case ELF::SHT_GROUP:
1168*9880d681SAndroid Build Coastguard Worker sh_link = SymbolTableIndex;
1169*9880d681SAndroid Build Coastguard Worker sh_info = GroupSymbolIndex;
1170*9880d681SAndroid Build Coastguard Worker break;
1171*9880d681SAndroid Build Coastguard Worker }
1172*9880d681SAndroid Build Coastguard Worker
1173*9880d681SAndroid Build Coastguard Worker if (TargetObjectWriter->getEMachine() == ELF::EM_ARM &&
1174*9880d681SAndroid Build Coastguard Worker Section.getType() == ELF::SHT_ARM_EXIDX)
1175*9880d681SAndroid Build Coastguard Worker sh_link = SectionIndexMap.lookup(Section.getAssociatedSection());
1176*9880d681SAndroid Build Coastguard Worker
1177*9880d681SAndroid Build Coastguard Worker WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
1178*9880d681SAndroid Build Coastguard Worker Section.getType(), Section.getFlags(), 0, Offset, Size,
1179*9880d681SAndroid Build Coastguard Worker sh_link, sh_info, Section.getAlignment(),
1180*9880d681SAndroid Build Coastguard Worker Section.getEntrySize());
1181*9880d681SAndroid Build Coastguard Worker }
1182*9880d681SAndroid Build Coastguard Worker
writeSectionHeader(const MCAsmLayout & Layout,const SectionIndexMapTy & SectionIndexMap,const SectionOffsetsTy & SectionOffsets)1183*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeSectionHeader(
1184*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
1185*9880d681SAndroid Build Coastguard Worker const SectionOffsetsTy &SectionOffsets) {
1186*9880d681SAndroid Build Coastguard Worker const unsigned NumSections = SectionTable.size();
1187*9880d681SAndroid Build Coastguard Worker
1188*9880d681SAndroid Build Coastguard Worker // Null section first.
1189*9880d681SAndroid Build Coastguard Worker uint64_t FirstSectionSize =
1190*9880d681SAndroid Build Coastguard Worker (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
1191*9880d681SAndroid Build Coastguard Worker WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
1192*9880d681SAndroid Build Coastguard Worker
1193*9880d681SAndroid Build Coastguard Worker for (const MCSectionELF *Section : SectionTable) {
1194*9880d681SAndroid Build Coastguard Worker uint32_t GroupSymbolIndex;
1195*9880d681SAndroid Build Coastguard Worker unsigned Type = Section->getType();
1196*9880d681SAndroid Build Coastguard Worker if (Type != ELF::SHT_GROUP)
1197*9880d681SAndroid Build Coastguard Worker GroupSymbolIndex = 0;
1198*9880d681SAndroid Build Coastguard Worker else
1199*9880d681SAndroid Build Coastguard Worker GroupSymbolIndex = Section->getGroup()->getIndex();
1200*9880d681SAndroid Build Coastguard Worker
1201*9880d681SAndroid Build Coastguard Worker const std::pair<uint64_t, uint64_t> &Offsets =
1202*9880d681SAndroid Build Coastguard Worker SectionOffsets.find(Section)->second;
1203*9880d681SAndroid Build Coastguard Worker uint64_t Size;
1204*9880d681SAndroid Build Coastguard Worker if (Type == ELF::SHT_NOBITS)
1205*9880d681SAndroid Build Coastguard Worker Size = Layout.getSectionAddressSize(Section);
1206*9880d681SAndroid Build Coastguard Worker else
1207*9880d681SAndroid Build Coastguard Worker Size = Offsets.second - Offsets.first;
1208*9880d681SAndroid Build Coastguard Worker
1209*9880d681SAndroid Build Coastguard Worker writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
1210*9880d681SAndroid Build Coastguard Worker *Section);
1211*9880d681SAndroid Build Coastguard Worker }
1212*9880d681SAndroid Build Coastguard Worker }
1213*9880d681SAndroid Build Coastguard Worker
writeObject(MCAssembler & Asm,const MCAsmLayout & Layout)1214*9880d681SAndroid Build Coastguard Worker void ELFObjectWriter::writeObject(MCAssembler &Asm,
1215*9880d681SAndroid Build Coastguard Worker const MCAsmLayout &Layout) {
1216*9880d681SAndroid Build Coastguard Worker MCContext &Ctx = Asm.getContext();
1217*9880d681SAndroid Build Coastguard Worker MCSectionELF *StrtabSection =
1218*9880d681SAndroid Build Coastguard Worker Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1219*9880d681SAndroid Build Coastguard Worker StringTableIndex = addToSectionTable(StrtabSection);
1220*9880d681SAndroid Build Coastguard Worker
1221*9880d681SAndroid Build Coastguard Worker RevGroupMapTy RevGroupMap;
1222*9880d681SAndroid Build Coastguard Worker SectionIndexMapTy SectionIndexMap;
1223*9880d681SAndroid Build Coastguard Worker
1224*9880d681SAndroid Build Coastguard Worker std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
1225*9880d681SAndroid Build Coastguard Worker
1226*9880d681SAndroid Build Coastguard Worker // Write out the ELF header ...
1227*9880d681SAndroid Build Coastguard Worker writeHeader(Asm);
1228*9880d681SAndroid Build Coastguard Worker
1229*9880d681SAndroid Build Coastguard Worker // ... then the sections ...
1230*9880d681SAndroid Build Coastguard Worker SectionOffsetsTy SectionOffsets;
1231*9880d681SAndroid Build Coastguard Worker std::vector<MCSectionELF *> Groups;
1232*9880d681SAndroid Build Coastguard Worker std::vector<MCSectionELF *> Relocations;
1233*9880d681SAndroid Build Coastguard Worker for (MCSection &Sec : Asm) {
1234*9880d681SAndroid Build Coastguard Worker MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
1235*9880d681SAndroid Build Coastguard Worker
1236*9880d681SAndroid Build Coastguard Worker align(Section.getAlignment());
1237*9880d681SAndroid Build Coastguard Worker
1238*9880d681SAndroid Build Coastguard Worker // Remember the offset into the file for this section.
1239*9880d681SAndroid Build Coastguard Worker uint64_t SecStart = getStream().tell();
1240*9880d681SAndroid Build Coastguard Worker
1241*9880d681SAndroid Build Coastguard Worker const MCSymbolELF *SignatureSymbol = Section.getGroup();
1242*9880d681SAndroid Build Coastguard Worker writeSectionData(Asm, Section, Layout);
1243*9880d681SAndroid Build Coastguard Worker
1244*9880d681SAndroid Build Coastguard Worker uint64_t SecEnd = getStream().tell();
1245*9880d681SAndroid Build Coastguard Worker SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1246*9880d681SAndroid Build Coastguard Worker
1247*9880d681SAndroid Build Coastguard Worker MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
1248*9880d681SAndroid Build Coastguard Worker
1249*9880d681SAndroid Build Coastguard Worker if (SignatureSymbol) {
1250*9880d681SAndroid Build Coastguard Worker Asm.registerSymbol(*SignatureSymbol);
1251*9880d681SAndroid Build Coastguard Worker unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1252*9880d681SAndroid Build Coastguard Worker if (!GroupIdx) {
1253*9880d681SAndroid Build Coastguard Worker MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
1254*9880d681SAndroid Build Coastguard Worker GroupIdx = addToSectionTable(Group);
1255*9880d681SAndroid Build Coastguard Worker Group->setAlignment(4);
1256*9880d681SAndroid Build Coastguard Worker Groups.push_back(Group);
1257*9880d681SAndroid Build Coastguard Worker }
1258*9880d681SAndroid Build Coastguard Worker std::vector<const MCSectionELF *> &Members =
1259*9880d681SAndroid Build Coastguard Worker GroupMembers[SignatureSymbol];
1260*9880d681SAndroid Build Coastguard Worker Members.push_back(&Section);
1261*9880d681SAndroid Build Coastguard Worker if (RelSection)
1262*9880d681SAndroid Build Coastguard Worker Members.push_back(RelSection);
1263*9880d681SAndroid Build Coastguard Worker }
1264*9880d681SAndroid Build Coastguard Worker
1265*9880d681SAndroid Build Coastguard Worker SectionIndexMap[&Section] = addToSectionTable(&Section);
1266*9880d681SAndroid Build Coastguard Worker if (RelSection) {
1267*9880d681SAndroid Build Coastguard Worker SectionIndexMap[RelSection] = addToSectionTable(RelSection);
1268*9880d681SAndroid Build Coastguard Worker Relocations.push_back(RelSection);
1269*9880d681SAndroid Build Coastguard Worker }
1270*9880d681SAndroid Build Coastguard Worker }
1271*9880d681SAndroid Build Coastguard Worker
1272*9880d681SAndroid Build Coastguard Worker for (MCSectionELF *Group : Groups) {
1273*9880d681SAndroid Build Coastguard Worker align(Group->getAlignment());
1274*9880d681SAndroid Build Coastguard Worker
1275*9880d681SAndroid Build Coastguard Worker // Remember the offset into the file for this section.
1276*9880d681SAndroid Build Coastguard Worker uint64_t SecStart = getStream().tell();
1277*9880d681SAndroid Build Coastguard Worker
1278*9880d681SAndroid Build Coastguard Worker const MCSymbol *SignatureSymbol = Group->getGroup();
1279*9880d681SAndroid Build Coastguard Worker assert(SignatureSymbol);
1280*9880d681SAndroid Build Coastguard Worker write(uint32_t(ELF::GRP_COMDAT));
1281*9880d681SAndroid Build Coastguard Worker for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1282*9880d681SAndroid Build Coastguard Worker uint32_t SecIndex = SectionIndexMap.lookup(Member);
1283*9880d681SAndroid Build Coastguard Worker write(SecIndex);
1284*9880d681SAndroid Build Coastguard Worker }
1285*9880d681SAndroid Build Coastguard Worker
1286*9880d681SAndroid Build Coastguard Worker uint64_t SecEnd = getStream().tell();
1287*9880d681SAndroid Build Coastguard Worker SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1288*9880d681SAndroid Build Coastguard Worker }
1289*9880d681SAndroid Build Coastguard Worker
1290*9880d681SAndroid Build Coastguard Worker // Compute symbol table information.
1291*9880d681SAndroid Build Coastguard Worker computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets);
1292*9880d681SAndroid Build Coastguard Worker
1293*9880d681SAndroid Build Coastguard Worker for (MCSectionELF *RelSection : Relocations) {
1294*9880d681SAndroid Build Coastguard Worker align(RelSection->getAlignment());
1295*9880d681SAndroid Build Coastguard Worker
1296*9880d681SAndroid Build Coastguard Worker // Remember the offset into the file for this section.
1297*9880d681SAndroid Build Coastguard Worker uint64_t SecStart = getStream().tell();
1298*9880d681SAndroid Build Coastguard Worker
1299*9880d681SAndroid Build Coastguard Worker writeRelocations(Asm, *RelSection->getAssociatedSection());
1300*9880d681SAndroid Build Coastguard Worker
1301*9880d681SAndroid Build Coastguard Worker uint64_t SecEnd = getStream().tell();
1302*9880d681SAndroid Build Coastguard Worker SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1303*9880d681SAndroid Build Coastguard Worker }
1304*9880d681SAndroid Build Coastguard Worker
1305*9880d681SAndroid Build Coastguard Worker {
1306*9880d681SAndroid Build Coastguard Worker uint64_t SecStart = getStream().tell();
1307*9880d681SAndroid Build Coastguard Worker const MCSectionELF *Sec = createStringTable(Ctx);
1308*9880d681SAndroid Build Coastguard Worker uint64_t SecEnd = getStream().tell();
1309*9880d681SAndroid Build Coastguard Worker SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
1310*9880d681SAndroid Build Coastguard Worker }
1311*9880d681SAndroid Build Coastguard Worker
1312*9880d681SAndroid Build Coastguard Worker uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
1313*9880d681SAndroid Build Coastguard Worker align(NaturalAlignment);
1314*9880d681SAndroid Build Coastguard Worker
1315*9880d681SAndroid Build Coastguard Worker const uint64_t SectionHeaderOffset = getStream().tell();
1316*9880d681SAndroid Build Coastguard Worker
1317*9880d681SAndroid Build Coastguard Worker // ... then the section header table ...
1318*9880d681SAndroid Build Coastguard Worker writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
1319*9880d681SAndroid Build Coastguard Worker
1320*9880d681SAndroid Build Coastguard Worker uint16_t NumSections = (SectionTable.size() + 1 >= ELF::SHN_LORESERVE)
1321*9880d681SAndroid Build Coastguard Worker ? (uint16_t)ELF::SHN_UNDEF
1322*9880d681SAndroid Build Coastguard Worker : SectionTable.size() + 1;
1323*9880d681SAndroid Build Coastguard Worker if (sys::IsLittleEndianHost != IsLittleEndian)
1324*9880d681SAndroid Build Coastguard Worker sys::swapByteOrder(NumSections);
1325*9880d681SAndroid Build Coastguard Worker unsigned NumSectionsOffset;
1326*9880d681SAndroid Build Coastguard Worker
1327*9880d681SAndroid Build Coastguard Worker if (is64Bit()) {
1328*9880d681SAndroid Build Coastguard Worker uint64_t Val = SectionHeaderOffset;
1329*9880d681SAndroid Build Coastguard Worker if (sys::IsLittleEndianHost != IsLittleEndian)
1330*9880d681SAndroid Build Coastguard Worker sys::swapByteOrder(Val);
1331*9880d681SAndroid Build Coastguard Worker getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1332*9880d681SAndroid Build Coastguard Worker offsetof(ELF::Elf64_Ehdr, e_shoff));
1333*9880d681SAndroid Build Coastguard Worker NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
1334*9880d681SAndroid Build Coastguard Worker } else {
1335*9880d681SAndroid Build Coastguard Worker uint32_t Val = SectionHeaderOffset;
1336*9880d681SAndroid Build Coastguard Worker if (sys::IsLittleEndianHost != IsLittleEndian)
1337*9880d681SAndroid Build Coastguard Worker sys::swapByteOrder(Val);
1338*9880d681SAndroid Build Coastguard Worker getStream().pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1339*9880d681SAndroid Build Coastguard Worker offsetof(ELF::Elf32_Ehdr, e_shoff));
1340*9880d681SAndroid Build Coastguard Worker NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
1341*9880d681SAndroid Build Coastguard Worker }
1342*9880d681SAndroid Build Coastguard Worker getStream().pwrite(reinterpret_cast<char *>(&NumSections),
1343*9880d681SAndroid Build Coastguard Worker sizeof(NumSections), NumSectionsOffset);
1344*9880d681SAndroid Build Coastguard Worker }
1345*9880d681SAndroid Build Coastguard Worker
isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler & Asm,const MCSymbol & SA,const MCFragment & FB,bool InSet,bool IsPCRel) const1346*9880d681SAndroid Build Coastguard Worker bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
1347*9880d681SAndroid Build Coastguard Worker const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
1348*9880d681SAndroid Build Coastguard Worker bool InSet, bool IsPCRel) const {
1349*9880d681SAndroid Build Coastguard Worker const auto &SymA = cast<MCSymbolELF>(SA);
1350*9880d681SAndroid Build Coastguard Worker if (IsPCRel) {
1351*9880d681SAndroid Build Coastguard Worker assert(!InSet);
1352*9880d681SAndroid Build Coastguard Worker if (::isWeak(SymA))
1353*9880d681SAndroid Build Coastguard Worker return false;
1354*9880d681SAndroid Build Coastguard Worker }
1355*9880d681SAndroid Build Coastguard Worker return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
1356*9880d681SAndroid Build Coastguard Worker InSet, IsPCRel);
1357*9880d681SAndroid Build Coastguard Worker }
1358*9880d681SAndroid Build Coastguard Worker
isWeak(const MCSymbol & S) const1359*9880d681SAndroid Build Coastguard Worker bool ELFObjectWriter::isWeak(const MCSymbol &S) const {
1360*9880d681SAndroid Build Coastguard Worker const auto &Sym = cast<MCSymbolELF>(S);
1361*9880d681SAndroid Build Coastguard Worker if (::isWeak(Sym))
1362*9880d681SAndroid Build Coastguard Worker return true;
1363*9880d681SAndroid Build Coastguard Worker
1364*9880d681SAndroid Build Coastguard Worker // It is invalid to replace a reference to a global in a comdat
1365*9880d681SAndroid Build Coastguard Worker // with a reference to a local since out of comdat references
1366*9880d681SAndroid Build Coastguard Worker // to a local are forbidden.
1367*9880d681SAndroid Build Coastguard Worker // We could try to return false for more cases, like the reference
1368*9880d681SAndroid Build Coastguard Worker // being in the same comdat or Sym being an alias to another global,
1369*9880d681SAndroid Build Coastguard Worker // but it is not clear if it is worth the effort.
1370*9880d681SAndroid Build Coastguard Worker if (Sym.getBinding() != ELF::STB_GLOBAL)
1371*9880d681SAndroid Build Coastguard Worker return false;
1372*9880d681SAndroid Build Coastguard Worker
1373*9880d681SAndroid Build Coastguard Worker if (!Sym.isInSection())
1374*9880d681SAndroid Build Coastguard Worker return false;
1375*9880d681SAndroid Build Coastguard Worker
1376*9880d681SAndroid Build Coastguard Worker const auto &Sec = cast<MCSectionELF>(Sym.getSection());
1377*9880d681SAndroid Build Coastguard Worker return Sec.getGroup();
1378*9880d681SAndroid Build Coastguard Worker }
1379*9880d681SAndroid Build Coastguard Worker
createELFObjectWriter(MCELFObjectTargetWriter * MOTW,raw_pwrite_stream & OS,bool IsLittleEndian)1380*9880d681SAndroid Build Coastguard Worker MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW,
1381*9880d681SAndroid Build Coastguard Worker raw_pwrite_stream &OS,
1382*9880d681SAndroid Build Coastguard Worker bool IsLittleEndian) {
1383*9880d681SAndroid Build Coastguard Worker return new ELFObjectWriter(MOTW, OS, IsLittleEndian);
1384*9880d681SAndroid Build Coastguard Worker }
1385