blob: e7d5a96ccf181c3e7b64cf648323de157c1d6236 [file] [log] [blame]
Nick Lewycky4288f9e2013-03-09 09:32:16 +00001//===- lib/MC/ELFObjectWriter.cpp - ELF File Writer -----------------------===//
Matt Fleming6c1ad482010-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 Zelenkod3a6c892017-02-11 00:27:28 +000014#include "llvm/ADT/ArrayRef.h"
15#include "llvm/ADT/DenseMap.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000016#include "llvm/ADT/STLExtras.h"
Rafael Espindola29abd972011-12-22 03:38:00 +000017#include "llvm/ADT/SmallString.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000018#include "llvm/ADT/SmallVector.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000019#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000021#include "llvm/BinaryFormat/ELF.h"
Rafael Espindolaceecfe5b2017-07-11 23:56:10 +000022#include "llvm/MC/MCAsmBackend.h"
David Blaikie8019bf82014-04-10 21:53:53 +000023#include "llvm/MC/MCAsmInfo.h"
Matt Fleming6c1ad482010-08-16 18:57:57 +000024#include "llvm/MC/MCAsmLayout.h"
Rafael Espindola29abd972011-12-22 03:38:00 +000025#include "llvm/MC/MCAssembler.h"
Matt Fleming6c1ad482010-08-16 18:57:57 +000026#include "llvm/MC/MCContext.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000027#include "llvm/MC/MCELFObjectWriter.h"
Matt Fleming6c1ad482010-08-16 18:57:57 +000028#include "llvm/MC/MCExpr.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000029#include "llvm/MC/MCFixup.h"
Rafael Espindolaceecfe5b2017-07-11 23:56:10 +000030#include "llvm/MC/MCFixupKindInfo.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000031#include "llvm/MC/MCFragment.h"
Craig Topper6e80c282012-03-26 06:58:25 +000032#include "llvm/MC/MCObjectWriter.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000033#include "llvm/MC/MCSection.h"
Matt Fleming6c1ad482010-08-16 18:57:57 +000034#include "llvm/MC/MCSectionELF.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000035#include "llvm/MC/MCSymbol.h"
Rafael Espindolaa8695762015-06-02 00:25:12 +000036#include "llvm/MC/MCSymbolELF.h"
Matt Fleming6c1ad482010-08-16 18:57:57 +000037#include "llvm/MC/MCValue.h"
Rafael Espindola97de4742014-07-03 02:01:39 +000038#include "llvm/MC/StringTableBuilder.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000039#include "llvm/Support/Allocator.h"
40#include "llvm/Support/Casting.h"
David Blaikie8019bf82014-04-10 21:53:53 +000041#include "llvm/Support/Compression.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000042#include "llvm/Support/Endian.h"
George Rimar167ca4a2017-01-17 15:45:07 +000043#include "llvm/Support/Error.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000044#include "llvm/Support/ErrorHandling.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000045#include "llvm/Support/Host.h"
46#include "llvm/Support/MathExtras.h"
47#include "llvm/Support/SMLoc.h"
Rafael Espindolafc063e82015-10-22 18:32:06 +000048#include "llvm/Support/StringSaver.h"
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000049#include "llvm/Support/SwapByteOrder.h"
50#include "llvm/Support/raw_ostream.h"
51#include <algorithm>
52#include <cassert>
53#include <cstddef>
54#include <cstdint>
55#include <map>
56#include <memory>
57#include <string>
58#include <utility>
Matt Fleming6c1ad482010-08-16 18:57:57 +000059#include <vector>
Eugene Zelenkoecefe5a2016-02-02 18:20:45 +000060
Matt Fleming6c1ad482010-08-16 18:57:57 +000061using namespace llvm;
62
Jason W Kimc09e7262011-05-11 22:53:06 +000063#undef DEBUG_TYPE
64#define DEBUG_TYPE "reloc-info"
65
Rafael Espindola29abd972011-12-22 03:38:00 +000066namespace {
Eugene Zelenkod3a6c892017-02-11 00:27:28 +000067
Eugene Zelenko7975b992017-04-26 22:31:39 +000068using SectionIndexMapTy = DenseMap<const MCSectionELF *, uint32_t>;
Rafael Espindola10be0832014-03-25 23:44:25 +000069
Rafael Espindola91fd2772015-04-29 21:09:32 +000070class ELFObjectWriter;
Peter Collingbournea29fe572018-05-21 19:18:28 +000071struct ELFWriter;
Rafael Espindola91fd2772015-04-29 21:09:32 +000072
Rafael Espindola10be0832014-03-25 23:44:25 +000073class SymbolTableWriter {
Peter Collingbournea29fe572018-05-21 19:18:28 +000074 ELFWriter &EWriter;
Rafael Espindola10be0832014-03-25 23:44:25 +000075 bool Is64Bit;
Rafael Espindola10be0832014-03-25 23:44:25 +000076
Rafael Espindola91fd2772015-04-29 21:09:32 +000077 // indexes we are going to write to .symtab_shndx.
78 std::vector<uint32_t> ShndxIndexes;
Rafael Espindola10be0832014-03-25 23:44:25 +000079
80 // The numbel of symbols written so far.
81 unsigned NumWritten;
82
83 void createSymtabShndx();
84
Rafael Espindola91fd2772015-04-29 21:09:32 +000085 template <typename T> void write(T Value);
Rafael Espindola10be0832014-03-25 23:44:25 +000086
87public:
Peter Collingbournea29fe572018-05-21 19:18:28 +000088 SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit);
Rafael Espindola10be0832014-03-25 23:44:25 +000089
90 void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size,
91 uint8_t other, uint32_t shndx, bool Reserved);
Rafael Espindola91fd2772015-04-29 21:09:32 +000092
93 ArrayRef<uint32_t> getShndxIndexes() const { return ShndxIndexes; }
Rafael Espindola10be0832014-03-25 23:44:25 +000094};
95
Peter Collingbournea29fe572018-05-21 19:18:28 +000096struct ELFWriter {
97 ELFObjectWriter &OWriter;
98 support::endian::Writer W;
99
David Blaikiea0fa2622016-04-12 21:45:53 +0000100 static uint64_t SymbolValue(const MCSymbol &Sym, const MCAsmLayout &Layout);
101 static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
102 bool Used, bool Renamed);
Rafael Espindola29abd972011-12-22 03:38:00 +0000103
David Blaikiea0fa2622016-04-12 21:45:53 +0000104 /// Helper struct for containing some precomputed information on symbols.
105 struct ELFSymbolData {
106 const MCSymbolELF *Symbol;
107 uint32_t SectionIndex;
108 StringRef Name;
Rafael Espindola29abd972011-12-22 03:38:00 +0000109
David Blaikiea0fa2622016-04-12 21:45:53 +0000110 // Support lexicographic sorting.
111 bool operator<(const ELFSymbolData &RHS) const {
112 unsigned LHSType = Symbol->getType();
113 unsigned RHSType = RHS.Symbol->getType();
114 if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION)
115 return false;
116 if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
117 return true;
118 if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION)
119 return SectionIndex < RHS.SectionIndex;
120 return Name < RHS.Name;
Rafael Espindola29abd972011-12-22 03:38:00 +0000121 }
Rafael Espindola29abd972011-12-22 03:38:00 +0000122 };
David Blaikiea0fa2622016-04-12 21:45:53 +0000123
David Blaikiea0fa2622016-04-12 21:45:53 +0000124 /// @}
125 /// @name Symbol Table Data
126 /// @{
127
David Blaikiea0fa2622016-04-12 21:45:53 +0000128 StringTableBuilder StrTabBuilder{StringTableBuilder::ELF};
129
130 /// @}
131
132 // This holds the symbol table index of the last local symbol.
133 unsigned LastLocalSymbolIndex;
134 // This holds the .strtab section index.
135 unsigned StringTableIndex;
136 // This holds the .symtab section index.
137 unsigned SymbolTableIndex;
138
139 // Sections in the order they are to be output in the section table.
140 std::vector<const MCSectionELF *> SectionTable;
141 unsigned addToSectionTable(const MCSectionELF *Sec);
142
143 // TargetObjectWriter wrappers.
Peter Collingbournea29fe572018-05-21 19:18:28 +0000144 bool is64Bit() const;
145 bool hasRelocationAddend() const;
David Blaikiea0fa2622016-04-12 21:45:53 +0000146
147 void align(unsigned Alignment);
148
George Rimarc91e38c2016-05-27 12:27:32 +0000149 bool maybeWriteCompression(uint64_t Size,
150 SmallVectorImpl<char> &CompressedContents,
151 bool ZLibStyle, unsigned Alignment);
152
David Blaikiea0fa2622016-04-12 21:45:53 +0000153public:
Peter Collingbournea29fe572018-05-21 19:18:28 +0000154 ELFWriter(ELFObjectWriter &OWriter, raw_pwrite_stream &OS,
155 bool IsLittleEndian)
156 : OWriter(OWriter),
Peter Collingbournef17b1492018-05-21 18:17:42 +0000157 W(OS, IsLittleEndian ? support::little : support::big) {}
David Blaikiea0fa2622016-04-12 21:45:53 +0000158
Peter Collingbournef17b1492018-05-21 18:17:42 +0000159 void WriteWord(uint64_t Word) {
David Blaikiea0fa2622016-04-12 21:45:53 +0000160 if (is64Bit())
Peter Collingbournef17b1492018-05-21 18:17:42 +0000161 W.write<uint64_t>(Word);
David Blaikiea0fa2622016-04-12 21:45:53 +0000162 else
Peter Collingbournef17b1492018-05-21 18:17:42 +0000163 W.write<uint32_t>(Word);
David Blaikiea0fa2622016-04-12 21:45:53 +0000164 }
165
166 template <typename T> void write(T Val) {
Peter Collingbournef17b1492018-05-21 18:17:42 +0000167 W.write(Val);
David Blaikiea0fa2622016-04-12 21:45:53 +0000168 }
169
170 void writeHeader(const MCAssembler &Asm);
171
172 void writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
173 ELFSymbolData &MSD, const MCAsmLayout &Layout);
174
175 // Start and end offset of each section
Eugene Zelenko7975b992017-04-26 22:31:39 +0000176 using SectionOffsetsTy =
177 std::map<const MCSectionELF *, std::pair<uint64_t, uint64_t>>;
David Blaikiea0fa2622016-04-12 21:45:53 +0000178
David Blaikiea0fa2622016-04-12 21:45:53 +0000179 // Map from a signature symbol to the group section index
Eugene Zelenko7975b992017-04-26 22:31:39 +0000180 using RevGroupMapTy = DenseMap<const MCSymbol *, unsigned>;
David Blaikiea0fa2622016-04-12 21:45:53 +0000181
182 /// Compute the symbol table data
183 ///
184 /// \param Asm - The assembler.
185 /// \param SectionIndexMap - Maps a section to its index.
186 /// \param RevGroupMap - Maps a signature symbol to the group section.
187 void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout,
188 const SectionIndexMapTy &SectionIndexMap,
189 const RevGroupMapTy &RevGroupMap,
190 SectionOffsetsTy &SectionOffsets);
191
192 MCSectionELF *createRelocationSection(MCContext &Ctx,
193 const MCSectionELF &Sec);
194
195 const MCSectionELF *createStringTable(MCContext &Ctx);
196
David Blaikiea0fa2622016-04-12 21:45:53 +0000197 void writeSectionHeader(const MCAsmLayout &Layout,
198 const SectionIndexMapTy &SectionIndexMap,
199 const SectionOffsetsTy &SectionOffsets);
200
201 void writeSectionData(const MCAssembler &Asm, MCSection &Sec,
202 const MCAsmLayout &Layout);
203
204 void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
205 uint64_t Address, uint64_t Offset, uint64_t Size,
206 uint32_t Link, uint32_t Info, uint64_t Alignment,
207 uint64_t EntrySize);
208
209 void writeRelocations(const MCAssembler &Asm, const MCSectionELF &Sec);
210
Peter Collingbournea29fe572018-05-21 19:18:28 +0000211 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout);
David Blaikiea0fa2622016-04-12 21:45:53 +0000212 void writeSection(const SectionIndexMapTy &SectionIndexMap,
213 uint32_t GroupSymbolIndex, uint64_t Offset, uint64_t Size,
214 const MCSectionELF &Section);
215};
Eugene Zelenkod3a6c892017-02-11 00:27:28 +0000216
Peter Collingbournea29fe572018-05-21 19:18:28 +0000217class ELFObjectWriter : public MCObjectWriter {
218 raw_pwrite_stream &OS;
219 bool IsLittleEndian;
220
221 /// The target specific ELF writer instance.
222 std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter;
223
224 DenseMap<const MCSectionELF *, std::vector<ELFRelocationEntry>> Relocations;
225
226 DenseMap<const MCSymbolELF *, const MCSymbolELF *> Renames;
227
228 bool hasRelocationAddend() const;
229
230 bool shouldRelocateWithSymbol(const MCAssembler &Asm,
231 const MCSymbolRefExpr *RefA,
232 const MCSymbolELF *Sym, uint64_t C,
233 unsigned Type) const;
234
235public:
236 ELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
237 raw_pwrite_stream &OS, bool IsLittleEndian)
238 : OS(OS), IsLittleEndian(IsLittleEndian),
239 TargetObjectWriter(std::move(MOTW)) {}
240
241 void reset() override {
242 Relocations.clear();
243 Renames.clear();
244 MCObjectWriter::reset();
245 }
246
247 bool isSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm,
248 const MCSymbol &SymA,
249 const MCFragment &FB, bool InSet,
250 bool IsPCRel) const override;
251
252 void recordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout,
253 const MCFragment *Fragment, const MCFixup &Fixup,
254 MCValue Target, uint64_t &FixedValue) override;
255
256 uint64_t writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) override {
257 return ELFWriter(*this, OS, IsLittleEndian).writeObject(Asm, Layout);
258 }
259
260 void executePostLayoutBinding(MCAssembler &Asm,
261 const MCAsmLayout &Layout) override;
262
263 friend struct ELFWriter;
264};
265
Eugene Zelenkoecefe5a2016-02-02 18:20:45 +0000266} // end anonymous namespace
Rafael Espindola29abd972011-12-22 03:38:00 +0000267
Peter Collingbournea29fe572018-05-21 19:18:28 +0000268void ELFWriter::align(unsigned Alignment) {
Peter Collingbournef17b1492018-05-21 18:17:42 +0000269 uint64_t Padding = OffsetToAlignment(W.OS.tell(), Alignment);
270 W.OS.write_zeros(Padding);
Rafael Espindolab20fbb82015-06-05 18:21:00 +0000271}
272
Peter Collingbournea29fe572018-05-21 19:18:28 +0000273unsigned ELFWriter::addToSectionTable(const MCSectionELF *Sec) {
Rafael Espindola03d7abb2015-04-30 20:53:27 +0000274 SectionTable.push_back(Sec);
Rafael Espindola5960cee2015-05-22 23:58:30 +0000275 StrTabBuilder.add(Sec->getSectionName());
Rafael Espindola03d7abb2015-04-30 20:53:27 +0000276 return SectionTable.size();
277}
278
Rafael Espindola10be0832014-03-25 23:44:25 +0000279void SymbolTableWriter::createSymtabShndx() {
Rafael Espindola91fd2772015-04-29 21:09:32 +0000280 if (!ShndxIndexes.empty())
Rafael Espindola10be0832014-03-25 23:44:25 +0000281 return;
282
Rafael Espindola91fd2772015-04-29 21:09:32 +0000283 ShndxIndexes.resize(NumWritten);
Rafael Espindola10be0832014-03-25 23:44:25 +0000284}
285
Rafael Espindola91fd2772015-04-29 21:09:32 +0000286template <typename T> void SymbolTableWriter::write(T Value) {
287 EWriter.write(Value);
Rafael Espindola10be0832014-03-25 23:44:25 +0000288}
289
Peter Collingbournea29fe572018-05-21 19:18:28 +0000290SymbolTableWriter::SymbolTableWriter(ELFWriter &EWriter, bool Is64Bit)
Rafael Espindola91fd2772015-04-29 21:09:32 +0000291 : EWriter(EWriter), Is64Bit(Is64Bit), NumWritten(0) {}
Rafael Espindola10be0832014-03-25 23:44:25 +0000292
293void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value,
294 uint64_t size, uint8_t other,
295 uint32_t shndx, bool Reserved) {
296 bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved;
297
298 if (LargeIndex)
299 createSymtabShndx();
300
Rafael Espindola91fd2772015-04-29 21:09:32 +0000301 if (!ShndxIndexes.empty()) {
Rafael Espindola10be0832014-03-25 23:44:25 +0000302 if (LargeIndex)
Rafael Espindola91fd2772015-04-29 21:09:32 +0000303 ShndxIndexes.push_back(shndx);
Rafael Espindola10be0832014-03-25 23:44:25 +0000304 else
Rafael Espindola91fd2772015-04-29 21:09:32 +0000305 ShndxIndexes.push_back(0);
Rafael Espindola10be0832014-03-25 23:44:25 +0000306 }
307
308 uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx;
309
Rafael Espindola10be0832014-03-25 23:44:25 +0000310 if (Is64Bit) {
Rafael Espindola91fd2772015-04-29 21:09:32 +0000311 write(name); // st_name
312 write(info); // st_info
313 write(other); // st_other
314 write(Index); // st_shndx
315 write(value); // st_value
316 write(size); // st_size
Rafael Espindola10be0832014-03-25 23:44:25 +0000317 } else {
Rafael Espindola91fd2772015-04-29 21:09:32 +0000318 write(name); // st_name
319 write(uint32_t(value)); // st_value
320 write(uint32_t(size)); // st_size
321 write(info); // st_info
322 write(other); // st_other
323 write(Index); // st_shndx
Rafael Espindola10be0832014-03-25 23:44:25 +0000324 }
325
326 ++NumWritten;
327}
328
Peter Collingbournea29fe572018-05-21 19:18:28 +0000329bool ELFWriter::is64Bit() const {
330 return OWriter.TargetObjectWriter->is64Bit();
331}
332
333bool ELFWriter::hasRelocationAddend() const {
334 return OWriter.hasRelocationAddend();
335}
336
Matt Fleming6c1ad482010-08-16 18:57:57 +0000337// Emit the ELF header.
Peter Collingbournea29fe572018-05-21 19:18:28 +0000338void ELFWriter::writeHeader(const MCAssembler &Asm) {
Matt Fleming6c1ad482010-08-16 18:57:57 +0000339 // ELF Header
340 // ----------
341 //
342 // Note
343 // ----
344 // emitWord method behaves differently for ELF32 and ELF64, writing
345 // 4 bytes in the former and 8 in the latter.
346
Peter Collingbournef17b1492018-05-21 18:17:42 +0000347 W.OS << ELF::ElfMagic; // e_ident[EI_MAG0] to e_ident[EI_MAG3]
Matt Fleming6c1ad482010-08-16 18:57:57 +0000348
Peter Collingbournef17b1492018-05-21 18:17:42 +0000349 W.OS << char(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS]
Matt Fleming6c1ad482010-08-16 18:57:57 +0000350
351 // e_ident[EI_DATA]
Peter Collingbournef17b1492018-05-21 18:17:42 +0000352 W.OS << char(W.Endian == support::little ? ELF::ELFDATA2LSB
353 : ELF::ELFDATA2MSB);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000354
Peter Collingbournef17b1492018-05-21 18:17:42 +0000355 W.OS << char(ELF::EV_CURRENT); // e_ident[EI_VERSION]
Roman Divacky3b727f52010-09-09 17:57:50 +0000356 // e_ident[EI_OSABI]
Peter Collingbournea29fe572018-05-21 19:18:28 +0000357 W.OS << char(OWriter.TargetObjectWriter->getOSABI());
Peter Collingbournef17b1492018-05-21 18:17:42 +0000358 W.OS << char(0); // e_ident[EI_ABIVERSION]
Matt Fleming6c1ad482010-08-16 18:57:57 +0000359
Peter Collingbournef17b1492018-05-21 18:17:42 +0000360 W.OS.write_zeros(ELF::EI_NIDENT - ELF::EI_PAD);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000361
Peter Collingbournef17b1492018-05-21 18:17:42 +0000362 W.write<uint16_t>(ELF::ET_REL); // e_type
Matt Fleming6c1ad482010-08-16 18:57:57 +0000363
Peter Collingbournea29fe572018-05-21 19:18:28 +0000364 W.write<uint16_t>(OWriter.TargetObjectWriter->getEMachine()); // e_machine = target
Matt Fleming6c1ad482010-08-16 18:57:57 +0000365
Peter Collingbournef17b1492018-05-21 18:17:42 +0000366 W.write<uint32_t>(ELF::EV_CURRENT); // e_version
Matt Fleming6c1ad482010-08-16 18:57:57 +0000367 WriteWord(0); // e_entry, no entry point in .o file
368 WriteWord(0); // e_phoff, no program header for .o
Rafael Espindola642a2212015-04-14 22:54:16 +0000369 WriteWord(0); // e_shoff = sec hdr table off in bytes
Matt Fleming6c1ad482010-08-16 18:57:57 +0000370
Jason W Kim4761fba2011-02-04 21:41:11 +0000371 // e_flags = whatever the target wants
Peter Collingbournef17b1492018-05-21 18:17:42 +0000372 W.write<uint32_t>(Asm.getELFHeaderEFlags());
Matt Fleming6c1ad482010-08-16 18:57:57 +0000373
374 // e_ehsize = ELF header size
Peter Collingbournef17b1492018-05-21 18:17:42 +0000375 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Ehdr)
376 : sizeof(ELF::Elf32_Ehdr));
Matt Fleming6c1ad482010-08-16 18:57:57 +0000377
Peter Collingbournef17b1492018-05-21 18:17:42 +0000378 W.write<uint16_t>(0); // e_phentsize = prog header entry size
379 W.write<uint16_t>(0); // e_phnum = # prog header entries = 0
Matt Fleming6c1ad482010-08-16 18:57:57 +0000380
381 // e_shentsize = Section header entry size
Peter Collingbournef17b1492018-05-21 18:17:42 +0000382 W.write<uint16_t>(is64Bit() ? sizeof(ELF::Elf64_Shdr)
383 : sizeof(ELF::Elf32_Shdr));
Matt Fleming6c1ad482010-08-16 18:57:57 +0000384
385 // e_shnum = # of section header ents
Peter Collingbournef17b1492018-05-21 18:17:42 +0000386 W.write<uint16_t>(0);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000387
388 // e_shstrndx = Section # of '.shstrtab'
Rafael Espindola5960cee2015-05-22 23:58:30 +0000389 assert(StringTableIndex < ELF::SHN_LORESERVE);
Peter Collingbournef17b1492018-05-21 18:17:42 +0000390 W.write<uint16_t>(StringTableIndex);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000391}
392
Peter Collingbournea29fe572018-05-21 19:18:28 +0000393uint64_t ELFWriter::SymbolValue(const MCSymbol &Sym,
394 const MCAsmLayout &Layout) {
Rafael Espindola4d37b2a2015-05-29 21:45:01 +0000395 if (Sym.isCommon() && Sym.isExternal())
Rafael Espindola14672502015-05-29 17:48:04 +0000396 return Sym.getCommonAlignment();
Rafael Espindola9735f4f2010-09-27 21:23:02 +0000397
Rafael Espindolafee224f2014-04-30 21:51:13 +0000398 uint64_t Res;
Duncan P. N. Exon Smith469f9db2015-05-20 04:39:01 +0000399 if (!Layout.getSymbolOffset(Sym, Res))
Rafael Espindola553e5eb2014-04-30 16:59:35 +0000400 return 0;
401
Duncan P. N. Exon Smith469f9db2015-05-20 04:39:01 +0000402 if (Layout.getAssembler().isThumbFunc(&Sym))
Rafael Espindola66f96fe2014-03-21 22:00:29 +0000403 Res |= 1;
Rafael Espindola9735f4f2010-09-27 21:23:02 +0000404
Rafael Espindola66f96fe2014-03-21 22:00:29 +0000405 return Res;
Rafael Espindola9735f4f2010-09-27 21:23:02 +0000406}
407
Roman Divacky5a1c5492014-01-07 20:17:03 +0000408static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) {
409 uint8_t Type = newType;
410
411 // Propagation rules:
412 // IFUNC > FUNC > OBJECT > NOTYPE
413 // TLS_OBJECT > OBJECT > NOTYPE
414 //
415 // dont let the new type degrade the old type
416 switch (origType) {
417 default:
418 break;
419 case ELF::STT_GNU_IFUNC:
420 if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT ||
421 Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS)
422 Type = ELF::STT_GNU_IFUNC;
423 break;
424 case ELF::STT_FUNC:
425 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
426 Type == ELF::STT_TLS)
427 Type = ELF::STT_FUNC;
428 break;
429 case ELF::STT_OBJECT:
430 if (Type == ELF::STT_NOTYPE)
431 Type = ELF::STT_OBJECT;
432 break;
433 case ELF::STT_TLS:
434 if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE ||
435 Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC)
436 Type = ELF::STT_TLS;
437 break;
438 }
439
440 return Type;
441}
442
Peter Collingbournea29fe572018-05-21 19:18:28 +0000443void ELFWriter::writeSymbol(SymbolTableWriter &Writer, uint32_t StringIndex,
444 ELFSymbolData &MSD, const MCAsmLayout &Layout) {
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000445 const auto &Symbol = cast<MCSymbolELF>(*MSD.Symbol);
Rafael Espindolaa8695762015-06-02 00:25:12 +0000446 const MCSymbolELF *Base =
447 cast_or_null<MCSymbolELF>(Layout.getBaseSymbol(Symbol));
Rafael Espindola85a84912014-03-26 00:16:43 +0000448
449 // This has to be in sync with when computeSymbolTable uses SHN_ABS or
450 // SHN_COMMON.
Rafael Espindola4d37b2a2015-05-29 21:45:01 +0000451 bool IsReserved = !Base || Symbol.isCommon();
Rafael Espindola3fe87a12010-10-31 00:16:26 +0000452
Jack Carter2f8d9d92013-02-19 21:57:35 +0000453 // Binding and Type share the same byte as upper and lower nibbles
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000454 uint8_t Binding = Symbol.getBinding();
455 uint8_t Type = Symbol.getType();
Rafael Espindolaa6e3a592014-03-23 03:33:20 +0000456 if (Base) {
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000457 Type = mergeTypeForSet(Type, Base->getType());
Rafael Espindolaa6e3a592014-03-23 03:33:20 +0000458 }
Rafael Espindolaf8794ff2015-06-04 00:47:43 +0000459 uint8_t Info = (Binding << 4) | Type;
Jack Carter2f8d9d92013-02-19 21:57:35 +0000460
Joerg Sonnenbergerfc184732013-10-29 01:06:17 +0000461 // Other and Visibility share the same byte with Visibility using the lower
Jack Carter2f8d9d92013-02-19 21:57:35 +0000462 // 2 bits
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000463 uint8_t Visibility = Symbol.getVisibility();
Rafael Espindola8c006ee2015-06-04 05:59:23 +0000464 uint8_t Other = Symbol.getOther() | Visibility;
Rafael Espindola5f2d6a52010-10-06 21:02:29 +0000465
Duncan P. N. Exon Smith469f9db2015-05-20 04:39:01 +0000466 uint64_t Value = SymbolValue(*MSD.Symbol, Layout);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000467 uint64_t Size = 0;
Matt Fleming6c1ad482010-08-16 18:57:57 +0000468
Rafael Espindola7c23cba2015-05-29 17:24:52 +0000469 const MCExpr *ESize = MSD.Symbol->getSize();
Rafael Espindolaa041ef12014-03-27 00:28:24 +0000470 if (!ESize && Base)
Rafael Espindola7c23cba2015-05-29 17:24:52 +0000471 ESize = Base->getSize();
Rafael Espindolaf0591c12010-09-21 00:24:38 +0000472
Rafael Espindola73c0ae72010-12-22 16:03:00 +0000473 if (ESize) {
474 int64_t Res;
Rafael Espindola94a88d72015-04-06 15:27:57 +0000475 if (!ESize->evaluateKnownAbsolute(Res, Layout))
Rafael Espindola73c0ae72010-12-22 16:03:00 +0000476 report_fatal_error("Size expression must be absolute.");
477 Size = Res;
Matt Fleming6c1ad482010-08-16 18:57:57 +0000478 }
479
480 // Write out the symbol table entry
Rafael Espindolae48421f2015-05-28 20:25:29 +0000481 Writer.writeSymbol(StringIndex, Info, Value, Size, Other, MSD.SectionIndex,
482 IsReserved);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000483}
484
Rafael Espindoladb8a5862015-04-17 20:05:17 +0000485// True if the assembler knows nothing about the final value of the symbol.
486// This doesn't cover the comdat issues, since in those cases the assembler
487// can at least know that all symbols in the section will move together.
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000488static bool isWeak(const MCSymbolELF &Sym) {
489 if (Sym.getType() == ELF::STT_GNU_IFUNC)
Rafael Espindolaa635d832015-04-17 08:46:11 +0000490 return true;
491
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000492 switch (Sym.getBinding()) {
Rafael Espindolaa635d832015-04-17 08:46:11 +0000493 default:
494 llvm_unreachable("Unknown binding");
495 case ELF::STB_LOCAL:
496 return false;
497 case ELF::STB_GLOBAL:
Rafael Espindoladb8a5862015-04-17 20:05:17 +0000498 return false;
Rafael Espindolaa635d832015-04-17 08:46:11 +0000499 case ELF::STB_WEAK:
500 case ELF::STB_GNU_UNIQUE:
501 return true;
502 }
Rafael Espindolac9e70682015-03-24 23:48:44 +0000503}
504
Peter Collingbournea29fe572018-05-21 19:18:28 +0000505bool ELFWriter::isInSymtab(const MCAsmLayout &Layout, const MCSymbolELF &Symbol,
506 bool Used, bool Renamed) {
Rafael Espindola7fadc0e2014-03-20 02:12:01 +0000507 if (Symbol.isVariable()) {
508 const MCExpr *Expr = Symbol.getVariableValue();
509 if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) {
510 if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF)
511 return false;
512 }
513 }
Rafael Espindola16145972010-11-01 14:28:48 +0000514
Rafael Espindolaee8d1512010-10-19 19:31:37 +0000515 if (Used)
516 return true;
517
Rafael Espindolaeb0c2c12010-10-27 15:18:17 +0000518 if (Renamed)
519 return false;
520
Rafael Espindolaef1e8632015-06-03 21:23:21 +0000521 if (Symbol.isVariable() && Symbol.isUndefined()) {
522 // FIXME: this is here just to diagnose the case of a var = commmon_sym.
523 Layout.getBaseSymbol(Symbol);
524 return false;
Rafael Espindola3b5ee552014-04-28 13:39:57 +0000525 }
Rafael Espindola9e18e962011-02-23 20:22:07 +0000526
Rafael Espindolaef1e8632015-06-03 21:23:21 +0000527 if (Symbol.isUndefined() && !Symbol.isBindingSet())
Rafael Espindolaa5efd6a2010-10-27 14:44:52 +0000528 return false;
529
Rafael Espindolaee8d1512010-10-19 19:31:37 +0000530 if (Symbol.isTemporary())
Rafael Espindolab1d07892010-10-05 18:01:23 +0000531 return false;
532
Rafael Espindolaa401eee2015-06-04 15:33:30 +0000533 if (Symbol.getType() == ELF::STT_SECTION)
534 return false;
535
Rafael Espindolab1d07892010-10-05 18:01:23 +0000536 return true;
537}
538
Peter Collingbournea29fe572018-05-21 19:18:28 +0000539void ELFWriter::computeSymbolTable(
Rafael Espindolaea1b3942015-04-07 19:00:17 +0000540 MCAssembler &Asm, const MCAsmLayout &Layout,
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000541 const SectionIndexMapTy &SectionIndexMap, const RevGroupMapTy &RevGroupMap,
542 SectionOffsetsTy &SectionOffsets) {
Rafael Espindola5960cee2015-05-22 23:58:30 +0000543 MCContext &Ctx = Asm.getContext();
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000544 SymbolTableWriter Writer(*this, is64Bit());
545
Rafael Espindola5960cee2015-05-22 23:58:30 +0000546 // Symbol table
547 unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32;
548 MCSectionELF *SymtabSection =
549 Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, EntrySize, "");
550 SymtabSection->setAlignment(is64Bit() ? 8 : 4);
551 SymbolTableIndex = addToSectionTable(SymtabSection);
552
Rafael Espindolab20fbb82015-06-05 18:21:00 +0000553 align(SymtabSection->getAlignment());
Peter Collingbournef17b1492018-05-21 18:17:42 +0000554 uint64_t SecStart = W.OS.tell();
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000555
556 // The first entry is the undefined symbol entry.
557 Writer.writeSymbol(0, 0, 0, 0, 0, 0, false);
558
Rafael Espindolacfbd35c2015-05-28 20:11:34 +0000559 std::vector<ELFSymbolData> LocalSymbolData;
560 std::vector<ELFSymbolData> ExternalSymbolData;
Rafael Espindolacfbd35c2015-05-28 20:11:34 +0000561
Rafael Espindolabee6e9f2010-10-14 16:34:44 +0000562 // Add the data for the symbols.
Rafael Espindola5960cee2015-05-22 23:58:30 +0000563 bool HasLargeSectionIndex = false;
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000564 for (const MCSymbol &S : Asm.symbols()) {
565 const auto &Symbol = cast<MCSymbolELF>(S);
Rafael Espindolaada43f62015-06-03 21:30:10 +0000566 bool Used = Symbol.isUsedInReloc();
Rafael Espindola212fdde2015-06-03 21:52:06 +0000567 bool WeakrefUsed = Symbol.isWeakrefUsedInReloc();
Rafael Espindola8c52a9b2015-06-03 21:41:59 +0000568 bool isSignature = Symbol.isSignature();
Rafael Espindola7d0ba342010-11-14 04:17:37 +0000569
Duncan P. N. Exon Smith469f9db2015-05-20 04:39:01 +0000570 if (!isInSymtab(Layout, Symbol, Used || WeakrefUsed || isSignature,
Peter Collingbournea29fe572018-05-21 19:18:28 +0000571 OWriter.Renames.count(&Symbol)))
Matt Fleming6c1ad482010-08-16 18:57:57 +0000572 continue;
573
Oliver Stannard9be59af2015-11-17 10:00:43 +0000574 if (Symbol.isTemporary() && Symbol.isUndefined()) {
575 Ctx.reportError(SMLoc(), "Undefined temporary symbol");
576 continue;
577 }
Rafael Espindola6dff8142015-06-25 20:10:45 +0000578
Matt Fleming6c1ad482010-08-16 18:57:57 +0000579 ELFSymbolData MSD;
Rafael Espindolaa8695762015-06-02 00:25:12 +0000580 MSD.Symbol = cast<MCSymbolELF>(&Symbol);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000581
Rafael Espindola8c52a9b2015-06-03 21:41:59 +0000582 bool Local = Symbol.getBinding() == ELF::STB_LOCAL;
Rafael Espindola6dff8142015-06-25 20:10:45 +0000583 assert(Local || !Symbol.isTemporary());
584
Rafael Espindolaf4b44302015-05-29 15:07:27 +0000585 if (Symbol.isAbsolute()) {
Rafael Espindola022bb762014-03-24 03:43:21 +0000586 MSD.SectionIndex = ELF::SHN_ABS;
Rafael Espindola14672502015-05-29 17:48:04 +0000587 } else if (Symbol.isCommon()) {
Rafael Espindolabee6e9f2010-10-14 16:34:44 +0000588 assert(!Local);
Rafael Espindolaf0591c12010-09-21 00:24:38 +0000589 MSD.SectionIndex = ELF::SHN_COMMON;
Rafael Espindolaf4b44302015-05-29 15:07:27 +0000590 } else if (Symbol.isUndefined()) {
Rafael Espindola5960cee2015-05-22 23:58:30 +0000591 if (isSignature && !Used) {
Rafael Espindola89feff32015-04-28 22:59:58 +0000592 MSD.SectionIndex = RevGroupMap.lookup(&Symbol);
Rafael Espindola5960cee2015-05-22 23:58:30 +0000593 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
594 HasLargeSectionIndex = true;
595 } else {
Rafael Espindola7d0ba342010-11-14 04:17:37 +0000596 MSD.SectionIndex = ELF::SHN_UNDEF;
Rafael Espindola5960cee2015-05-22 23:58:30 +0000597 }
Matt Fleming6c1ad482010-08-16 18:57:57 +0000598 } else {
Rafael Espindolad6340032010-11-10 21:51:05 +0000599 const MCSectionELF &Section =
Rafael Espindolaf4b44302015-05-29 15:07:27 +0000600 static_cast<const MCSectionELF &>(Symbol.getSection());
Rafael Espindolad6340032010-11-10 21:51:05 +0000601 MSD.SectionIndex = SectionIndexMap.lookup(&Section);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000602 assert(MSD.SectionIndex && "Invalid section index!");
Rafael Espindola5960cee2015-05-22 23:58:30 +0000603 if (MSD.SectionIndex >= ELF::SHN_LORESERVE)
604 HasLargeSectionIndex = true;
Rafael Espindolafbcf0db2010-10-15 15:39:06 +0000605 }
606
Rafael Espindolaeb0c2c12010-10-27 15:18:17 +0000607 StringRef Name = Symbol.getName();
Rafael Espindolab6613022014-10-17 01:48:58 +0000608
609 // Sections have their own string table
Rafael Espindolafc063e82015-10-22 18:32:06 +0000610 if (Symbol.getType() != ELF::STT_SECTION) {
611 MSD.Name = Name;
612 StrTabBuilder.add(Name);
613 }
Rafael Espindolaeb0c2c12010-10-27 15:18:17 +0000614
Rafael Espindola10d23872015-05-29 14:20:40 +0000615 if (Local)
Rafael Espindolaa5efd6a2010-10-27 14:44:52 +0000616 LocalSymbolData.push_back(MSD);
617 else
618 ExternalSymbolData.push_back(MSD);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000619 }
620
Rafael Espindola2cd19512015-07-02 16:59:57 +0000621 // This holds the .symtab_shndx section index.
622 unsigned SymtabShndxSectionIndex = 0;
623
Rafael Espindola5960cee2015-05-22 23:58:30 +0000624 if (HasLargeSectionIndex) {
625 MCSectionELF *SymtabShndxSection =
626 Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, "");
627 SymtabShndxSectionIndex = addToSectionTable(SymtabShndxSection);
628 SymtabShndxSection->setAlignment(4);
629 }
630
Rafael Espindola1fd36272015-05-28 19:29:15 +0000631 ArrayRef<std::string> FileNames = Asm.getFileNames();
632 for (const std::string &Name : FileNames)
Rafael Espindola66f3c9c2015-05-28 18:03:20 +0000633 StrTabBuilder.add(Name);
Hans Wennborg83e6e1e2014-04-30 16:25:02 +0000634
Rafael Espindola21956e42015-10-23 21:48:05 +0000635 StrTabBuilder.finalize();
Hans Wennborg83e6e1e2014-04-30 16:25:02 +0000636
Peter Collingbourne5b75fd92017-03-03 21:22:06 +0000637 // File symbols are emitted first and handled separately from normal symbols,
638 // i.e. a non-STT_FILE symbol with the same name may appear.
Rafael Espindola0cbea292015-05-28 20:00:13 +0000639 for (const std::string &Name : FileNames)
640 Writer.writeSymbol(StrTabBuilder.getOffset(Name),
641 ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, ELF::STV_DEFAULT,
642 ELF::SHN_ABS, true);
643
Matt Fleming6c1ad482010-08-16 18:57:57 +0000644 // Symbols are required to be in lexicographic order.
645 array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end());
646 array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end());
Matt Fleming6c1ad482010-08-16 18:57:57 +0000647
648 // Set the symbol indices. Local symbols must come before all other
649 // symbols with non-local bindings.
Rafael Espindola1fd36272015-05-28 19:29:15 +0000650 unsigned Index = FileNames.size() + 1;
Rafael Espindola0e3decf2010-11-14 03:12:24 +0000651
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000652 for (ELFSymbolData &MSD : LocalSymbolData) {
Daniel Jasper41de8022015-06-23 11:31:32 +0000653 unsigned StringIndex = MSD.Symbol->getType() == ELF::STT_SECTION
654 ? 0
655 : StrTabBuilder.getOffset(MSD.Name);
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000656 MSD.Symbol->setIndex(Index++);
Rafael Espindolae48421f2015-05-28 20:25:29 +0000657 writeSymbol(Writer, StringIndex, MSD, Layout);
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000658 }
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000659
660 // Write the symbol table entries.
Rafael Espindola0cbea292015-05-28 20:00:13 +0000661 LastLocalSymbolIndex = Index;
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000662
Rafael Espindoladcda9972015-05-28 19:43:20 +0000663 for (ELFSymbolData &MSD : ExternalSymbolData) {
Rafael Espindolae48421f2015-05-28 20:25:29 +0000664 unsigned StringIndex = StrTabBuilder.getOffset(MSD.Name);
Rafael Espindola0cbea292015-05-28 20:00:13 +0000665 MSD.Symbol->setIndex(Index++);
Rafael Espindolae48421f2015-05-28 20:25:29 +0000666 writeSymbol(Writer, StringIndex, MSD, Layout);
Rafael Espindola95fb9b92015-06-02 20:38:46 +0000667 assert(MSD.Symbol->getBinding() != ELF::STB_LOCAL);
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000668 }
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000669
Peter Collingbournef17b1492018-05-21 18:17:42 +0000670 uint64_t SecEnd = W.OS.tell();
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000671 SectionOffsets[SymtabSection] = std::make_pair(SecStart, SecEnd);
672
673 ArrayRef<uint32_t> ShndxIndexes = Writer.getShndxIndexes();
674 if (ShndxIndexes.empty()) {
675 assert(SymtabShndxSectionIndex == 0);
676 return;
677 }
678 assert(SymtabShndxSectionIndex != 0);
679
Peter Collingbournef17b1492018-05-21 18:17:42 +0000680 SecStart = W.OS.tell();
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000681 const MCSectionELF *SymtabShndxSection =
682 SectionTable[SymtabShndxSectionIndex - 1];
683 for (uint32_t Index : ShndxIndexes)
684 write(Index);
Peter Collingbournef17b1492018-05-21 18:17:42 +0000685 SecEnd = W.OS.tell();
Rafael Espindolaaa486e92015-05-28 17:54:01 +0000686 SectionOffsets[SymtabShndxSection] = std::make_pair(SecStart, SecEnd);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000687}
688
Peter Collingbournea29fe572018-05-21 19:18:28 +0000689MCSectionELF *ELFWriter::createRelocationSection(MCContext &Ctx,
690 const MCSectionELF &Sec) {
691 if (OWriter.Relocations[&Sec].empty())
Rafael Espindolabda19802015-04-30 14:21:49 +0000692 return nullptr;
Rafael Espindola1557fd62011-03-20 18:44:20 +0000693
Rafael Espindola34948e52015-04-30 00:45:46 +0000694 const StringRef SectionName = Sec.getSectionName();
Rafael Espindolaead85492015-02-17 20:31:13 +0000695 std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel";
696 RelaSectionName += SectionName;
Benjamin Kramerfd054152010-08-17 17:56:13 +0000697
Rafael Espindolaead85492015-02-17 20:31:13 +0000698 unsigned EntrySize;
699 if (hasRelocationAddend())
700 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela);
701 else
702 EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000703
Rafael Espindolaead85492015-02-17 20:31:13 +0000704 unsigned Flags = 0;
Rafael Espindola34948e52015-04-30 00:45:46 +0000705 if (Sec.getFlags() & ELF::SHF_GROUP)
Rafael Espindolaead85492015-02-17 20:31:13 +0000706 Flags = ELF::SHF_GROUP;
Rafael Espindolaead85492015-02-17 20:31:13 +0000707
Rafael Espindola0709a7b2015-05-21 19:20:38 +0000708 MCSectionELF *RelaSection = Ctx.createELFRelSection(
Rafael Espindolaead85492015-02-17 20:31:13 +0000709 RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL,
Rafael Espindola34948e52015-04-30 00:45:46 +0000710 Flags, EntrySize, Sec.getGroup(), &Sec);
Rafael Espindola0a82ad72015-05-21 20:43:13 +0000711 RelaSection->setAlignment(is64Bit() ? 8 : 4);
Rafael Espindolabda19802015-04-30 14:21:49 +0000712 return RelaSection;
Rafael Espindola1557fd62011-03-20 18:44:20 +0000713}
Matt Fleming6c1ad482010-08-16 18:57:57 +0000714
George Rimarc91e38c2016-05-27 12:27:32 +0000715// Include the debug info compression header.
Peter Collingbournea29fe572018-05-21 19:18:28 +0000716bool ELFWriter::maybeWriteCompression(
George Rimarc91e38c2016-05-27 12:27:32 +0000717 uint64_t Size, SmallVectorImpl<char> &CompressedContents, bool ZLibStyle,
718 unsigned Alignment) {
719 if (ZLibStyle) {
720 uint64_t HdrSize =
721 is64Bit() ? sizeof(ELF::Elf32_Chdr) : sizeof(ELF::Elf64_Chdr);
722 if (Size <= HdrSize + CompressedContents.size())
723 return false;
724 // Platform specific header is followed by compressed data.
725 if (is64Bit()) {
726 // Write Elf64_Chdr header.
727 write(static_cast<ELF::Elf64_Word>(ELF::ELFCOMPRESS_ZLIB));
728 write(static_cast<ELF::Elf64_Word>(0)); // ch_reserved field.
729 write(static_cast<ELF::Elf64_Xword>(Size));
730 write(static_cast<ELF::Elf64_Xword>(Alignment));
731 } else {
732 // Write Elf32_Chdr header otherwise.
733 write(static_cast<ELF::Elf32_Word>(ELF::ELFCOMPRESS_ZLIB));
734 write(static_cast<ELF::Elf32_Word>(Size));
735 write(static_cast<ELF::Elf32_Word>(Alignment));
736 }
737 return true;
738 }
739
740 // "ZLIB" followed by 8 bytes representing the uncompressed size of the section,
741 // useful for consumers to preallocate a buffer to decompress into.
Richard Smithb910e562016-05-25 00:14:12 +0000742 const StringRef Magic = "ZLIB";
743 if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size())
744 return false;
Peter Collingbournef17b1492018-05-21 18:17:42 +0000745 W.OS << Magic;
746 support::endian::write(W.OS, Size, support::big);
Richard Smithb910e562016-05-25 00:14:12 +0000747 return true;
748}
749
Peter Collingbournea29fe572018-05-21 19:18:28 +0000750void ELFWriter::writeSectionData(const MCAssembler &Asm, MCSection &Sec,
751 const MCAsmLayout &Layout) {
Rafael Espindolae15b1b72015-05-27 13:30:50 +0000752 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
Rafael Espindola868b3f42015-04-30 21:51:58 +0000753 StringRef SectionName = Section.getSectionName();
David Blaikie8019bf82014-04-10 21:53:53 +0000754
Saleem Abdulrasool1f62f572017-06-09 00:40:19 +0000755 auto &MC = Asm.getContext();
756 const auto &MAI = MC.getAsmInfo();
757
Rafael Espindola868b3f42015-04-30 21:51:58 +0000758 // Compressing debug_frame requires handling alignment fragments which is
759 // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow
760 // for writing to arbitrary buffers) for little benefit.
George Rimarc91e38c2016-05-27 12:27:32 +0000761 bool CompressionEnabled =
Saleem Abdulrasool1f62f572017-06-09 00:40:19 +0000762 MAI->compressDebugSections() != DebugCompressionType::None;
George Rimarc91e38c2016-05-27 12:27:32 +0000763 if (!CompressionEnabled || !SectionName.startswith(".debug_") ||
764 SectionName == ".debug_frame") {
Peter Collingbournef17b1492018-05-21 18:17:42 +0000765 Asm.writeSectionData(W.OS, &Section, Layout);
Rafael Espindola868b3f42015-04-30 21:51:58 +0000766 return;
767 }
768
Saleem Abdulrasool1f62f572017-06-09 00:40:19 +0000769 assert((MAI->compressDebugSections() == DebugCompressionType::Z ||
770 MAI->compressDebugSections() == DebugCompressionType::GNU) &&
771 "expected zlib or zlib-gnu style compression");
772
David Majnemerabdb2d2a2015-09-01 16:19:03 +0000773 SmallVector<char, 128> UncompressedData;
774 raw_svector_ostream VecOS(UncompressedData);
Peter Collingbourne147db3e2018-05-21 18:11:35 +0000775 Asm.writeSectionData(VecOS, &Section, Layout);
David Blaikie8019bf82014-04-10 21:53:53 +0000776
Rafael Espindola868b3f42015-04-30 21:51:58 +0000777 SmallVector<char, 128> CompressedContents;
George Rimar167ca4a2017-01-17 15:45:07 +0000778 if (Error E = zlib::compress(
779 StringRef(UncompressedData.data(), UncompressedData.size()),
780 CompressedContents)) {
781 consumeError(std::move(E));
Peter Collingbournef17b1492018-05-21 18:17:42 +0000782 W.OS << UncompressedData;
David Blaikie8019bf82014-04-10 21:53:53 +0000783 return;
Rafael Espindola868b3f42015-04-30 21:51:58 +0000784 }
David Blaikie8019bf82014-04-10 21:53:53 +0000785
Saleem Abdulrasool1f62f572017-06-09 00:40:19 +0000786 bool ZlibStyle = MAI->compressDebugSections() == DebugCompressionType::Z;
George Rimarc91e38c2016-05-27 12:27:32 +0000787 if (!maybeWriteCompression(UncompressedData.size(), CompressedContents,
788 ZlibStyle, Sec.getAlignment())) {
Peter Collingbournef17b1492018-05-21 18:17:42 +0000789 W.OS << UncompressedData;
Rafael Espindola868b3f42015-04-30 21:51:58 +0000790 return;
791 }
George Rimarc91e38c2016-05-27 12:27:32 +0000792
793 if (ZlibStyle)
794 // Set the compressed flag. That is zlib style.
795 Section.setFlags(Section.getFlags() | ELF::SHF_COMPRESSED);
796 else
797 // Add "z" prefix to section name. This is zlib-gnu style.
Saleem Abdulrasool1f62f572017-06-09 00:40:19 +0000798 MC.renameELFSection(&Section, (".z" + SectionName.drop_front(1)).str());
Peter Collingbournef17b1492018-05-21 18:17:42 +0000799 W.OS << CompressedContents;
David Blaikie8019bf82014-04-10 21:53:53 +0000800}
801
Peter Collingbournea29fe572018-05-21 19:18:28 +0000802void ELFWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags,
803 uint64_t Address, uint64_t Offset,
804 uint64_t Size, uint32_t Link, uint32_t Info,
805 uint64_t Alignment, uint64_t EntrySize) {
Peter Collingbournef17b1492018-05-21 18:17:42 +0000806 W.write<uint32_t>(Name); // sh_name: index into string table
807 W.write<uint32_t>(Type); // sh_type
Matt Fleming6c1ad482010-08-16 18:57:57 +0000808 WriteWord(Flags); // sh_flags
809 WriteWord(Address); // sh_addr
810 WriteWord(Offset); // sh_offset
811 WriteWord(Size); // sh_size
Peter Collingbournef17b1492018-05-21 18:17:42 +0000812 W.write<uint32_t>(Link); // sh_link
813 W.write<uint32_t>(Info); // sh_info
Matt Fleming6c1ad482010-08-16 18:57:57 +0000814 WriteWord(Alignment); // sh_addralign
815 WriteWord(EntrySize); // sh_entsize
816}
817
Peter Collingbournea29fe572018-05-21 19:18:28 +0000818void ELFWriter::writeRelocations(const MCAssembler &Asm,
Rafael Espindola34948e52015-04-30 00:45:46 +0000819 const MCSectionELF &Sec) {
Peter Collingbournea29fe572018-05-21 19:18:28 +0000820 std::vector<ELFRelocationEntry> &Relocs = OWriter.Relocations[&Sec];
Akira Hatanaka64ad2cf2012-03-23 23:06:45 +0000821
Rafael Espindolaf44db242015-12-17 16:22:06 +0000822 // We record relocations by pushing to the end of a vector. Reverse the vector
823 // to get the relocations in the order they were created.
824 // In most cases that is not important, but it can be for special sections
825 // (.eh_frame) or specific relocations (TLS optimizations on SystemZ).
826 std::reverse(Relocs.begin(), Relocs.end());
Rafael Espindolad0e16522015-12-17 15:08:24 +0000827
Rafael Espindolaf44db242015-12-17 16:22:06 +0000828 // Sort the relocation entries. MIPS needs this.
Peter Collingbournea29fe572018-05-21 19:18:28 +0000829 OWriter.TargetObjectWriter->sortRelocs(Asm, Relocs);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000830
831 for (unsigned i = 0, e = Relocs.size(); i != e; ++i) {
Rafael Espindola5904e122014-03-29 06:26:49 +0000832 const ELFRelocationEntry &Entry = Relocs[e - i - 1];
Rafael Espindola5e9ed902015-05-28 20:53:09 +0000833 unsigned Index = Entry.Symbol ? Entry.Symbol->getIndex() : 0;
Rafael Espindola5904e122014-03-29 06:26:49 +0000834
Rafael Espindolafdaae0d2010-12-18 03:27:34 +0000835 if (is64Bit()) {
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000836 write(Entry.Offset);
Peter Collingbournea29fe572018-05-21 19:18:28 +0000837 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000838 write(uint32_t(Index));
Benjamin Kramer6c3c3492010-09-09 18:01:29 +0000839
Peter Collingbournea29fe572018-05-21 19:18:28 +0000840 write(OWriter.TargetObjectWriter->getRSsym(Entry.Type));
841 write(OWriter.TargetObjectWriter->getRType3(Entry.Type));
842 write(OWriter.TargetObjectWriter->getRType2(Entry.Type));
843 write(OWriter.TargetObjectWriter->getRType(Entry.Type));
Rafael Espindola5904e122014-03-29 06:26:49 +0000844 } else {
Jack Carter8ad0c272012-06-27 22:28:30 +0000845 struct ELF::Elf64_Rela ERE64;
Rafael Espindola5904e122014-03-29 06:26:49 +0000846 ERE64.setSymbolAndType(Index, Entry.Type);
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000847 write(ERE64.r_info);
Jack Carter8ad0c272012-06-27 22:28:30 +0000848 }
Rafael Espindolafdaae0d2010-12-18 03:27:34 +0000849 if (hasRelocationAddend())
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000850 write(Entry.Addend);
Benjamin Kramer6c3c3492010-09-09 18:01:29 +0000851 } else {
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000852 write(uint32_t(Entry.Offset));
Benjamin Kramer6c3c3492010-09-09 18:01:29 +0000853
Rafael Espindolabce26a12010-10-05 15:11:03 +0000854 struct ELF::Elf32_Rela ERE32;
Rafael Espindola5904e122014-03-29 06:26:49 +0000855 ERE32.setSymbolAndType(Index, Entry.Type);
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000856 write(ERE32.r_info);
Benjamin Kramer6c3c3492010-09-09 18:01:29 +0000857
Rafael Espindolafdaae0d2010-12-18 03:27:34 +0000858 if (hasRelocationAddend())
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000859 write(uint32_t(Entry.Addend));
Simon Atanasyanede43b72017-09-21 14:04:53 +0000860
Peter Collingbournea29fe572018-05-21 19:18:28 +0000861 if (OWriter.TargetObjectWriter->getEMachine() == ELF::EM_MIPS) {
862 if (uint32_t RType =
863 OWriter.TargetObjectWriter->getRType2(Entry.Type)) {
Simon Atanasyanede43b72017-09-21 14:04:53 +0000864 write(uint32_t(Entry.Offset));
865
866 ERE32.setSymbolAndType(0, RType);
867 write(ERE32.r_info);
868 write(uint32_t(0));
869 }
Peter Collingbournea29fe572018-05-21 19:18:28 +0000870 if (uint32_t RType =
871 OWriter.TargetObjectWriter->getRType3(Entry.Type)) {
Simon Atanasyanede43b72017-09-21 14:04:53 +0000872 write(uint32_t(Entry.Offset));
873
874 ERE32.setSymbolAndType(0, RType);
875 write(ERE32.r_info);
876 write(uint32_t(0));
877 }
878 }
Benjamin Kramer6c3c3492010-09-09 18:01:29 +0000879 }
Matt Fleming6c1ad482010-08-16 18:57:57 +0000880 }
881}
882
Peter Collingbournea29fe572018-05-21 19:18:28 +0000883const MCSectionELF *ELFWriter::createStringTable(MCContext &Ctx) {
Rafael Espindola08850b32015-05-25 21:56:55 +0000884 const MCSectionELF *StrtabSection = SectionTable[StringTableIndex - 1];
Peter Collingbournef17b1492018-05-21 18:17:42 +0000885 StrTabBuilder.write(W.OS);
Rafael Espindolabda19802015-04-30 14:21:49 +0000886 return StrtabSection;
Rafael Espindolaa3e9a222010-11-11 18:13:52 +0000887}
888
Peter Collingbournea29fe572018-05-21 19:18:28 +0000889void ELFWriter::writeSection(const SectionIndexMapTy &SectionIndexMap,
890 uint32_t GroupSymbolIndex, uint64_t Offset,
891 uint64_t Size, const MCSectionELF &Section) {
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000892 uint64_t sh_link = 0;
893 uint64_t sh_info = 0;
894
895 switch(Section.getType()) {
Rafael Espindola86fe2fe2015-04-06 03:16:51 +0000896 default:
897 // Nothing to do.
898 break;
899
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000900 case ELF::SHT_DYNAMIC:
Rafael Espindola74ef4802015-04-30 21:20:06 +0000901 llvm_unreachable("SHT_DYNAMIC in a relocatable object");
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000902
903 case ELF::SHT_REL:
904 case ELF::SHT_RELA: {
Rafael Espindola3a7c0eb2015-02-17 20:37:50 +0000905 sh_link = SymbolTableIndex;
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000906 assert(sh_link && ".symtab not found");
Evgeniy Stepanov43dcf4d2017-03-14 19:28:51 +0000907 const MCSection *InfoSection = Section.getAssociatedSection();
908 sh_info = SectionIndexMap.lookup(cast<MCSectionELF>(InfoSection));
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000909 break;
910 }
911
912 case ELF::SHT_SYMTAB:
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000913 sh_link = StringTableIndex;
914 sh_info = LastLocalSymbolIndex;
915 break;
916
917 case ELF::SHT_SYMTAB_SHNDX:
918 sh_link = SymbolTableIndex;
919 break;
920
Nick Lewyckyc6ac5f72011-10-07 23:28:32 +0000921 case ELF::SHT_GROUP:
Rafael Espindolaa3e9a222010-11-11 18:13:52 +0000922 sh_link = SymbolTableIndex;
923 sh_info = GroupSymbolIndex;
924 break;
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000925 }
926
Evgeniy Stepanov43dcf4d2017-03-14 19:28:51 +0000927 if (Section.getFlags() & ELF::SHF_LINK_ORDER) {
928 const MCSymbol *Sym = Section.getAssociatedSymbol();
929 const MCSectionELF *Sec = cast<MCSectionELF>(&Sym->getSection());
930 sh_link = SectionIndexMap.lookup(Sec);
931 }
Logan Chien4b724422013-02-05 14:18:59 +0000932
Rafael Espindola5960cee2015-05-22 23:58:30 +0000933 WriteSecHdrEntry(StrTabBuilder.getOffset(Section.getSectionName()),
Rafael Espindola28687582015-05-21 19:36:43 +0000934 Section.getType(), Section.getFlags(), 0, Offset, Size,
935 sh_link, sh_info, Section.getAlignment(),
936 Section.getEntrySize());
Rafael Espindola5a8d7812010-11-10 23:36:59 +0000937}
938
Peter Collingbournea29fe572018-05-21 19:18:28 +0000939void ELFWriter::writeSectionHeader(
Rafael Espindola57c80832015-06-04 20:55:49 +0000940 const MCAsmLayout &Layout, const SectionIndexMapTy &SectionIndexMap,
Rafael Espindolaa8201692015-04-28 15:26:21 +0000941 const SectionOffsetsTy &SectionOffsets) {
Rafael Espindolab1863912015-04-30 21:10:06 +0000942 const unsigned NumSections = SectionTable.size();
Rafael Espindolaa3e9a222010-11-11 18:13:52 +0000943
Matt Fleming6c1ad482010-08-16 18:57:57 +0000944 // Null section first.
Rafael Espindola3fe87a12010-10-31 00:16:26 +0000945 uint64_t FirstSectionSize =
Rafael Espindolabf0db6c2015-04-15 13:07:47 +0000946 (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0;
Rafael Espindola88d1f632015-04-29 20:25:24 +0000947 WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, 0, 0, 0, 0);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000948
Rafael Espindola08850b32015-05-25 21:56:55 +0000949 for (const MCSectionELF *Section : SectionTable) {
Rafael Espindolaa3e9a222010-11-11 18:13:52 +0000950 uint32_t GroupSymbolIndex;
Rafael Espindola03d7abb2015-04-30 20:53:27 +0000951 unsigned Type = Section->getType();
952 if (Type != ELF::SHT_GROUP)
Rafael Espindolaa3e9a222010-11-11 18:13:52 +0000953 GroupSymbolIndex = 0;
954 else
Rafael Espindola5e9ed902015-05-28 20:53:09 +0000955 GroupSymbolIndex = Section->getGroup()->getIndex();
Matt Fleming6c1ad482010-08-16 18:57:57 +0000956
Rafael Espindolabda19802015-04-30 14:21:49 +0000957 const std::pair<uint64_t, uint64_t> &Offsets =
Rafael Espindola03d7abb2015-04-30 20:53:27 +0000958 SectionOffsets.find(Section)->second;
Rafael Espindola1aa20fc2015-05-21 19:46:39 +0000959 uint64_t Size;
Rafael Espindola5a1e80b2015-05-26 02:00:36 +0000960 if (Type == ELF::SHT_NOBITS)
961 Size = Layout.getSectionAddressSize(Section);
962 else
Rafael Espindola1aa20fc2015-05-21 19:46:39 +0000963 Size = Offsets.second - Offsets.first;
Rafael Espindola60ebca92010-12-02 03:09:06 +0000964
Rafael Espindolae92c1bf2015-05-21 19:42:35 +0000965 writeSection(SectionIndexMap, GroupSymbolIndex, Offsets.first, Size,
Rafael Espindola28687582015-05-21 19:36:43 +0000966 *Section);
Matt Fleming6c1ad482010-08-16 18:57:57 +0000967 }
968}
969
Peter Collingbournea29fe572018-05-21 19:18:28 +0000970uint64_t ELFWriter::writeObject(MCAssembler &Asm, const MCAsmLayout &Layout) {
Peter Collingbourne438390f2018-05-21 18:23:50 +0000971 uint64_t StartOffset = W.OS.tell();
972
Rafael Espindolabda19802015-04-30 14:21:49 +0000973 MCContext &Ctx = Asm.getContext();
Rafael Espindola5960cee2015-05-22 23:58:30 +0000974 MCSectionELF *StrtabSection =
975 Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0);
976 StringTableIndex = addToSectionTable(StrtabSection);
Rafael Espindolabda19802015-04-30 14:21:49 +0000977
Rafael Espindola1557fd62011-03-20 18:44:20 +0000978 RevGroupMapTy RevGroupMap;
979 SectionIndexMapTy SectionIndexMap;
980
Rafael Espindolabda19802015-04-30 14:21:49 +0000981 std::map<const MCSymbol *, std::vector<const MCSectionELF *>> GroupMembers;
Rafael Espindola1557fd62011-03-20 18:44:20 +0000982
Rafael Espindola1557fd62011-03-20 18:44:20 +0000983 // Write out the ELF header ...
Rafael Espindola8c7829b2015-04-29 20:39:37 +0000984 writeHeader(Asm);
Rafael Espindola1557fd62011-03-20 18:44:20 +0000985
Rafael Espindola7230f802015-04-08 11:41:24 +0000986 // ... then the sections ...
Rafael Espindolabda19802015-04-30 14:21:49 +0000987 SectionOffsetsTy SectionOffsets;
Rafael Espindola0a82ad72015-05-21 20:43:13 +0000988 std::vector<MCSectionELF *> Groups;
989 std::vector<MCSectionELF *> Relocations;
Rafael Espindolae15b1b72015-05-27 13:30:50 +0000990 for (MCSection &Sec : Asm) {
991 MCSectionELF &Section = static_cast<MCSectionELF &>(Sec);
Rafael Espindolabda19802015-04-30 14:21:49 +0000992
Rafael Espindolab20fbb82015-06-05 18:21:00 +0000993 align(Section.getAlignment());
Rafael Espindola1557fd62011-03-20 18:44:20 +0000994
Rafael Espindola642a2212015-04-14 22:54:16 +0000995 // Remember the offset into the file for this section.
Peter Collingbournef17b1492018-05-21 18:17:42 +0000996 uint64_t SecStart = W.OS.tell();
Rafael Espindolab8cbb262015-04-30 00:30:40 +0000997
Rafael Espindola0ccf9b72015-06-02 21:30:13 +0000998 const MCSymbolELF *SignatureSymbol = Section.getGroup();
Rafael Espindolae15b1b72015-05-27 13:30:50 +0000999 writeSectionData(Asm, Section, Layout);
Rafael Espindolab8cbb262015-04-30 00:30:40 +00001000
Peter Collingbournef17b1492018-05-21 18:17:42 +00001001 uint64_t SecEnd = W.OS.tell();
Rafael Espindolabda19802015-04-30 14:21:49 +00001002 SectionOffsets[&Section] = std::make_pair(SecStart, SecEnd);
1003
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001004 MCSectionELF *RelSection = createRelocationSection(Ctx, Section);
Rafael Espindolabda19802015-04-30 14:21:49 +00001005
1006 if (SignatureSymbol) {
Rafael Espindolab5d316b2015-05-29 20:21:02 +00001007 Asm.registerSymbol(*SignatureSymbol);
Rafael Espindolabda19802015-04-30 14:21:49 +00001008 unsigned &GroupIdx = RevGroupMap[SignatureSymbol];
1009 if (!GroupIdx) {
Rafael Espindola0709a7b2015-05-21 19:20:38 +00001010 MCSectionELF *Group = Ctx.createELFGroupSection(SignatureSymbol);
Rafael Espindola03d7abb2015-04-30 20:53:27 +00001011 GroupIdx = addToSectionTable(Group);
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001012 Group->setAlignment(4);
1013 Groups.push_back(Group);
Rafael Espindolabda19802015-04-30 14:21:49 +00001014 }
Rafael Espindola7830fc82015-06-05 17:54:25 +00001015 std::vector<const MCSectionELF *> &Members =
1016 GroupMembers[SignatureSymbol];
1017 Members.push_back(&Section);
Rafael Espindolabda19802015-04-30 14:21:49 +00001018 if (RelSection)
Rafael Espindola7830fc82015-06-05 17:54:25 +00001019 Members.push_back(RelSection);
Rafael Espindolabda19802015-04-30 14:21:49 +00001020 }
1021
Rafael Espindola03d7abb2015-04-30 20:53:27 +00001022 SectionIndexMap[&Section] = addToSectionTable(&Section);
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001023 if (RelSection) {
Rafael Espindola03d7abb2015-04-30 20:53:27 +00001024 SectionIndexMap[RelSection] = addToSectionTable(RelSection);
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001025 Relocations.push_back(RelSection);
1026 }
Rafael Espindolabda19802015-04-30 14:21:49 +00001027 }
1028
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001029 for (MCSectionELF *Group : Groups) {
Rafael Espindolab20fbb82015-06-05 18:21:00 +00001030 align(Group->getAlignment());
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001031
1032 // Remember the offset into the file for this section.
Peter Collingbournef17b1492018-05-21 18:17:42 +00001033 uint64_t SecStart = W.OS.tell();
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001034
1035 const MCSymbol *SignatureSymbol = Group->getGroup();
1036 assert(SignatureSymbol);
1037 write(uint32_t(ELF::GRP_COMDAT));
1038 for (const MCSectionELF *Member : GroupMembers[SignatureSymbol]) {
1039 uint32_t SecIndex = SectionIndexMap.lookup(Member);
1040 write(SecIndex);
1041 }
1042
Peter Collingbournef17b1492018-05-21 18:17:42 +00001043 uint64_t SecEnd = W.OS.tell();
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001044 SectionOffsets[Group] = std::make_pair(SecStart, SecEnd);
1045 }
1046
1047 // Compute symbol table information.
Rafael Espindolaaa486e92015-05-28 17:54:01 +00001048 computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap, SectionOffsets);
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001049
1050 for (MCSectionELF *RelSection : Relocations) {
Rafael Espindolab20fbb82015-06-05 18:21:00 +00001051 align(RelSection->getAlignment());
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001052
1053 // Remember the offset into the file for this section.
Peter Collingbournef17b1492018-05-21 18:17:42 +00001054 uint64_t SecStart = W.OS.tell();
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001055
Evgeniy Stepanov43dcf4d2017-03-14 19:28:51 +00001056 writeRelocations(Asm,
1057 cast<MCSectionELF>(*RelSection->getAssociatedSection()));
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001058
Peter Collingbournef17b1492018-05-21 18:17:42 +00001059 uint64_t SecEnd = W.OS.tell();
Rafael Espindola0a82ad72015-05-21 20:43:13 +00001060 SectionOffsets[RelSection] = std::make_pair(SecStart, SecEnd);
Rafael Espindola642a2212015-04-14 22:54:16 +00001061 }
1062
Rafael Espindola88d1f632015-04-29 20:25:24 +00001063 {
Peter Collingbournef17b1492018-05-21 18:17:42 +00001064 uint64_t SecStart = W.OS.tell();
Rafael Espindolab1863912015-04-30 21:10:06 +00001065 const MCSectionELF *Sec = createStringTable(Ctx);
Peter Collingbournef17b1492018-05-21 18:17:42 +00001066 uint64_t SecEnd = W.OS.tell();
Rafael Espindolabda19802015-04-30 14:21:49 +00001067 SectionOffsets[Sec] = std::make_pair(SecStart, SecEnd);
Rafael Espindola88abc392015-04-29 20:34:31 +00001068 }
1069
Rafael Espindola642a2212015-04-14 22:54:16 +00001070 uint64_t NaturalAlignment = is64Bit() ? 8 : 4;
Rafael Espindolab20fbb82015-06-05 18:21:00 +00001071 align(NaturalAlignment);
Rafael Espindola1557fd62011-03-20 18:44:20 +00001072
Peter Collingbournef17b1492018-05-21 18:17:42 +00001073 const uint64_t SectionHeaderOffset = W.OS.tell();
Rafael Espindola642a2212015-04-14 22:54:16 +00001074
Rafael Espindola1557fd62011-03-20 18:44:20 +00001075 // ... then the section header table ...
Rafael Espindola57c80832015-06-04 20:55:49 +00001076 writeSectionHeader(Layout, SectionIndexMap, SectionOffsets);
Rafael Espindola642a2212015-04-14 22:54:16 +00001077
Peter Collingbournef17b1492018-05-21 18:17:42 +00001078 uint16_t NumSections = support::endian::byte_swap<uint16_t>(
1079 (SectionTable.size() + 1 >= ELF::SHN_LORESERVE) ? (uint16_t)ELF::SHN_UNDEF
1080 : SectionTable.size() + 1,
1081 W.Endian);
Rafael Espindola8c7829b2015-04-29 20:39:37 +00001082 unsigned NumSectionsOffset;
1083
Peter Collingbournef17b1492018-05-21 18:17:42 +00001084 auto &Stream = static_cast<raw_pwrite_stream &>(W.OS);
Rafael Espindola642a2212015-04-14 22:54:16 +00001085 if (is64Bit()) {
Peter Collingbournef17b1492018-05-21 18:17:42 +00001086 uint64_t Val =
1087 support::endian::byte_swap<uint64_t>(SectionHeaderOffset, W.Endian);
1088 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1089 offsetof(ELF::Elf64_Ehdr, e_shoff));
Rafael Espindola8c7829b2015-04-29 20:39:37 +00001090 NumSectionsOffset = offsetof(ELF::Elf64_Ehdr, e_shnum);
Rafael Espindola642a2212015-04-14 22:54:16 +00001091 } else {
Peter Collingbournef17b1492018-05-21 18:17:42 +00001092 uint32_t Val =
1093 support::endian::byte_swap<uint32_t>(SectionHeaderOffset, W.Endian);
1094 Stream.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val),
1095 offsetof(ELF::Elf32_Ehdr, e_shoff));
Rafael Espindola8c7829b2015-04-29 20:39:37 +00001096 NumSectionsOffset = offsetof(ELF::Elf32_Ehdr, e_shnum);
Rafael Espindola642a2212015-04-14 22:54:16 +00001097 }
Peter Collingbournef17b1492018-05-21 18:17:42 +00001098 Stream.pwrite(reinterpret_cast<char *>(&NumSections), sizeof(NumSections),
1099 NumSectionsOffset);
Peter Collingbourne438390f2018-05-21 18:23:50 +00001100
1101 return W.OS.tell() - StartOffset;
Rafael Espindola1557fd62011-03-20 18:44:20 +00001102}
1103
Peter Collingbournea29fe572018-05-21 19:18:28 +00001104bool ELFObjectWriter::hasRelocationAddend() const {
1105 return TargetObjectWriter->hasRelocationAddend();
1106}
1107
1108void ELFObjectWriter::executePostLayoutBinding(MCAssembler &Asm,
1109 const MCAsmLayout &Layout) {
1110 // The presence of symbol versions causes undefined symbols and
1111 // versions declared with @@@ to be renamed.
1112 for (const std::pair<StringRef, const MCSymbol *> &P : Asm.Symvers) {
1113 StringRef AliasName = P.first;
1114 const auto &Symbol = cast<MCSymbolELF>(*P.second);
1115 size_t Pos = AliasName.find('@');
1116 assert(Pos != StringRef::npos);
1117
1118 StringRef Prefix = AliasName.substr(0, Pos);
1119 StringRef Rest = AliasName.substr(Pos);
1120 StringRef Tail = Rest;
1121 if (Rest.startswith("@@@"))
1122 Tail = Rest.substr(Symbol.isUndefined() ? 2 : 1);
1123
1124 auto *Alias =
1125 cast<MCSymbolELF>(Asm.getContext().getOrCreateSymbol(Prefix + Tail));
1126 Asm.registerSymbol(*Alias);
1127 const MCExpr *Value = MCSymbolRefExpr::create(&Symbol, Asm.getContext());
1128 Alias->setVariableValue(Value);
1129
1130 // Aliases defined with .symvar copy the binding from the symbol they alias.
1131 // This is the first place we are able to copy this information.
1132 Alias->setExternal(Symbol.isExternal());
1133 Alias->setBinding(Symbol.getBinding());
1134
1135 if (!Symbol.isUndefined() && !Rest.startswith("@@@"))
1136 continue;
1137
1138 // FIXME: produce a better error message.
1139 if (Symbol.isUndefined() && Rest.startswith("@@") &&
1140 !Rest.startswith("@@@"))
1141 report_fatal_error("A @@ version cannot be undefined");
1142
1143 if (Renames.count(&Symbol) && Renames[&Symbol] != Alias)
1144 report_fatal_error(llvm::Twine("Multiple symbol versions defined for ") +
1145 Symbol.getName());
1146
1147 Renames.insert(std::make_pair(&Symbol, Alias));
1148 }
1149}
1150
1151// It is always valid to create a relocation with a symbol. It is preferable
1152// to use a relocation with a section if that is possible. Using the section
1153// allows us to omit some local symbols from the symbol table.
1154bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm,
1155 const MCSymbolRefExpr *RefA,
1156 const MCSymbolELF *Sym,
1157 uint64_t C,
1158 unsigned Type) const {
1159 // A PCRel relocation to an absolute value has no symbol (or section). We
1160 // represent that with a relocation to a null section.
1161 if (!RefA)
1162 return false;
1163
1164 MCSymbolRefExpr::VariantKind Kind = RefA->getKind();
1165 switch (Kind) {
1166 default:
1167 break;
1168 // The .odp creation emits a relocation against the symbol ".TOC." which
1169 // create a R_PPC64_TOC relocation. However the relocation symbol name
1170 // in final object creation should be NULL, since the symbol does not
1171 // really exist, it is just the reference to TOC base for the current
1172 // object file. Since the symbol is undefined, returning false results
1173 // in a relocation with a null section which is the desired result.
1174 case MCSymbolRefExpr::VK_PPC_TOCBASE:
1175 return false;
1176
1177 // These VariantKind cause the relocation to refer to something other than
1178 // the symbol itself, like a linker generated table. Since the address of
1179 // symbol is not relevant, we cannot replace the symbol with the
1180 // section and patch the difference in the addend.
1181 case MCSymbolRefExpr::VK_GOT:
1182 case MCSymbolRefExpr::VK_PLT:
1183 case MCSymbolRefExpr::VK_GOTPCREL:
1184 case MCSymbolRefExpr::VK_PPC_GOT_LO:
1185 case MCSymbolRefExpr::VK_PPC_GOT_HI:
1186 case MCSymbolRefExpr::VK_PPC_GOT_HA:
1187 return true;
1188 }
1189
1190 // An undefined symbol is not in any section, so the relocation has to point
1191 // to the symbol itself.
1192 assert(Sym && "Expected a symbol");
1193 if (Sym->isUndefined())
1194 return true;
1195
1196 unsigned Binding = Sym->getBinding();
1197 switch(Binding) {
1198 default:
1199 llvm_unreachable("Invalid Binding");
1200 case ELF::STB_LOCAL:
1201 break;
1202 case ELF::STB_WEAK:
1203 // If the symbol is weak, it might be overridden by a symbol in another
1204 // file. The relocation has to point to the symbol so that the linker
1205 // can update it.
1206 return true;
1207 case ELF::STB_GLOBAL:
1208 // Global ELF symbols can be preempted by the dynamic linker. The relocation
1209 // has to point to the symbol for a reason analogous to the STB_WEAK case.
1210 return true;
1211 }
1212
1213 // If a relocation points to a mergeable section, we have to be careful.
1214 // If the offset is zero, a relocation with the section will encode the
1215 // same information. With a non-zero offset, the situation is different.
1216 // For example, a relocation can point 42 bytes past the end of a string.
1217 // If we change such a relocation to use the section, the linker would think
1218 // that it pointed to another string and subtracting 42 at runtime will
1219 // produce the wrong value.
1220 if (Sym->isInSection()) {
1221 auto &Sec = cast<MCSectionELF>(Sym->getSection());
1222 unsigned Flags = Sec.getFlags();
1223 if (Flags & ELF::SHF_MERGE) {
1224 if (C != 0)
1225 return true;
1226
1227 // It looks like gold has a bug (http://sourceware.org/PR16794) and can
1228 // only handle section relocations to mergeable sections if using RELA.
1229 if (!hasRelocationAddend())
1230 return true;
1231 }
1232
1233 // Most TLS relocations use a got, so they need the symbol. Even those that
1234 // are just an offset (@tpoff), require a symbol in gold versions before
1235 // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed
1236 // http://sourceware.org/PR16773.
1237 if (Flags & ELF::SHF_TLS)
1238 return true;
1239 }
1240
1241 // If the symbol is a thumb function the final relocation must set the lowest
1242 // bit. With a symbol that is done by just having the symbol have that bit
1243 // set, so we would lose the bit if we relocated with the section.
1244 // FIXME: We could use the section but add the bit to the relocation value.
1245 if (Asm.isThumbFunc(Sym))
1246 return true;
1247
1248 if (TargetObjectWriter->needsRelocateWithSymbol(*Sym, Type))
1249 return true;
1250 return false;
1251}
1252
1253void ELFObjectWriter::recordRelocation(MCAssembler &Asm,
1254 const MCAsmLayout &Layout,
1255 const MCFragment *Fragment,
1256 const MCFixup &Fixup, MCValue Target,
1257 uint64_t &FixedValue) {
1258 MCAsmBackend &Backend = Asm.getBackend();
1259 bool IsPCRel = Backend.getFixupKindInfo(Fixup.getKind()).Flags &
1260 MCFixupKindInfo::FKF_IsPCRel;
1261 const MCSectionELF &FixupSection = cast<MCSectionELF>(*Fragment->getParent());
1262 uint64_t C = Target.getConstant();
1263 uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset();
1264 MCContext &Ctx = Asm.getContext();
1265
1266 if (const MCSymbolRefExpr *RefB = Target.getSymB()) {
1267 // Let A, B and C being the components of Target and R be the location of
1268 // the fixup. If the fixup is not pcrel, we want to compute (A - B + C).
1269 // If it is pcrel, we want to compute (A - B + C - R).
1270
1271 // In general, ELF has no relocations for -B. It can only represent (A + C)
1272 // or (A + C - R). If B = R + K and the relocation is not pcrel, we can
1273 // replace B to implement it: (A - R - K + C)
1274 if (IsPCRel) {
1275 Ctx.reportError(
1276 Fixup.getLoc(),
1277 "No relocation available to represent this relative expression");
1278 return;
1279 }
1280
1281 const auto &SymB = cast<MCSymbolELF>(RefB->getSymbol());
1282
1283 if (SymB.isUndefined()) {
1284 Ctx.reportError(Fixup.getLoc(),
1285 Twine("symbol '") + SymB.getName() +
1286 "' can not be undefined in a subtraction expression");
1287 return;
1288 }
1289
1290 assert(!SymB.isAbsolute() && "Should have been folded");
1291 const MCSection &SecB = SymB.getSection();
1292 if (&SecB != &FixupSection) {
1293 Ctx.reportError(Fixup.getLoc(),
1294 "Cannot represent a difference across sections");
1295 return;
1296 }
1297
1298 uint64_t SymBOffset = Layout.getSymbolOffset(SymB);
1299 uint64_t K = SymBOffset - FixupOffset;
1300 IsPCRel = true;
1301 C -= K;
1302 }
1303
1304 // We either rejected the fixup or folded B into C at this point.
1305 const MCSymbolRefExpr *RefA = Target.getSymA();
1306 const auto *SymA = RefA ? cast<MCSymbolELF>(&RefA->getSymbol()) : nullptr;
1307
1308 bool ViaWeakRef = false;
1309 if (SymA && SymA->isVariable()) {
1310 const MCExpr *Expr = SymA->getVariableValue();
1311 if (const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr)) {
1312 if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) {
1313 SymA = cast<MCSymbolELF>(&Inner->getSymbol());
1314 ViaWeakRef = true;
1315 }
1316 }
1317 }
1318
1319 unsigned Type = TargetObjectWriter->getRelocType(Ctx, Target, Fixup, IsPCRel);
1320 uint64_t OriginalC = C;
1321 bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymA, C, Type);
1322 if (!RelocateWithSymbol && SymA && !SymA->isUndefined())
1323 C += Layout.getSymbolOffset(*SymA);
1324
1325 uint64_t Addend = 0;
1326 if (hasRelocationAddend()) {
1327 Addend = C;
1328 C = 0;
1329 }
1330
1331 FixedValue = C;
1332
1333 if (!RelocateWithSymbol) {
1334 const MCSection *SecA =
1335 (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr;
1336 const auto *SectionSymbol =
1337 SecA ? cast<MCSymbolELF>(SecA->getBeginSymbol()) : nullptr;
1338 if (SectionSymbol)
1339 SectionSymbol->setUsedInReloc();
1340 ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend, SymA,
1341 OriginalC);
1342 Relocations[&FixupSection].push_back(Rec);
1343 return;
1344 }
1345
1346 const auto *RenamedSymA = SymA;
1347 if (SymA) {
1348 if (const MCSymbolELF *R = Renames.lookup(SymA))
1349 RenamedSymA = R;
1350
1351 if (ViaWeakRef)
1352 RenamedSymA->setIsWeakrefUsedInReloc();
1353 else
1354 RenamedSymA->setUsedInReloc();
1355 }
1356 ELFRelocationEntry Rec(FixupOffset, RenamedSymA, Type, Addend, SymA,
1357 OriginalC);
1358 Relocations[&FixupSection].push_back(Rec);
1359}
1360
Jim Grosbach36e60e92015-06-04 22:24:41 +00001361bool ELFObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(
Rafael Espindola95fb9b92015-06-02 20:38:46 +00001362 const MCAssembler &Asm, const MCSymbol &SA, const MCFragment &FB,
Rafael Espindola35d61892015-04-17 21:15:17 +00001363 bool InSet, bool IsPCRel) const {
Rafael Espindola95fb9b92015-06-02 20:38:46 +00001364 const auto &SymA = cast<MCSymbolELF>(SA);
Rafael Espindola35d61892015-04-17 21:15:17 +00001365 if (IsPCRel) {
1366 assert(!InSet);
Peter Collingbourne36003052017-04-08 23:35:49 +00001367 if (isWeak(SymA))
Rafael Espindola35d61892015-04-17 21:15:17 +00001368 return false;
1369 }
Jim Grosbach36e60e92015-06-04 22:24:41 +00001370 return MCObjectWriter::isSymbolRefDifferenceFullyResolvedImpl(Asm, SymA, FB,
Rafael Espindola35d61892015-04-17 21:15:17 +00001371 InSet, IsPCRel);
Eli Friedmand92d17b2011-03-03 07:24:36 +00001372}
1373
Lang Hames60fbc7c2017-10-10 16:28:07 +00001374std::unique_ptr<MCObjectWriter>
Lang Hamesdcb312b2017-10-09 23:53:15 +00001375llvm::createELFObjectWriter(std::unique_ptr<MCELFObjectTargetWriter> MOTW,
1376 raw_pwrite_stream &OS, bool IsLittleEndian) {
Lang Hames60fbc7c2017-10-10 16:28:07 +00001377 return llvm::make_unique<ELFObjectWriter>(std::move(MOTW), OS,
1378 IsLittleEndian);
Rafael Espindolab264d332011-12-21 17:30:17 +00001379}