blob: ade858113a300944a3e2e8dd8cc3b9bca99268e7 [file] [log] [blame]
Nick Lewycky7394c5a2013-03-09 09:32:16 +00001//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
Matt Fleming3565a062010-08-16 18:57:57 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements ELF object file writer information.
11//
12//===----------------------------------------------------------------------===//
13
Eugene Zelenkoa700a602017-02-11 00:27:28 +000014#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/DenseMap.h"
Chandler Carruthe3e43d92017-06-06 11:49:48 +000016#include "llvm/ADT/STLExtras.h"
Rafael Espindola3963d612011-12-22 03:38:00 +000017#include "llvm/ADT/SmallString.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000018#include "llvm/ADT/SmallVector.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000019#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.h"
Zachary Turner19ca2b02017-06-07 03:48:56 +000021#include "llvm/BinaryFormat/ELF.h"
Rafael Espindola210f5222017-07-11 23:56:10 +000022#include "llvm/MC/MCAsmBackend.h"
David Blaikiefe255212014-04-10 21:53:53 +000023#include "llvm/MC/MCAsmInfo.h"
Matt Fleming3565a062010-08-16 18:57:57 +000024#include "llvm/MC/MCAsmLayout.h"
Rafael Espindola3963d612011-12-22 03:38:00 +000025#include "llvm/MC/MCAssembler.h"
Matt Fleming3565a062010-08-16 18:57:57 +000026#include "llvm/MC/MCContext.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000027#include "llvm/MC/MCELFObjectWriter.h"
Matt Fleming3565a062010-08-16 18:57:57 +000028#include "llvm/MC/MCExpr.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000029#include "llvm/MC/MCFixup.h"
Rafael Espindola210f5222017-07-11 23:56:10 +000030#include "llvm/MC/MCFixupKindInfo.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000031#include "llvm/MC/MCFragment.h"
Eric Christopher42eb0822018-09-06 22:09:31 +000032#include "llvm/MC/MCObjectFileInfo.h"
Craig Topperf1d0f772012-03-26 06:58:25 +000033#include "llvm/MC/MCObjectWriter.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000034#include "llvm/MC/MCSection.h"
Matt Fleming3565a062010-08-16 18:57:57 +000035#include "llvm/MC/MCSectionELF.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000036#include "llvm/MC/MCSymbol.h"
Rafael Espindolaf7e06852015-06-02 00:25:12 +000037#include "llvm/MC/MCSymbolELF.h"
Matt Fleming3565a062010-08-16 18:57:57 +000038#include "llvm/MC/MCValue.h"
Rafael Espindola7413fef2014-07-03 02:01:39 +000039#include "llvm/MC/StringTableBuilder.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000040#include "llvm/Support/Allocator.h"
41#include "llvm/Support/Casting.h"
David Blaikiefe255212014-04-10 21:53:53 +000042#include "llvm/Support/Compression.h"
Chandler Carruth1b279142015-01-14 11:23:27 +000043#include "llvm/Support/Endian.h"
George Rimaref935cd2017-01-17 15:45:07 +000044#include "llvm/Support/Error.h"
Chandler Carruthd04a8d42012-12-03 16:50:05 +000045#include "llvm/Support/ErrorHandling.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000046#include "llvm/Support/Host.h"
Peter Collingbournea29ff2e2018-07-17 22:17:18 +000047#include "llvm/Support/LEB128.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000048#include "llvm/Support/MathExtras.h"
49#include "llvm/Support/SMLoc.h"
Rafael Espindolad43c0012015-10-22 18:32:06 +000050#include "llvm/Support/StringSaver.h"
Eugene Zelenkoa700a602017-02-11 00:27:28 +000051#include "llvm/Support/SwapByteOrder.h"
52#include "llvm/Support/raw_ostream.h"
53#include <algorithm>
54#include <cassert>
55#include <cstddef>
56#include <cstdint>
57#include <map>
58#include <memory>
59#include <string>
60#include <utility>
Matt Fleming3565a062010-08-16 18:57:57 +000061#include <vector>
Eugene Zelenko380d47d2016-02-02 18:20:45 +000062
Matt Fleming3565a062010-08-16 18:57:57 +000063using namespace llvm;
64
Jason W Kime964d112011-05-11 22:53:06 +000065#undef DEBUG_TYPE
66#define DEBUG_TYPE "reloc-info"
67
Rafael Espindola3963d612011-12-22 03:38:00 +000068namespace {
Eugene Zelenkoa700a602017-02-11 00:27:28 +000069
Eugene Zelenkof49f90e2017-04-26 22:31:39 +000070using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
Rafael Espindola81c66bc2014-03-25 23:44:25 +000071
Rafael Espindola5fc37692015-04-29 21:09:32 +000072class ELFObjectWriter;
Peter Collingbourne815bbef2018-05-21 19:18:28 +000073struct ELFWriter;
Rafael Espindola5fc37692015-04-29 21:09:32 +000074
Peter Collingbourne60fd99d2018-05-21 19:44:54 +000075bool isDwoSection(const MCSectionELF &Sec) {
76 return Sec.getSectionName().endswith(".dwo");
77}
78
Rafael Espindola81c66bc2014-03-25 23:44:25 +000079class SymbolTableWriter {
Peter Collingbourne815bbef2018-05-21 19:18:28 +000080 ELFWriter &EWriter;
Rafael Espindola81c66bc2014-03-25 23:44:25 +000081 bool Is64Bit;
Rafael Espindola81c66bc2014-03-25 23:44:25 +000082
Rafael Espindola5fc37692015-04-29 21:09:32 +000083 // indexes we are going to write to .symtab_shndx.
84 std::vector<uint32_t> ShndxIndexes;
Rafael Espindola81c66bc2014-03-25 23:44:25 +000085
86 // The numbel of symbols written so far.
87 unsigned NumWritten;
88
89 void createSymtabShndx();
90
Rafael Espindola5fc37692015-04-29 21:09:32 +000091 template <typename T> void write(T Value);
Rafael Espindola81c66bc2014-03-25 23:44:25 +000092
93public:
Peter Collingbourne815bbef2018-05-21 19:18:28 +000094 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
Rafael Espindola81c66bc2014-03-25 23:44:25 +000095
96 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
97 uint8_t other, uint32_t shndx, bool Reserved);
Rafael Espindola5fc37692015-04-29 21:09:32 +000098
99 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000100};
101
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000102struct ELFWriter {
103 ELFObjectWriter &OWriter;
104 support::endian::Writer W;
105
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000106 enum DwoMode {
107 AllSections,
108 NonDwoOnly,
109 DwoOnly,
110 } Mode;
111
David Blaikie23d05792016-04-12 21:45:53 +0000112 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
113 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
114 bool Used, bool Renamed);
Rafael Espindola3963d612011-12-22 03:38:00 +0000115
David Blaikie23d05792016-04-12 21:45:53 +0000116 /// Helper struct for containing some precomputed information on symbols.
117 struct ELFSymbolData {
118 const MCSymbolELF *Symbol;
119 uint32_t SectionIndex;
120 StringRef Name;
Rafael Espindola3963d612011-12-22 03:38:00 +0000121
David Blaikie23d05792016-04-12 21:45:53 +0000122 // Support lexicographic sorting.
123 bool operator<(const ELFSymbolData &RHS) const {
124 unsigned LHSType = Symbol->getType();
125 unsigned RHSType = RHS.Symbol->getType();
126 if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
127 return false;
128 if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
129 return true;
130 if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
131 return SectionIndex < RHS.SectionIndex;
132 return Name < RHS.Name;
Rafael Espindola3963d612011-12-22 03:38:00 +0000133 }
Rafael Espindola3963d612011-12-22 03:38:00 +0000134 };
David Blaikie23d05792016-04-12 21:45:53 +0000135
David Blaikie23d05792016-04-12 21:45:53 +0000136 /// @}
137 /// @name Symbol Table Data
138 /// @{
139
David Blaikie23d05792016-04-12 21:45:53 +0000140 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
141
142 /// @}
143
144 // This holds the symbol table index of the last local symbol.
145 unsigned LastLocalSymbolIndex;
146 // This holds the .strtab section index.
147 unsigned StringTableIndex;
148 // This holds the .symtab section index.
149 unsigned SymbolTableIndex;
150
151 // Sections in the order they are to be output in the section table.
152 std::vector<const MCSectionELF *> SectionTable;
153 unsigned addToSectionTable(const MCSectionELF *Sec);
154
155 // TargetObjectWriter wrappers.
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000156 bool is64Bit() const;
157 bool hasRelocationAddend() const;
David Blaikie23d05792016-04-12 21:45:53 +0000158
159 void align(unsigned Alignment);
160
George Rimarec285af2016-05-27 12:27:32 +0000161 bool maybeWriteCompression(uint64_t Size,
162 SmallVectorImpl<char> &CompressedContents,
163 bool ZLibStyle, unsigned Alignment);
164
David Blaikie23d05792016-04-12 21:45:53 +0000165public:
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000166 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000167 bool IsLittleEndian, DwoMode Mode)
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000168 : OWriter(OWriter),
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000169 W(OS, IsLittleEndian ? support::little : support::big), Mode(Mode) {}
David Blaikie23d05792016-04-12 21:45:53 +0000170
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000171 void WriteWord(uint64_t Word) {
David Blaikie23d05792016-04-12 21:45:53 +0000172 if (is64Bit())
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000173 W.write<uint64_t>(Word);
David Blaikie23d05792016-04-12 21:45:53 +0000174 else
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000175 W.write<uint32_t>(Word);
David Blaikie23d05792016-04-12 21:45:53 +0000176 }
177
178 template <typename T> void write(T Val) {
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000179 W.write(Val);
David Blaikie23d05792016-04-12 21:45:53 +0000180 }
181
182 void writeHeader(const MCAssembler &Asm);
183
184 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
185 ELFSymbolData &MSD, const MCAsmLayout &Layout);
186
187 // Start and end offset of each section
Eugene Zelenkof49f90e2017-04-26 22:31:39 +0000188 using SectionOffsetsTy =
189 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
David Blaikie23d05792016-04-12 21:45:53 +0000190
David Blaikie23d05792016-04-12 21:45:53 +0000191 // Map from a signature symbol to the group section index
Eugene Zelenkof49f90e2017-04-26 22:31:39 +0000192 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
David Blaikie23d05792016-04-12 21:45:53 +0000193
194 /// Compute the symbol table data
195 ///
196 /// \param Asm - The assembler.
197 /// \param SectionIndexMap - Maps a section to its index.
198 /// \param RevGroupMap - Maps a signature symbol to the group section.
199 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
200 const SectionIndexMapTy &SectionIndexMap,
201 const RevGroupMapTy &RevGroupMap,
202 SectionOffsetsTy &SectionOffsets);
203
Peter Collingbournea29ff2e2018-07-17 22:17:18 +0000204 void writeAddrsigSection();
205
David Blaikie23d05792016-04-12 21:45:53 +0000206 MCSectionELF *createRelocationSection(MCContext &Ctx,
207 const MCSectionELF &Sec);
208
209 const MCSectionELF *createStringTable(MCContext &Ctx);
210
David Blaikie23d05792016-04-12 21:45:53 +0000211 void writeSectionHeader(const MCAsmLayout &Layout,
212 const SectionIndexMapTy &SectionIndexMap,
213 const SectionOffsetsTy &SectionOffsets);
214
215 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
216 const MCAsmLayout &Layout);
217
218 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
219 uint64_t Address, uint64_t Offset, uint64_t Size,
220 uint32_t Link, uint32_t Info, uint64_t Alignment,
221 uint64_t EntrySize);
222
223 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
224
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000225 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
David Blaikie23d05792016-04-12 21:45:53 +0000226 void writeSection(const SectionIndexMapTy &SectionIndexMap,
227 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
228 const MCSectionELF &Section);
229};
Eugene Zelenkoa700a602017-02-11 00:27:28 +0000230
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000231class ELFObjectWriter : public MCObjectWriter {
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000232 /// The target specific ELF writer instance.
233 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
234
235 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
236
237 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
238
Peter Collingbournea29ff2e2018-07-17 22:17:18 +0000239 bool EmitAddrsigSection = false;
240 std::vector<const MCSymbol *> AddrsigSyms;
241
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000242 bool hasRelocationAddend() const;
243
244 bool shouldRelocateWithSymbol(const MCAssembler &Asm,
245 const MCSymbolRefExpr *RefA,
246 const MCSymbolELF *Sym, uint64_t C,
247 unsigned Type) const;
248
249public:
Peter Collingbourne4ef18412018-05-21 19:30:59 +0000250 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW)
251 : TargetObjectWriter(std::move(MOTW)) {}
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000252
253 void reset() override {
254 Relocations.clear();
255 Renames.clear();
256 MCObjectWriter::reset();
257 }
258
259 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
260 const MCSymbol &SymA,
261 const MCFragment &FB, bool InSet,
262 bool IsPCRel) const override;
263
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000264 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
265 const MCSectionELF *From,
266 const MCSectionELF *To) {
267 return true;
268 }
269
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000270 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
271 const MCFragment *Fragment, const MCFixup &Fixup,
272 MCValue Target, uint64_t &FixedValue) override;
273
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000274 void executePostLayoutBinding(MCAssembler &Asm,
275 const MCAsmLayout &Layout) override;
276
Peter Collingbournea29ff2e2018-07-17 22:17:18 +0000277 void emitAddrsigSection() override { EmitAddrsigSection = true; }
278 void addAddrsigSymbol(const MCSymbol *Sym) override {
279 AddrsigSyms.push_back(Sym);
280 }
281
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000282 friend struct ELFWriter;
283};
284
Peter Collingbourne4ef18412018-05-21 19:30:59 +0000285class ELFSingleObjectWriter : public ELFObjectWriter {
286 raw_pwrite_stream &OS;
287 bool IsLittleEndian;
288
289public:
290 ELFSingleObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
291 raw_pwrite_stream &OS, bool IsLittleEndian)
292 : ELFObjectWriter(std::move(MOTW)), OS(OS),
293 IsLittleEndian(IsLittleEndian) {}
294
295 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000296 return ELFWriter(*this, OS, IsLittleEndian, ELFWriter::AllSections)
297 .writeObject(Asm, Layout);
298 }
299
300 friend struct ELFWriter;
301};
302
303class ELFDwoObjectWriter : public ELFObjectWriter {
304 raw_pwrite_stream &OS, &DwoOS;
305 bool IsLittleEndian;
306
307public:
308 ELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
309 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
310 bool IsLittleEndian)
311 : ELFObjectWriter(std::move(MOTW)), OS(OS), DwoOS(DwoOS),
312 IsLittleEndian(IsLittleEndian) {}
313
314 virtual bool checkRelocation(MCContext &Ctx, SMLoc Loc,
315 const MCSectionELF *From,
316 const MCSectionELF *To) override {
317 if (isDwoSection(*From)) {
318 Ctx.reportError(Loc, "A dwo section may not contain relocations");
319 return false;
320 }
321 if (To && isDwoSection(*To)) {
322 Ctx.reportError(Loc, "A relocation may not refer to a dwo section");
323 return false;
324 }
325 return true;
326 }
327
328 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
329 uint64_t Size = ELFWriter(*this, OS, IsLittleEndian, ELFWriter::NonDwoOnly)
330 .writeObject(Asm, Layout);
331 Size += ELFWriter(*this, DwoOS, IsLittleEndian, ELFWriter::DwoOnly)
332 .writeObject(Asm, Layout);
333 return Size;
Peter Collingbourne4ef18412018-05-21 19:30:59 +0000334 }
335};
336
Eugene Zelenko380d47d2016-02-02 18:20:45 +0000337} // end anonymous namespace
Rafael Espindola3963d612011-12-22 03:38:00 +0000338
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000339void ELFWriter::align(unsigned Alignment) {
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000340 uint64_t Padding = OffsetToAlignment(W.OS.tell(), Alignment);
341 W.OS.write_zeros(Padding);
Rafael Espindolaaa4466d2015-06-05 18:21:00 +0000342}
343
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000344unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
Rafael Espindolab65870f2015-04-30 20:53:27 +0000345 SectionTable.push_back(Sec);
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000346 StrTabBuilder.add(Sec->getSectionName());
Rafael Espindolab65870f2015-04-30 20:53:27 +0000347 return SectionTable.size();
348}
349
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000350void SymbolTableWriter::createSymtabShndx() {
Rafael Espindola5fc37692015-04-29 21:09:32 +0000351 if (!ShndxIndexes.empty())
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000352 return;
353
Rafael Espindola5fc37692015-04-29 21:09:32 +0000354 ShndxIndexes.resize(NumWritten);
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000355}
356
Rafael Espindola5fc37692015-04-29 21:09:32 +0000357template <typename T> void SymbolTableWriter::write(T Value) {
358 EWriter.write(Value);
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000359}
360
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000361SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
Rafael Espindola5fc37692015-04-29 21:09:32 +0000362 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000363
364void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
365 uint64_t size, uint8_t other,
366 uint32_t shndx, bool Reserved) {
367 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
368
369 if (LargeIndex)
370 createSymtabShndx();
371
Rafael Espindola5fc37692015-04-29 21:09:32 +0000372 if (!ShndxIndexes.empty()) {
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000373 if (LargeIndex)
Rafael Espindola5fc37692015-04-29 21:09:32 +0000374 ShndxIndexes.push_back(shndx);
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000375 else
Rafael Espindola5fc37692015-04-29 21:09:32 +0000376 ShndxIndexes.push_back(0);
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000377 }
378
379 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
380
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000381 if (Is64Bit) {
Rafael Espindola5fc37692015-04-29 21:09:32 +0000382 write(name); // st_name
383 write(info); // st_info
384 write(other); // st_other
385 write(Index); // st_shndx
386 write(value); // st_value
387 write(size); // st_size
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000388 } else {
Rafael Espindola5fc37692015-04-29 21:09:32 +0000389 write(name); // st_name
390 write(uint32_t(value)); // st_value
391 write(uint32_t(size)); // st_size
392 write(info); // st_info
393 write(other); // st_other
394 write(Index); // st_shndx
Rafael Espindola81c66bc2014-03-25 23:44:25 +0000395 }
396
397 ++NumWritten;
398}
399
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000400bool ELFWriter::is64Bit() const {
401 return OWriter.TargetObjectWriter->is64Bit();
402}
403
404bool ELFWriter::hasRelocationAddend() const {
405 return OWriter.hasRelocationAddend();
406}
407
Matt Fleming3565a062010-08-16 18:57:57 +0000408// Emit the ELF header.
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000409void ELFWriter::writeHeader(const MCAssembler &Asm) {
Matt Fleming3565a062010-08-16 18:57:57 +0000410 // ELF Header
411 // ----------
412 //
413 // Note
414 // ----
415 // emitWord method behaves differently for ELF32 and ELF64, writing
416 // 4 bytes in the former and 8 in the latter.
417
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000418 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
Matt Fleming3565a062010-08-16 18:57:57 +0000419
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000420 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
Matt Fleming3565a062010-08-16 18:57:57 +0000421
422 // e_ident[EI_DATA]
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000423 W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
424 : ELF::ELFDATA2MSB);
Matt Fleming3565a062010-08-16 18:57:57 +0000425
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000426 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
Roman Divacky5baf79e2010-09-09 17:57:50 +0000427 // e_ident[EI_OSABI]
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000428 W.OS << char(OWriter.TargetObjectWriter->getOSABI());
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000429 W.OS << char(0); // e_ident[EI_ABIVERSION]
Matt Fleming3565a062010-08-16 18:57:57 +0000430
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000431 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
Matt Fleming3565a062010-08-16 18:57:57 +0000432
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000433 W.write<uint16_t>(ELF::ET_REL); // e_type
Matt Fleming3565a062010-08-16 18:57:57 +0000434
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000435 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
Matt Fleming3565a062010-08-16 18:57:57 +0000436
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000437 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
Matt Fleming3565a062010-08-16 18:57:57 +0000438 WriteWord(0); // e_entry, no entry point in .o file
439 WriteWord(0); // e_phoff, no program header for .o
Rafael Espindola83ed6b72015-04-14 22:54:16 +0000440 WriteWord(0); // e_shoff = sec hdr table off in bytes
Matt Fleming3565a062010-08-16 18:57:57 +0000441
Jason W Kim2d7a53a2011-02-04 21:41:11 +0000442 // e_flags = whatever the target wants
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000443 W.write<uint32_t>(Asm.getELFHeaderEFlags());
Matt Fleming3565a062010-08-16 18:57:57 +0000444
445 // e_ehsize = ELF header size
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000446 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
447 : sizeof(ELF::Elf32_Ehdr));
Matt Fleming3565a062010-08-16 18:57:57 +0000448
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000449 W.write<uint16_t>(0); // e_phentsize = prog header entry size
450 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
Matt Fleming3565a062010-08-16 18:57:57 +0000451
452 // e_shentsize = Section header entry size
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000453 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
454 : sizeof(ELF::Elf32_Shdr));
Matt Fleming3565a062010-08-16 18:57:57 +0000455
456 // e_shnum = # of section header ents
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000457 W.write<uint16_t>(0);
Matt Fleming3565a062010-08-16 18:57:57 +0000458
459 // e_shstrndx = Section # of '.shstrtab'
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000460 assert(StringTableIndex < ELF::SHN_LORESERVE);
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000461 W.write<uint16_t>(StringTableIndex);
Matt Fleming3565a062010-08-16 18:57:57 +0000462}
463
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000464uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
465 const MCAsmLayout &Layout) {
Rafael Espindolacfac75a2015-05-29 21:45:01 +0000466 if (Sym.isCommon() && Sym.isExternal())
Rafael Espindola82fdcc02015-05-29 17:48:04 +0000467 return Sym.getCommonAlignment();
Rafael Espindola2c6ec312010-09-27 21:23:02 +0000468
Rafael Espindola593cb792014-04-30 21:51:13 +0000469 uint64_t Res;
Duncan P. N. Exon Smith37e9aba2015-05-20 04:39:01 +0000470 if (!Layout.getSymbolOffset(Sym, Res))
Rafael Espindola1c37cbd2014-04-30 16:59:35 +0000471 return 0;
472
Duncan P. N. Exon Smith37e9aba2015-05-20 04:39:01 +0000473 if (Layout.getAssembler().isThumbFunc(&Sym))
Rafael Espindolaa60f7192014-03-21 22:00:29 +0000474 Res |= 1;
Rafael Espindola2c6ec312010-09-27 21:23:02 +0000475
Rafael Espindolaa60f7192014-03-21 22:00:29 +0000476 return Res;
Rafael Espindola2c6ec312010-09-27 21:23:02 +0000477}
478
Roman Divacky7e889af2014-01-07 20:17:03 +0000479static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
480 uint8_t Type = newType;
481
482 // Propagation rules:
483 // IFUNC > FUNC > OBJECT > NOTYPE
484 // TLS_OBJECT > OBJECT > NOTYPE
485 //
486 // dont let the new type degrade the old type
487 switch (origType) {
488 default:
489 break;
490 case ELF::STT_GNU_IFUNC:
491 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
492 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
493 Type = ELF::STT_GNU_IFUNC;
494 break;
495 case ELF::STT_FUNC:
496 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
497 Type == ELF::STT_TLS)
498 Type = ELF::STT_FUNC;
499 break;
500 case ELF::STT_OBJECT:
501 if (Type == ELF::STT_NOTYPE)
502 Type = ELF::STT_OBJECT;
503 break;
504 case ELF::STT_TLS:
505 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
506 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
507 Type = ELF::STT_TLS;
508 break;
509 }
510
511 return Type;
512}
513
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000514void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
515 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
Rafael Espindola569f3822015-06-02 20:38:46 +0000516 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
Rafael Espindolaf7e06852015-06-02 00:25:12 +0000517 const MCSymbolELF *Base =
518 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
Rafael Espindola3008f802014-03-26 00:16:43 +0000519
520 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
521 // SHN_COMMON.
Rafael Espindolacfac75a2015-05-29 21:45:01 +0000522 bool IsReserved = !Base || Symbol.isCommon();
Rafael Espindola7be2c332010-10-31 00:16:26 +0000523
Jack Carter77afbdc2013-02-19 21:57:35 +0000524 // Binding and Type share the same byte as upper and lower nibbles
Rafael Espindola569f3822015-06-02 20:38:46 +0000525 uint8_t Binding = Symbol.getBinding();
526 uint8_t Type = Symbol.getType();
Rafael Espindola4ff2dad2014-03-23 03:33:20 +0000527 if (Base) {
Rafael Espindola569f3822015-06-02 20:38:46 +0000528 Type = mergeTypeForSet(Type, Base->getType());
Rafael Espindola4ff2dad2014-03-23 03:33:20 +0000529 }
Rafael Espindolac2128562015-06-04 00:47:43 +0000530 uint8_t Info = (Binding << 4) | Type;
Jack Carter77afbdc2013-02-19 21:57:35 +0000531
Joerg Sonnenberger72580782013-10-29 01:06:17 +0000532 // Other and Visibility share the same byte with Visibility using the lower
Jack Carter77afbdc2013-02-19 21:57:35 +0000533 // 2 bits
Rafael Espindola569f3822015-06-02 20:38:46 +0000534 uint8_t Visibility = Symbol.getVisibility();
Rafael Espindolacddcaba2015-06-04 05:59:23 +0000535 uint8_t Other = Symbol.getOther() | Visibility;
Rafael Espindola152c1062010-10-06 21:02:29 +0000536
Duncan P. N. Exon Smith37e9aba2015-05-20 04:39:01 +0000537 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
Matt Fleming3565a062010-08-16 18:57:57 +0000538 uint64_t Size = 0;
Matt Fleming3565a062010-08-16 18:57:57 +0000539
Rafael Espindola28afbf242015-05-29 17:24:52 +0000540 const MCExpr *ESize = MSD.Symbol->getSize();
Rafael Espindolae459f722014-03-27 00:28:24 +0000541 if (!ESize && Base)
Rafael Espindola28afbf242015-05-29 17:24:52 +0000542 ESize = Base->getSize();
Rafael Espindolaf7c10a32010-09-21 00:24:38 +0000543
Rafael Espindolaf0121242010-12-22 16:03:00 +0000544 if (ESize) {
545 int64_t Res;
Rafael Espindola9428f182015-04-06 15:27:57 +0000546 if (!ESize->evaluateKnownAbsolute(Res, Layout))
Rafael Espindolaf0121242010-12-22 16:03:00 +0000547 report_fatal_error("Size expression must be absolute.");
548 Size = Res;
Matt Fleming3565a062010-08-16 18:57:57 +0000549 }
550
551 // Write out the symbol table entry
Rafael Espindolac66c8e72015-05-28 20:25:29 +0000552 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
553 IsReserved);
Matt Fleming3565a062010-08-16 18:57:57 +0000554}
555
Rafael Espindola560d73a2015-04-17 20:05:17 +0000556// True if the assembler knows nothing about the final value of the symbol.
557// This doesn't cover the comdat issues, since in those cases the assembler
558// can at least know that all symbols in the section will move together.
Rafael Espindola569f3822015-06-02 20:38:46 +0000559static bool isWeak(const MCSymbolELF &Sym) {
560 if (Sym.getType() == ELF::STT_GNU_IFUNC)
Rafael Espindola2298ce32015-04-17 08:46:11 +0000561 return true;
562
Rafael Espindola569f3822015-06-02 20:38:46 +0000563 switch (Sym.getBinding()) {
Rafael Espindola2298ce32015-04-17 08:46:11 +0000564 default:
565 llvm_unreachable("Unknown binding");
566 case ELF::STB_LOCAL:
567 return false;
568 case ELF::STB_GLOBAL:
Rafael Espindola560d73a2015-04-17 20:05:17 +0000569 return false;
Rafael Espindola2298ce32015-04-17 08:46:11 +0000570 case ELF::STB_WEAK:
571 case ELF::STB_GNU_UNIQUE:
572 return true;
573 }
Rafael Espindola4e86f542015-03-24 23:48:44 +0000574}
575
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000576bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
577 bool Used, bool Renamed) {
Rafael Espindola0a70f9b2014-03-20 02:12:01 +0000578 if (Symbol.isVariable()) {
579 const MCExpr *Expr = Symbol.getVariableValue();
580 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
581 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
582 return false;
583 }
584 }
Rafael Espindola484291c2010-11-01 14:28:48 +0000585
Rafael Espindolabd701182010-10-19 19:31:37 +0000586 if (Used)
587 return true;
588
Rafael Espindola88182132010-10-27 15:18:17 +0000589 if (Renamed)
590 return false;
591
Rafael Espindolaa41438c2015-06-03 21:23:21 +0000592 if (Symbol.isVariable() && Symbol.isUndefined()) {
593 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
594 Layout.getBaseSymbol(Symbol);
595 return false;
Rafael Espindola0af058f2014-04-28 13:39:57 +0000596 }
Rafael Espindola21451e52011-02-23 20:22:07 +0000597
Rafael Espindolaa41438c2015-06-03 21:23:21 +0000598 if (Symbol.isUndefined() && !Symbol.isBindingSet())
Rafael Espindolaa6866962010-10-27 14:44:52 +0000599 return false;
600
Rafael Espindolabd701182010-10-19 19:31:37 +0000601 if (Symbol.isTemporary())
Rafael Espindola737cd212010-10-05 18:01:23 +0000602 return false;
603
Rafael Espindola9f299ab2015-06-04 15:33:30 +0000604 if (Symbol.getType() == ELF::STT_SECTION)
605 return false;
606
Rafael Espindola737cd212010-10-05 18:01:23 +0000607 return true;
608}
609
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000610void ELFWriter::computeSymbolTable(
Rafael Espindolac78f07a2015-04-07 19:00:17 +0000611 MCAssembler &Asm, const MCAsmLayout &Layout,
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000612 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
613 SectionOffsetsTy &SectionOffsets) {
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000614 MCContext &Ctx = Asm.getContext();
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000615 SymbolTableWriter Writer(*this, is64Bit());
616
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000617 // Symbol table
618 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
619 MCSectionELF *SymtabSection =
620 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
621 SymtabSection->setAlignment(is64Bit() ? 8 : 4);
622 SymbolTableIndex = addToSectionTable(SymtabSection);
623
Rafael Espindolaaa4466d2015-06-05 18:21:00 +0000624 align(SymtabSection->getAlignment());
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000625 uint64_t SecStart = W.OS.tell();
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000626
627 // The first entry is the undefined symbol entry.
628 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
629
Rafael Espindola7978ab32015-05-28 20:11:34 +0000630 std::vector<ELFSymbolData> LocalSymbolData;
631 std::vector<ELFSymbolData> ExternalSymbolData;
Rafael Espindola7978ab32015-05-28 20:11:34 +0000632
Rafael Espindolaa0949b52010-10-14 16:34:44 +0000633 // Add the data for the symbols.
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000634 bool HasLargeSectionIndex = false;
Rafael Espindola569f3822015-06-02 20:38:46 +0000635 for (const MCSymbol &S : Asm.symbols()) {
636 const auto &Symbol = cast<MCSymbolELF>(S);
Rafael Espindola2b9f4dc2015-06-03 21:30:10 +0000637 bool Used = Symbol.isUsedInReloc();
Rafael Espindola5eb74812015-06-03 21:52:06 +0000638 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
Rafael Espindolaf3857c32015-06-03 21:41:59 +0000639 bool isSignature = Symbol.isSignature();
Rafael Espindola1f4f9e32010-11-14 04:17:37 +0000640
Duncan P. N. Exon Smith37e9aba2015-05-20 04:39:01 +0000641 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000642 OWriter.Renames.count(&Symbol)))
Matt Fleming3565a062010-08-16 18:57:57 +0000643 continue;
644
Oliver Stannard99ab1122015-11-17 10:00:43 +0000645 if (Symbol.isTemporary() && Symbol.isUndefined()) {
646 Ctx.reportError(SMLoc(), "Undefined temporary symbol");
647 continue;
648 }
Rafael Espindola1de6f362015-06-25 20:10:45 +0000649
Matt Fleming3565a062010-08-16 18:57:57 +0000650 ELFSymbolData MSD;
Rafael Espindolaf7e06852015-06-02 00:25:12 +0000651 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
Matt Fleming3565a062010-08-16 18:57:57 +0000652
Rafael Espindolaf3857c32015-06-03 21:41:59 +0000653 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
Rafael Espindola1de6f362015-06-25 20:10:45 +0000654 assert(Local || !Symbol.isTemporary());
655
Rafael Espindola616c7af2015-05-29 15:07:27 +0000656 if (Symbol.isAbsolute()) {
Rafael Espindola0bce3342014-03-24 03:43:21 +0000657 MSD.SectionIndex = ELF::SHN_ABS;
Rafael Espindola82fdcc02015-05-29 17:48:04 +0000658 } else if (Symbol.isCommon()) {
Rafael Espindolaa0949b52010-10-14 16:34:44 +0000659 assert(!Local);
Rafael Espindolaf7c10a32010-09-21 00:24:38 +0000660 MSD.SectionIndex = ELF::SHN_COMMON;
Rafael Espindola616c7af2015-05-29 15:07:27 +0000661 } else if (Symbol.isUndefined()) {
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000662 if (isSignature && !Used) {
Rafael Espindola5acccb12015-04-28 22:59:58 +0000663 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000664 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
665 HasLargeSectionIndex = true;
666 } else {
Rafael Espindola1f4f9e32010-11-14 04:17:37 +0000667 MSD.SectionIndex = ELF::SHN_UNDEF;
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000668 }
Matt Fleming3565a062010-08-16 18:57:57 +0000669 } else {
Rafael Espindolabab2a802010-11-10 21:51:05 +0000670 const MCSectionELF &Section =
Rafael Espindola616c7af2015-05-29 15:07:27 +0000671 static_cast<const MCSectionELF &>(Symbol.getSection());
George Rimard437f3c2018-12-05 10:43:58 +0000672
673 // We may end up with a situation when section symbol is technically
674 // defined, but should not be. That happens because we explicitly
675 // pre-create few .debug_* sections to have accessors.
676 // And if these sections were not really defined in the code, but were
677 // referenced, we simply error out.
678 if (!Section.isRegistered()) {
679 assert(static_cast<const MCSymbolELF &>(Symbol).getType() ==
680 ELF::STT_SECTION);
681 Ctx.reportError(SMLoc(),
682 "Undefined section reference: " + Symbol.getName());
683 continue;
684 }
685
Peter Collingbourne60fd99d2018-05-21 19:44:54 +0000686 if (Mode == NonDwoOnly && isDwoSection(Section))
687 continue;
Rafael Espindolabab2a802010-11-10 21:51:05 +0000688 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
Matt Fleming3565a062010-08-16 18:57:57 +0000689 assert(MSD.SectionIndex && "Invalid section index!");
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000690 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
691 HasLargeSectionIndex = true;
Rafael Espindola5df0b652010-10-15 15:39:06 +0000692 }
693
Rafael Espindola88182132010-10-27 15:18:17 +0000694 StringRef Name = Symbol.getName();
Rafael Espindolad8ee23f2014-10-17 01:48:58 +0000695
696 // Sections have their own string table
Rafael Espindolad43c0012015-10-22 18:32:06 +0000697 if (Symbol.getType() != ELF::STT_SECTION) {
698 MSD.Name = Name;
699 StrTabBuilder.add(Name);
700 }
Rafael Espindola88182132010-10-27 15:18:17 +0000701
Rafael Espindola3b087502015-05-29 14:20:40 +0000702 if (Local)
Rafael Espindolaa6866962010-10-27 14:44:52 +0000703 LocalSymbolData.push_back(MSD);
704 else
705 ExternalSymbolData.push_back(MSD);
Matt Fleming3565a062010-08-16 18:57:57 +0000706 }
707
Rafael Espindola95615062015-07-02 16:59:57 +0000708 // This holds the .symtab_shndx section index.
709 unsigned SymtabShndxSectionIndex = 0;
710
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +0000711 if (HasLargeSectionIndex) {
712 MCSectionELF *SymtabShndxSection =
713 Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
714 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
715 SymtabShndxSection->setAlignment(4);
716 }
717
Rafael Espindola24441412015-05-28 19:29:15 +0000718 ArrayRef<std::string> FileNames = Asm.getFileNames();
719 for (const std::string &Name : FileNames)
Rafael Espindolafd64e0f2015-05-28 18:03:20 +0000720 StrTabBuilder.add(Name);
Hans Wennborga8febf22014-04-30 16:25:02 +0000721
Rafael Espindola715bcca2015-10-23 21:48:05 +0000722 StrTabBuilder.finalize();
Hans Wennborga8febf22014-04-30 16:25:02 +0000723
Peter Collingbourne6387bda2017-03-03 21:22:06 +0000724 // File symbols are emitted first and handled separately from normal symbols,
725 // i.e. a non-STT_FILE symbol with the same name may appear.
Rafael Espindola86c0a102015-05-28 20:00:13 +0000726 for (const std::string &Name : FileNames)
727 Writer.writeSymbol(StrTabBuilder.getOffset(Name),
728 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
729 ELF::SHN_ABS, true);
730
Matt Fleming3565a062010-08-16 18:57:57 +0000731 // Symbols are required to be in lexicographic order.
732 array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
733 array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
Matt Fleming3565a062010-08-16 18:57:57 +0000734
735 // Set the symbol indices. Local symbols must come before all other
736 // symbols with non-local bindings.
Rafael Espindola24441412015-05-28 19:29:15 +0000737 unsigned Index = FileNames.size() + 1;
Rafael Espindolaab4a7af2010-11-14 03:12:24 +0000738
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000739 for (ELFSymbolData &MSD : LocalSymbolData) {
Daniel Jasperb7f5b8b2015-06-23 11:31:32 +0000740 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
741 ? 0
742 : StrTabBuilder.getOffset(MSD.Name);
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000743 MSD.Symbol->setIndex(Index++);
Rafael Espindolac66c8e72015-05-28 20:25:29 +0000744 writeSymbol(Writer, StringIndex, MSD, Layout);
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000745 }
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000746
747 // Write the symbol table entries.
Rafael Espindola86c0a102015-05-28 20:00:13 +0000748 LastLocalSymbolIndex = Index;
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000749
Rafael Espindolab665c2b2015-05-28 19:43:20 +0000750 for (ELFSymbolData &MSD : ExternalSymbolData) {
Rafael Espindolac66c8e72015-05-28 20:25:29 +0000751 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
Rafael Espindola86c0a102015-05-28 20:00:13 +0000752 MSD.Symbol->setIndex(Index++);
Rafael Espindolac66c8e72015-05-28 20:25:29 +0000753 writeSymbol(Writer, StringIndex, MSD, Layout);
Rafael Espindola569f3822015-06-02 20:38:46 +0000754 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000755 }
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000756
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000757 uint64_t SecEnd = W.OS.tell();
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000758 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
759
760 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
761 if (ShndxIndexes.empty()) {
762 assert(SymtabShndxSectionIndex == 0);
763 return;
764 }
765 assert(SymtabShndxSectionIndex != 0);
766
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000767 SecStart = W.OS.tell();
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000768 const MCSectionELF *SymtabShndxSection =
769 SectionTable[SymtabShndxSectionIndex - 1];
770 for (uint32_t Index : ShndxIndexes)
771 write(Index);
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000772 SecEnd = W.OS.tell();
Rafael Espindolab9ffeb092015-05-28 17:54:01 +0000773 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
Matt Fleming3565a062010-08-16 18:57:57 +0000774}
775
Peter Collingbournea29ff2e2018-07-17 22:17:18 +0000776void ELFWriter::writeAddrsigSection() {
777 for (const MCSymbol *Sym : OWriter.AddrsigSyms)
778 encodeULEB128(Sym->getIndex(), W.OS);
779}
780
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000781MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
782 const MCSectionELF &Sec) {
783 if (OWriter.Relocations[&Sec].empty())
Rafael Espindola76e71bd2015-04-30 14:21:49 +0000784 return nullptr;
Rafael Espindola7c18fa82011-03-20 18:44:20 +0000785
Rafael Espindola46895012015-04-30 00:45:46 +0000786 const StringRef SectionName = Sec.getSectionName();
Rafael Espindola07102892015-02-17 20:31:13 +0000787 std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
788 RelaSectionName += SectionName;
Benjamin Kramer299fbe32010-08-17 17:56:13 +0000789
Rafael Espindola07102892015-02-17 20:31:13 +0000790 unsigned EntrySize;
791 if (hasRelocationAddend())
792 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
793 else
794 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
Matt Fleming3565a062010-08-16 18:57:57 +0000795
Rafael Espindola07102892015-02-17 20:31:13 +0000796 unsigned Flags = 0;
Rafael Espindola46895012015-04-30 00:45:46 +0000797 if (Sec.getFlags() & ELF::SHF_GROUP)
Rafael Espindola07102892015-02-17 20:31:13 +0000798 Flags = ELF::SHF_GROUP;
Rafael Espindola07102892015-02-17 20:31:13 +0000799
Rafael Espindola75219642015-05-21 19:20:38 +0000800 MCSectionELF *RelaSection = Ctx.createELFRelSection(
Rafael Espindola07102892015-02-17 20:31:13 +0000801 RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
Rafael Espindola46895012015-04-30 00:45:46 +0000802 Flags, EntrySize, Sec.getGroup(), &Sec);
Rafael Espindolafabbc492015-05-21 20:43:13 +0000803 RelaSection->setAlignment(is64Bit() ? 8 : 4);
Rafael Espindola76e71bd2015-04-30 14:21:49 +0000804 return RelaSection;
Rafael Espindola7c18fa82011-03-20 18:44:20 +0000805}
Matt Fleming3565a062010-08-16 18:57:57 +0000806
George Rimarec285af2016-05-27 12:27:32 +0000807// Include the debug info compression header.
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000808bool ELFWriter::maybeWriteCompression(
George Rimarec285af2016-05-27 12:27:32 +0000809 uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
810 unsigned Alignment) {
811 if (ZLibStyle) {
812 uint64_t HdrSize =
813 is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
814 if (Size <= HdrSize + CompressedContents.size())
815 return false;
816 // Platform specific header is followed by compressed data.
817 if (is64Bit()) {
818 // Write Elf64_Chdr header.
819 write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB));
820 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
821 write(static_cast<ELF::Elf64_Xword>(Size));
822 write(static_cast<ELF::Elf64_Xword>(Alignment));
823 } else {
824 // Write Elf32_Chdr header otherwise.
825 write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB));
826 write(static_cast<ELF::Elf32_Word>(Size));
827 write(static_cast<ELF::Elf32_Word>(Alignment));
828 }
829 return true;
830 }
831
832 // "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
833 // useful for consumers to preallocate a buffer to decompress into.
Richard Smithe89c0002016-05-25 00:14:12 +0000834 const StringRef Magic = "ZLIB";
835 if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
836 return false;
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000837 W.OS << Magic;
838 support::endian::write(W.OS, Size, support::big);
Richard Smithe89c0002016-05-25 00:14:12 +0000839 return true;
840}
841
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000842void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
843 const MCAsmLayout &Layout) {
Rafael Espindolaa287fe72015-05-27 13:30:50 +0000844 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000845 StringRef SectionName = Section.getSectionName();
David Blaikiefe255212014-04-10 21:53:53 +0000846
Saleem Abdulrasoole6be41f2017-06-09 00:40:19 +0000847 auto &MC = Asm.getContext();
848 const auto &MAI = MC.getAsmInfo();
849
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000850 // Compressing debug_frame requires handling alignment fragments which is
851 // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
852 // for writing to arbitrary buffers) for little benefit.
George Rimarec285af2016-05-27 12:27:32 +0000853 bool CompressionEnabled =
Saleem Abdulrasoole6be41f2017-06-09 00:40:19 +0000854 MAI->compressDebugSections() != DebugCompressionType::None;
George Rimarec285af2016-05-27 12:27:32 +0000855 if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
856 SectionName == ".debug_frame") {
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000857 Asm.writeSectionData(W.OS, &Section, Layout);
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000858 return;
859 }
860
Saleem Abdulrasoole6be41f2017-06-09 00:40:19 +0000861 assert((MAI->compressDebugSections() == DebugCompressionType::Z ||
862 MAI->compressDebugSections() == DebugCompressionType::GNU) &&
863 "expected zlib or zlib-gnu style compression");
864
David Majnemer919f1f42015-09-01 16:19:03 +0000865 SmallVector<char, 128> UncompressedData;
866 raw_svector_ostream VecOS(UncompressedData);
Peter Collingbourne74bda0b2018-05-21 18:11:35 +0000867 Asm.writeSectionData(VecOS, &Section, Layout);
David Blaikiefe255212014-04-10 21:53:53 +0000868
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000869 SmallVector<char, 128> CompressedContents;
George Rimaref935cd2017-01-17 15:45:07 +0000870 if (Error E = zlib::compress(
871 StringRef(UncompressedData.data(), UncompressedData.size()),
872 CompressedContents)) {
873 consumeError(std::move(E));
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000874 W.OS << UncompressedData;
David Blaikiefe255212014-04-10 21:53:53 +0000875 return;
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000876 }
David Blaikiefe255212014-04-10 21:53:53 +0000877
Saleem Abdulrasoole6be41f2017-06-09 00:40:19 +0000878 bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
George Rimarec285af2016-05-27 12:27:32 +0000879 if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
880 ZlibStyle, Sec.getAlignment())) {
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000881 W.OS << UncompressedData;
Rafael Espindolaa55dd522015-04-30 21:51:58 +0000882 return;
883 }
George Rimarec285af2016-05-27 12:27:32 +0000884
885 if (ZlibStyle)
886 // Set the compressed flag. That is zlib style.
887 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
888 else
889 // Add "z" prefix to section name. This is zlib-gnu style.
Saleem Abdulrasoole6be41f2017-06-09 00:40:19 +0000890 MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str());
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000891 W.OS << CompressedContents;
David Blaikiefe255212014-04-10 21:53:53 +0000892}
893
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000894void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
895 uint64_t Address, uint64_t Offset,
896 uint64_t Size, uint32_t Link, uint32_t Info,
897 uint64_t Alignment, uint64_t EntrySize) {
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000898 W.write<uint32_t>(Name); // sh_name: index into string table
899 W.write<uint32_t>(Type); // sh_type
Matt Fleming3565a062010-08-16 18:57:57 +0000900 WriteWord(Flags); // sh_flags
901 WriteWord(Address); // sh_addr
902 WriteWord(Offset); // sh_offset
903 WriteWord(Size); // sh_size
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000904 W.write<uint32_t>(Link); // sh_link
905 W.write<uint32_t>(Info); // sh_info
Matt Fleming3565a062010-08-16 18:57:57 +0000906 WriteWord(Alignment); // sh_addralign
907 WriteWord(EntrySize); // sh_entsize
908}
909
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000910void ELFWriter::writeRelocations(const MCAssembler &Asm,
Rafael Espindola46895012015-04-30 00:45:46 +0000911 const MCSectionELF &Sec) {
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000912 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
Akira Hatanaka00ca8882012-03-23 23:06:45 +0000913
Rafael Espindolacdfe7902015-12-17 16:22:06 +0000914 // We record relocations by pushing to the end of a vector. Reverse the vector
915 // to get the relocations in the order they were created.
916 // In most cases that is not important, but it can be for special sections
917 // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
918 std::reverse(Relocs.begin(), Relocs.end());
Rafael Espindolaf50f96b2015-12-17 15:08:24 +0000919
Rafael Espindolacdfe7902015-12-17 16:22:06 +0000920 // Sort the relocation entries. MIPS needs this.
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000921 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
Matt Fleming3565a062010-08-16 18:57:57 +0000922
923 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
Rafael Espindola224dbf42014-03-29 06:26:49 +0000924 const ELFRelocationEntry &Entry = Relocs[e - i - 1];
Rafael Espindoladb8eb522015-05-28 20:53:09 +0000925 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
Rafael Espindola224dbf42014-03-29 06:26:49 +0000926
Rafael Espindolabff66a82010-12-18 03:27:34 +0000927 if (is64Bit()) {
Rafael Espindola1e95f212015-04-30 00:30:40 +0000928 write(Entry.Offset);
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000929 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
Rafael Espindola1e95f212015-04-30 00:30:40 +0000930 write(uint32_t(Index));
Benjamin Kramer5e492e82010-09-09 18:01:29 +0000931
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000932 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
933 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
934 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
935 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
Rafael Espindola224dbf42014-03-29 06:26:49 +0000936 } else {
Jack Carter93ee2862012-06-27 22:28:30 +0000937 struct ELF::Elf64_Rela ERE64;
Rafael Espindola224dbf42014-03-29 06:26:49 +0000938 ERE64.setSymbolAndType(Index, Entry.Type);
Rafael Espindola1e95f212015-04-30 00:30:40 +0000939 write(ERE64.r_info);
Jack Carter93ee2862012-06-27 22:28:30 +0000940 }
Rafael Espindolabff66a82010-12-18 03:27:34 +0000941 if (hasRelocationAddend())
Rafael Espindola1e95f212015-04-30 00:30:40 +0000942 write(Entry.Addend);
Benjamin Kramer5e492e82010-09-09 18:01:29 +0000943 } else {
Rafael Espindola1e95f212015-04-30 00:30:40 +0000944 write(uint32_t(Entry.Offset));
Benjamin Kramer5e492e82010-09-09 18:01:29 +0000945
Rafael Espindola8f413fa2010-10-05 15:11:03 +0000946 struct ELF::Elf32_Rela ERE32;
Rafael Espindola224dbf42014-03-29 06:26:49 +0000947 ERE32.setSymbolAndType(Index, Entry.Type);
Rafael Espindola1e95f212015-04-30 00:30:40 +0000948 write(ERE32.r_info);
Benjamin Kramer5e492e82010-09-09 18:01:29 +0000949
Rafael Espindolabff66a82010-12-18 03:27:34 +0000950 if (hasRelocationAddend())
Rafael Espindola1e95f212015-04-30 00:30:40 +0000951 write(uint32_t(Entry.Addend));
Simon Atanasyancff5a9f2017-09-21 14:04:53 +0000952
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000953 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
954 if (uint32_t RType =
955 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
Simon Atanasyancff5a9f2017-09-21 14:04:53 +0000956 write(uint32_t(Entry.Offset));
957
958 ERE32.setSymbolAndType(0, RType);
959 write(ERE32.r_info);
960 write(uint32_t(0));
961 }
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000962 if (uint32_t RType =
963 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
Simon Atanasyancff5a9f2017-09-21 14:04:53 +0000964 write(uint32_t(Entry.Offset));
965
966 ERE32.setSymbolAndType(0, RType);
967 write(ERE32.r_info);
968 write(uint32_t(0));
969 }
970 }
Benjamin Kramer5e492e82010-09-09 18:01:29 +0000971 }
Matt Fleming3565a062010-08-16 18:57:57 +0000972 }
973}
974
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000975const MCSectionELF *ELFWriter::createStringTable(MCContext &Ctx) {
Rafael Espindolaab78d672015-05-25 21:56:55 +0000976 const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
Peter Collingbourne8e93a952018-05-21 18:17:42 +0000977 StrTabBuilder.write(W.OS);
Rafael Espindola76e71bd2015-04-30 14:21:49 +0000978 return StrtabSection;
Rafael Espindola2ff9e832010-11-11 18:13:52 +0000979}
980
Peter Collingbourne815bbef2018-05-21 19:18:28 +0000981void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
982 uint32_t GroupSymbolIndex, uint64_t Offset,
983 uint64_t Size, const MCSectionELF &Section) {
Rafael Espindolac87a94a2010-11-10 23:36:59 +0000984 uint64_t sh_link = 0;
985 uint64_t sh_info = 0;
986
987 switch(Section.getType()) {
Rafael Espindola6254dcc2015-04-06 03:16:51 +0000988 default:
989 // Nothing to do.
990 break;
991
Rafael Espindolac87a94a2010-11-10 23:36:59 +0000992 case ELF::SHT_DYNAMIC:
Rafael Espindola15953ff2015-04-30 21:20:06 +0000993 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
Rafael Espindolac87a94a2010-11-10 23:36:59 +0000994
995 case ELF::SHT_REL:
996 case ELF::SHT_RELA: {
Rafael Espindola8fd9fc32015-02-17 20:37:50 +0000997 sh_link = SymbolTableIndex;
Rafael Espindolac87a94a2010-11-10 23:36:59 +0000998 assert(sh_link && ".symtab not found");
Evgeniy Stepanovc67a9ef2017-03-14 19:28:51 +0000999 const MCSection *InfoSection = Section.getAssociatedSection();
1000 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
Rafael Espindolac87a94a2010-11-10 23:36:59 +00001001 break;
1002 }
1003
1004 case ELF::SHT_SYMTAB:
Rafael Espindolac87a94a2010-11-10 23:36:59 +00001005 sh_link = StringTableIndex;
1006 sh_info = LastLocalSymbolIndex;
1007 break;
1008
1009 case ELF::SHT_SYMTAB_SHNDX:
Michael J. Spencer56500c72018-06-02 16:33:01 +00001010 case ELF::SHT_LLVM_CALL_GRAPH_PROFILE:
Peter Collingbournea29ff2e2018-07-17 22:17:18 +00001011 case ELF::SHT_LLVM_ADDRSIG:
Rafael Espindolac87a94a2010-11-10 23:36:59 +00001012 sh_link = SymbolTableIndex;
1013 break;
1014
Nick Lewycky4a8d43e2011-10-07 23:28:32 +00001015 case ELF::SHT_GROUP:
Rafael Espindola2ff9e832010-11-11 18:13:52 +00001016 sh_link = SymbolTableIndex;
1017 sh_info = GroupSymbolIndex;
1018 break;
Rafael Espindolac87a94a2010-11-10 23:36:59 +00001019 }
1020
Evgeniy Stepanovc67a9ef2017-03-14 19:28:51 +00001021 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
1022 const MCSymbol *Sym = Section.getAssociatedSymbol();
1023 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
1024 sh_link = SectionIndexMap.lookup(Sec);
1025 }
Logan Chienb0c89962013-02-05 14:18:59 +00001026
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +00001027 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
Rafael Espindolaad7c1172015-05-21 19:36:43 +00001028 Section.getType(), Section.getFlags(), 0, Offset, Size,
1029 sh_link, sh_info, Section.getAlignment(),
1030 Section.getEntrySize());
Rafael Espindolac87a94a2010-11-10 23:36:59 +00001031}
1032
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001033void ELFWriter::writeSectionHeader(
Rafael Espindola4dbd6032015-06-04 20:55:49 +00001034 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
Rafael Espindolaa34b8b22015-04-28 15:26:21 +00001035 const SectionOffsetsTy &SectionOffsets) {
Rafael Espindolad80f5162015-04-30 21:10:06 +00001036 const unsigned NumSections = SectionTable.size();
Rafael Espindola2ff9e832010-11-11 18:13:52 +00001037
Matt Fleming3565a062010-08-16 18:57:57 +00001038 // Null section first.
Rafael Espindola7be2c332010-10-31 00:16:26 +00001039 uint64_t FirstSectionSize =
Rafael Espindola50b93572015-04-15 13:07:47 +00001040 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
Rafael Espindola58a854d2015-04-29 20:25:24 +00001041 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
Matt Fleming3565a062010-08-16 18:57:57 +00001042
Rafael Espindolaab78d672015-05-25 21:56:55 +00001043 for (const MCSectionELF *Section : SectionTable) {
Rafael Espindola2ff9e832010-11-11 18:13:52 +00001044 uint32_t GroupSymbolIndex;
Rafael Espindolab65870f2015-04-30 20:53:27 +00001045 unsigned Type = Section->getType();
1046 if (Type != ELF::SHT_GROUP)
Rafael Espindola2ff9e832010-11-11 18:13:52 +00001047 GroupSymbolIndex = 0;
1048 else
Rafael Espindoladb8eb522015-05-28 20:53:09 +00001049 GroupSymbolIndex = Section->getGroup()->getIndex();
Matt Fleming3565a062010-08-16 18:57:57 +00001050
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001051 const std::pair<uint64_t, uint64_t> &Offsets =
Rafael Espindolab65870f2015-04-30 20:53:27 +00001052 SectionOffsets.find(Section)->second;
Rafael Espindola9a9984d2015-05-21 19:46:39 +00001053 uint64_t Size;
Rafael Espindolaea3533b2015-05-26 02:00:36 +00001054 if (Type == ELF::SHT_NOBITS)
1055 Size = Layout.getSectionAddressSize(Section);
1056 else
Rafael Espindola9a9984d2015-05-21 19:46:39 +00001057 Size = Offsets.second - Offsets.first;
Rafael Espindola6db8a9f2010-12-02 03:09:06 +00001058
Rafael Espindolaa127bd02015-05-21 19:42:35 +00001059 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
Rafael Espindolaad7c1172015-05-21 19:36:43 +00001060 *Section);
Matt Fleming3565a062010-08-16 18:57:57 +00001061 }
1062}
1063
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001064uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
Peter Collingbourne0d4292f2018-05-21 18:23:50 +00001065 uint64_t StartOffset = W.OS.tell();
1066
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001067 MCContext &Ctx = Asm.getContext();
Rafael Espindola7c4f3dc2015-05-22 23:58:30 +00001068 MCSectionELF *StrtabSection =
1069 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
1070 StringTableIndex = addToSectionTable(StrtabSection);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001071
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001072 RevGroupMapTy RevGroupMap;
1073 SectionIndexMapTy SectionIndexMap;
1074
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001075 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001076
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001077 // Write out the ELF header ...
Rafael Espindola840bb0f2015-04-29 20:39:37 +00001078 writeHeader(Asm);
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001079
Rafael Espindola541279f2015-04-08 11:41:24 +00001080 // ... then the sections ...
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001081 SectionOffsetsTy SectionOffsets;
Rafael Espindolafabbc492015-05-21 20:43:13 +00001082 std::vector<MCSectionELF *> Groups;
1083 std::vector<MCSectionELF *> Relocations;
Rafael Espindolaa287fe72015-05-27 13:30:50 +00001084 for (MCSection &Sec : Asm) {
1085 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001086 if (Mode == NonDwoOnly && isDwoSection(Section))
1087 continue;
1088 if (Mode == DwoOnly && !isDwoSection(Section))
1089 continue;
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001090
Rafael Espindolaaa4466d2015-06-05 18:21:00 +00001091 align(Section.getAlignment());
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001092
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001093 // Remember the offset into the file for this section.
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001094 uint64_t SecStart = W.OS.tell();
Rafael Espindola1e95f212015-04-30 00:30:40 +00001095
Rafael Espindola4cc59a12015-06-02 21:30:13 +00001096 const MCSymbolELF *SignatureSymbol = Section.getGroup();
Rafael Espindolaa287fe72015-05-27 13:30:50 +00001097 writeSectionData(Asm, Section, Layout);
Rafael Espindola1e95f212015-04-30 00:30:40 +00001098
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001099 uint64_t SecEnd = W.OS.tell();
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001100 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1101
Rafael Espindolafabbc492015-05-21 20:43:13 +00001102 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001103
1104 if (SignatureSymbol) {
Rafael Espindolaf00654b2015-05-29 20:21:02 +00001105 Asm.registerSymbol(*SignatureSymbol);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001106 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1107 if (!GroupIdx) {
Rafael Espindola75219642015-05-21 19:20:38 +00001108 MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
Rafael Espindolab65870f2015-04-30 20:53:27 +00001109 GroupIdx = addToSectionTable(Group);
Rafael Espindolafabbc492015-05-21 20:43:13 +00001110 Group->setAlignment(4);
1111 Groups.push_back(Group);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001112 }
Rafael Espindolac1233a82015-06-05 17:54:25 +00001113 std::vector<const MCSectionELF *> &Members =
1114 GroupMembers[SignatureSymbol];
1115 Members.push_back(&Section);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001116 if (RelSection)
Rafael Espindolac1233a82015-06-05 17:54:25 +00001117 Members.push_back(RelSection);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001118 }
1119
Rafael Espindolab65870f2015-04-30 20:53:27 +00001120 SectionIndexMap[&Section] = addToSectionTable(&Section);
Rafael Espindolafabbc492015-05-21 20:43:13 +00001121 if (RelSection) {
Rafael Espindolab65870f2015-04-30 20:53:27 +00001122 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
Rafael Espindolafabbc492015-05-21 20:43:13 +00001123 Relocations.push_back(RelSection);
1124 }
Eric Christopher42eb0822018-09-06 22:09:31 +00001125
1126 OWriter.TargetObjectWriter->addTargetSectionFlags(Ctx, Section);
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001127 }
1128
Michael J. Spencer56500c72018-06-02 16:33:01 +00001129 MCSectionELF *CGProfileSection = nullptr;
1130 if (!Asm.CGProfile.empty()) {
1131 CGProfileSection = Ctx.getELFSection(".llvm.call-graph-profile",
1132 ELF::SHT_LLVM_CALL_GRAPH_PROFILE,
1133 ELF::SHF_EXCLUDE, 16, "");
1134 SectionIndexMap[CGProfileSection] = addToSectionTable(CGProfileSection);
1135 }
1136
Rafael Espindolafabbc492015-05-21 20:43:13 +00001137 for (MCSectionELF *Group : Groups) {
Rafael Espindolaaa4466d2015-06-05 18:21:00 +00001138 align(Group->getAlignment());
Rafael Espindolafabbc492015-05-21 20:43:13 +00001139
1140 // Remember the offset into the file for this section.
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001141 uint64_t SecStart = W.OS.tell();
Rafael Espindolafabbc492015-05-21 20:43:13 +00001142
1143 const MCSymbol *SignatureSymbol = Group->getGroup();
1144 assert(SignatureSymbol);
1145 write(uint32_t(ELF::GRP_COMDAT));
1146 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1147 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1148 write(SecIndex);
1149 }
1150
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001151 uint64_t SecEnd = W.OS.tell();
Rafael Espindolafabbc492015-05-21 20:43:13 +00001152 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1153 }
1154
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001155 if (Mode == DwoOnly) {
1156 // dwo files don't have symbol tables or relocations, but they do have
1157 // string tables.
1158 StrTabBuilder.finalize();
1159 } else {
Peter Collingbournea29ff2e2018-07-17 22:17:18 +00001160 MCSectionELF *AddrsigSection;
1161 if (OWriter.EmitAddrsigSection) {
1162 AddrsigSection = Ctx.getELFSection(".llvm_addrsig", ELF::SHT_LLVM_ADDRSIG,
1163 ELF::SHF_EXCLUDE);
1164 addToSectionTable(AddrsigSection);
1165 }
1166
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001167 // Compute symbol table information.
1168 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap,
1169 SectionOffsets);
Rafael Espindolafabbc492015-05-21 20:43:13 +00001170
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001171 for (MCSectionELF *RelSection : Relocations) {
1172 align(RelSection->getAlignment());
Rafael Espindolafabbc492015-05-21 20:43:13 +00001173
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001174 // Remember the offset into the file for this section.
1175 uint64_t SecStart = W.OS.tell();
Rafael Espindolafabbc492015-05-21 20:43:13 +00001176
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001177 writeRelocations(Asm,
1178 cast<MCSectionELF>(*RelSection->getAssociatedSection()));
Rafael Espindolafabbc492015-05-21 20:43:13 +00001179
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001180 uint64_t SecEnd = W.OS.tell();
1181 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
1182 }
Peter Collingbournea29ff2e2018-07-17 22:17:18 +00001183
1184 if (OWriter.EmitAddrsigSection) {
1185 uint64_t SecStart = W.OS.tell();
1186 writeAddrsigSection();
1187 uint64_t SecEnd = W.OS.tell();
1188 SectionOffsets[AddrsigSection] = std::make_pair(SecStart, SecEnd);
1189 }
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001190 }
1191
Michael J. Spencer56500c72018-06-02 16:33:01 +00001192 if (CGProfileSection) {
1193 uint64_t SecStart = W.OS.tell();
1194 for (const MCAssembler::CGProfileEntry &CGPE : Asm.CGProfile) {
1195 W.write<uint32_t>(CGPE.From->getSymbol().getIndex());
1196 W.write<uint32_t>(CGPE.To->getSymbol().getIndex());
1197 W.write<uint64_t>(CGPE.Count);
1198 }
1199 uint64_t SecEnd = W.OS.tell();
1200 SectionOffsets[CGProfileSection] = std::make_pair(SecStart, SecEnd);
1201 }
1202
Rafael Espindola58a854d2015-04-29 20:25:24 +00001203 {
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001204 uint64_t SecStart = W.OS.tell();
Rafael Espindolad80f5162015-04-30 21:10:06 +00001205 const MCSectionELF *Sec = createStringTable(Ctx);
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001206 uint64_t SecEnd = W.OS.tell();
Rafael Espindola76e71bd2015-04-30 14:21:49 +00001207 SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
Rafael Espindola4fa3a172015-04-29 20:34:31 +00001208 }
1209
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001210 uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
Rafael Espindolaaa4466d2015-06-05 18:21:00 +00001211 align(NaturalAlignment);
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001212
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001213 const uint64_t SectionHeaderOffset = W.OS.tell();
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001214
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001215 // ... then the section header table ...
Rafael Espindola4dbd6032015-06-04 20:55:49 +00001216 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001217
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001218 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1219 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1220 : SectionTable.size() + 1,
1221 W.Endian);
Rafael Espindola840bb0f2015-04-29 20:39:37 +00001222 unsigned NumSectionsOffset;
1223
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001224 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001225 if (is64Bit()) {
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001226 uint64_t Val =
1227 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1228 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1229 offsetof(ELF::Elf64_Ehdr, e_shoff));
Rafael Espindola840bb0f2015-04-29 20:39:37 +00001230 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001231 } else {
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001232 uint32_t Val =
1233 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1234 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1235 offsetof(ELF::Elf32_Ehdr, e_shoff));
Rafael Espindola840bb0f2015-04-29 20:39:37 +00001236 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
Rafael Espindola83ed6b72015-04-14 22:54:16 +00001237 }
Peter Collingbourne8e93a952018-05-21 18:17:42 +00001238 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1239 NumSectionsOffset);
Peter Collingbourne0d4292f2018-05-21 18:23:50 +00001240
1241 return W.OS.tell() - StartOffset;
Rafael Espindola7c18fa82011-03-20 18:44:20 +00001242}
1243
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001244bool ELFObjectWriter::hasRelocationAddend() const {
1245 return TargetObjectWriter->hasRelocationAddend();
1246}
1247
1248void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1249 const MCAsmLayout &Layout) {
1250 // The presence of symbol versions causes undefined symbols and
1251 // versions declared with @@@ to be renamed.
1252 for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
1253 StringRef AliasName = P.first;
1254 const auto &Symbol = cast<MCSymbolELF>(*P.second);
1255 size_t Pos = AliasName.find('@');
1256 assert(Pos != StringRef::npos);
1257
1258 StringRef Prefix = AliasName.substr(0, Pos);
1259 StringRef Rest = AliasName.substr(Pos);
1260 StringRef Tail = Rest;
1261 if (Rest.startswith("@@@"))
1262 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1263
1264 auto *Alias =
1265 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1266 Asm.registerSymbol(*Alias);
1267 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1268 Alias->setVariableValue(Value);
1269
1270 // Aliases defined with .symvar copy the binding from the symbol they alias.
1271 // This is the first place we are able to copy this information.
1272 Alias->setExternal(Symbol.isExternal());
1273 Alias->setBinding(Symbol.getBinding());
1274
1275 if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
1276 continue;
1277
Hans Wennborg2a7ad002019-02-18 10:39:35 +00001278 // FIXME: Get source locations for these errors or diagnose them earlier.
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001279 if (Symbol.isUndefined() && Rest.startswith("@@") &&
Hans Wennborg2a7ad002019-02-18 10:39:35 +00001280 !Rest.startswith("@@@")) {
1281 Asm.getContext().reportError(SMLoc(), "versioned symbol " + AliasName +
1282 " must be defined");
1283 continue;
1284 }
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001285
Hans Wennborg2a7ad002019-02-18 10:39:35 +00001286 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias) {
1287 Asm.getContext().reportError(
1288 SMLoc(), llvm::Twine("multiple symbol versions defined for ") +
1289 Symbol.getName());
1290 continue;
1291 }
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001292
1293 Renames.insert(std::make_pair(&Symbol, Alias));
1294 }
Peter Collingbournea29ff2e2018-07-17 22:17:18 +00001295
1296 for (const MCSymbol *&Sym : AddrsigSyms) {
1297 if (const MCSymbol *R = Renames.lookup(cast<MCSymbolELF>(Sym)))
1298 Sym = R;
Peter Collingbournef06afc32018-08-06 21:59:58 +00001299 if (Sym->isInSection() && Sym->getName().startswith(".L"))
1300 Sym = Sym->getSection().getBeginSymbol();
Peter Collingbournea29ff2e2018-07-17 22:17:18 +00001301 Sym->setUsedInReloc();
1302 }
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001303}
1304
1305// It is always valid to create a relocation with a symbol. It is preferable
1306// to use a relocation with a section if that is possible. Using the section
1307// allows us to omit some local symbols from the symbol table.
1308bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1309 const MCSymbolRefExpr *RefA,
1310 const MCSymbolELF *Sym,
1311 uint64_t C,
1312 unsigned Type) const {
1313 // A PCRel relocation to an absolute value has no symbol (or section). We
1314 // represent that with a relocation to a null section.
1315 if (!RefA)
1316 return false;
1317
1318 MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
1319 switch (Kind) {
1320 default:
1321 break;
1322 // The .odp creation emits a relocation against the symbol ".TOC." which
1323 // create a R_PPC64_TOC relocation. However the relocation symbol name
1324 // in final object creation should be NULL, since the symbol does not
1325 // really exist, it is just the reference to TOC base for the current
1326 // object file. Since the symbol is undefined, returning false results
1327 // in a relocation with a null section which is the desired result.
1328 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1329 return false;
1330
1331 // These VariantKind cause the relocation to refer to something other than
1332 // the symbol itself, like a linker generated table. Since the address of
1333 // symbol is not relevant, we cannot replace the symbol with the
1334 // section and patch the difference in the addend.
1335 case MCSymbolRefExpr::VK_GOT:
1336 case MCSymbolRefExpr::VK_PLT:
1337 case MCSymbolRefExpr::VK_GOTPCREL:
1338 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1339 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1340 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1341 return true;
1342 }
1343
1344 // An undefined symbol is not in any section, so the relocation has to point
1345 // to the symbol itself.
1346 assert(Sym && "Expected a symbol");
1347 if (Sym->isUndefined())
1348 return true;
1349
1350 unsigned Binding = Sym->getBinding();
1351 switch(Binding) {
1352 default:
1353 llvm_unreachable("Invalid Binding");
1354 case ELF::STB_LOCAL:
1355 break;
1356 case ELF::STB_WEAK:
1357 // If the symbol is weak, it might be overridden by a symbol in another
1358 // file. The relocation has to point to the symbol so that the linker
1359 // can update it.
1360 return true;
1361 case ELF::STB_GLOBAL:
1362 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1363 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1364 return true;
1365 }
1366
1367 // If a relocation points to a mergeable section, we have to be careful.
1368 // If the offset is zero, a relocation with the section will encode the
1369 // same information. With a non-zero offset, the situation is different.
1370 // For example, a relocation can point 42 bytes past the end of a string.
1371 // If we change such a relocation to use the section, the linker would think
1372 // that it pointed to another string and subtracting 42 at runtime will
1373 // produce the wrong value.
1374 if (Sym->isInSection()) {
1375 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1376 unsigned Flags = Sec.getFlags();
1377 if (Flags & ELF::SHF_MERGE) {
1378 if (C != 0)
1379 return true;
1380
1381 // It looks like gold has a bug (http://sourceware.org/PR16794) and can
1382 // only handle section relocations to mergeable sections if using RELA.
1383 if (!hasRelocationAddend())
1384 return true;
1385 }
1386
1387 // Most TLS relocations use a got, so they need the symbol. Even those that
1388 // are just an offset (@tpoff), require a symbol in gold versions before
1389 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1390 // http://sourceware.org/PR16773.
1391 if (Flags & ELF::SHF_TLS)
1392 return true;
1393 }
1394
1395 // If the symbol is a thumb function the final relocation must set the lowest
1396 // bit. With a symbol that is done by just having the symbol have that bit
1397 // set, so we would lose the bit if we relocated with the section.
1398 // FIXME: We could use the section but add the bit to the relocation value.
1399 if (Asm.isThumbFunc(Sym))
1400 return true;
1401
1402 if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
1403 return true;
1404 return false;
1405}
1406
1407void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1408 const MCAsmLayout &Layout,
1409 const MCFragment *Fragment,
1410 const MCFixup &Fixup, MCValue Target,
1411 uint64_t &FixedValue) {
1412 MCAsmBackend &Backend = Asm.getBackend();
1413 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1414 MCFixupKindInfo::FKF_IsPCRel;
1415 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1416 uint64_t C = Target.getConstant();
1417 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1418 MCContext &Ctx = Asm.getContext();
1419
1420 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1421 // Let A, B and C being the components of Target and R be the location of
1422 // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
1423 // If it is pcrel, we want to compute (A - B + C - R).
1424
1425 // In general, ELF has no relocations for -B. It can only represent (A + C)
1426 // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
1427 // replace B to implement it: (A - R - K + C)
1428 if (IsPCRel) {
1429 Ctx.reportError(
1430 Fixup.getLoc(),
1431 "No relocation available to represent this relative expression");
1432 return;
1433 }
1434
1435 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1436
1437 if (SymB.isUndefined()) {
1438 Ctx.reportError(Fixup.getLoc(),
1439 Twine("symbol '") + SymB.getName() +
1440 "' can not be undefined in a subtraction expression");
1441 return;
1442 }
1443
1444 assert(!SymB.isAbsolute() && "Should have been folded");
1445 const MCSection &SecB = SymB.getSection();
1446 if (&SecB != &FixupSection) {
1447 Ctx.reportError(Fixup.getLoc(),
1448 "Cannot represent a difference across sections");
1449 return;
1450 }
1451
1452 uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
1453 uint64_t K = SymBOffset - FixupOffset;
1454 IsPCRel = true;
1455 C -= K;
1456 }
1457
1458 // We either rejected the fixup or folded B into C at this point.
1459 const MCSymbolRefExpr *RefA = Target.getSymA();
1460 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1461
1462 bool ViaWeakRef = false;
1463 if (SymA && SymA->isVariable()) {
1464 const MCExpr *Expr = SymA->getVariableValue();
1465 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1466 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1467 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1468 ViaWeakRef = true;
1469 }
1470 }
1471 }
1472
1473 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1474 uint64_t OriginalC = C;
1475 bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
1476 if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
1477 C += Layout.getSymbolOffset(*SymA);
1478
1479 uint64_t Addend = 0;
1480 if (hasRelocationAddend()) {
1481 Addend = C;
1482 C = 0;
1483 }
1484
1485 FixedValue = C;
1486
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001487 const MCSectionELF *SecA = (SymA && SymA->isInSection())
1488 ? cast<MCSectionELF>(&SymA->getSection())
1489 : nullptr;
1490 if (!checkRelocation(Ctx, Fixup.getLoc(), &FixupSection, SecA))
1491 return;
1492
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001493 if (!RelocateWithSymbol) {
Peter Collingbourne815bbef2018-05-21 19:18:28 +00001494 const auto *SectionSymbol =
1495 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1496 if (SectionSymbol)
1497 SectionSymbol->setUsedInReloc();
1498 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA,
1499 OriginalC);
1500 Relocations[&FixupSection].push_back(Rec);
1501 return;
1502 }
1503
1504 const auto *RenamedSymA = SymA;
1505 if (SymA) {
1506 if (const MCSymbolELF *R = Renames.lookup(SymA))
1507 RenamedSymA = R;
1508
1509 if (ViaWeakRef)
1510 RenamedSymA->setIsWeakrefUsedInReloc();
1511 else
1512 RenamedSymA->setUsedInReloc();
1513 }
1514 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA,
1515 OriginalC);
1516 Relocations[&FixupSection].push_back(Rec);
1517}
1518
Jim Grosbachbc812862015-06-04 22:24:41 +00001519bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
Rafael Espindola569f3822015-06-02 20:38:46 +00001520 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
Rafael Espindolafb118bd2015-04-17 21:15:17 +00001521 bool InSet, bool IsPCRel) const {
Rafael Espindola569f3822015-06-02 20:38:46 +00001522 const auto &SymA = cast<MCSymbolELF>(SA);
Rafael Espindolafb118bd2015-04-17 21:15:17 +00001523 if (IsPCRel) {
1524 assert(!InSet);
Peter Collingbourneb06c3942017-04-08 23:35:49 +00001525 if (isWeak(SymA))
Rafael Espindolafb118bd2015-04-17 21:15:17 +00001526 return false;
1527 }
Jim Grosbachbc812862015-06-04 22:24:41 +00001528 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
Rafael Espindolafb118bd2015-04-17 21:15:17 +00001529 InSet, IsPCRel);
Eli Friedman78c1e172011-03-03 07:24:36 +00001530}
1531
Lang Hamese4713462017-10-10 16:28:07 +00001532std::unique_ptr<MCObjectWriter>
Lang Hames37437af2017-10-09 23:53:15 +00001533llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1534 raw_pwrite_stream &OS, bool IsLittleEndian) {
Peter Collingbourne4ef18412018-05-21 19:30:59 +00001535 return llvm::make_unique<ELFSingleObjectWriter>(std::move(MOTW), OS,
1536 IsLittleEndian);
Rafael Espindolaedae8e12011-12-21 17:30:17 +00001537}
Peter Collingbourne60fd99d2018-05-21 19:44:54 +00001538
1539std::unique_ptr<MCObjectWriter>
1540llvm::createELFDwoObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1541 raw_pwrite_stream &OS, raw_pwrite_stream &DwoOS,
1542 bool IsLittleEndian) {
1543 return llvm::make_unique<ELFDwoObjectWriter>(std::move(MOTW), OS, DwoOS,
1544 IsLittleEndian);
1545}