xref: /aosp_15_r20/external/llvm/lib/MC/ELFObjectWriter.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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