Coverage Report

Created: 2017-10-03 07:32

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