File: | lib/MC/ELFObjectWriter.cpp |
Location: | line 1304, column 74 |
Description: | Potential leak of memory pointed to by 'F' |
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/MC/MCELFObjectWriter.h" | |||
15 | #include "llvm/ADT/STLExtras.h" | |||
16 | #include "llvm/ADT/SmallPtrSet.h" | |||
17 | #include "llvm/ADT/SmallString.h" | |||
18 | #include "llvm/ADT/StringMap.h" | |||
19 | #include "llvm/MC/MCAsmBackend.h" | |||
20 | #include "llvm/MC/MCAsmInfo.h" | |||
21 | #include "llvm/MC/MCAsmLayout.h" | |||
22 | #include "llvm/MC/MCAssembler.h" | |||
23 | #include "llvm/MC/MCContext.h" | |||
24 | #include "llvm/MC/MCELF.h" | |||
25 | #include "llvm/MC/MCELFSymbolFlags.h" | |||
26 | #include "llvm/MC/MCExpr.h" | |||
27 | #include "llvm/MC/MCFixupKindInfo.h" | |||
28 | #include "llvm/MC/MCObjectWriter.h" | |||
29 | #include "llvm/MC/MCSectionELF.h" | |||
30 | #include "llvm/MC/MCValue.h" | |||
31 | #include "llvm/MC/StringTableBuilder.h" | |||
32 | #include "llvm/Support/Compression.h" | |||
33 | #include "llvm/Support/Debug.h" | |||
34 | #include "llvm/Support/ELF.h" | |||
35 | #include "llvm/Support/Endian.h" | |||
36 | #include "llvm/Support/ErrorHandling.h" | |||
37 | #include <vector> | |||
38 | using namespace llvm; | |||
39 | ||||
40 | #undef DEBUG_TYPE"reloc-info" | |||
41 | #define DEBUG_TYPE"reloc-info" "reloc-info" | |||
42 | ||||
43 | namespace { | |||
44 | class FragmentWriter { | |||
45 | bool IsLittleEndian; | |||
46 | ||||
47 | public: | |||
48 | FragmentWriter(bool IsLittleEndian); | |||
49 | template <typename T> void write(MCDataFragment &F, T Val); | |||
50 | }; | |||
51 | ||||
52 | typedef DenseMap<const MCSectionELF *, uint32_t> SectionIndexMapTy; | |||
53 | ||||
54 | class SymbolTableWriter { | |||
55 | MCAssembler &Asm; | |||
56 | FragmentWriter &FWriter; | |||
57 | bool Is64Bit; | |||
58 | SectionIndexMapTy &SectionIndexMap; | |||
59 | ||||
60 | // The symbol .symtab fragment we are writting to. | |||
61 | MCDataFragment *SymtabF; | |||
62 | ||||
63 | // .symtab_shndx fragment we are writting to. | |||
64 | MCDataFragment *ShndxF; | |||
65 | ||||
66 | // The numbel of symbols written so far. | |||
67 | unsigned NumWritten; | |||
68 | ||||
69 | void createSymtabShndx(); | |||
70 | ||||
71 | template <typename T> void write(MCDataFragment &F, T Value); | |||
72 | ||||
73 | public: | |||
74 | SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, bool Is64Bit, | |||
75 | SectionIndexMapTy &SectionIndexMap, | |||
76 | MCDataFragment *SymtabF); | |||
77 | ||||
78 | void writeSymbol(uint32_t name, uint8_t info, uint64_t value, uint64_t size, | |||
79 | uint8_t other, uint32_t shndx, bool Reserved); | |||
80 | }; | |||
81 | ||||
82 | class ELFObjectWriter : public MCObjectWriter { | |||
83 | FragmentWriter FWriter; | |||
84 | ||||
85 | protected: | |||
86 | ||||
87 | static bool isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind); | |||
88 | static bool RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant); | |||
89 | static uint64_t SymbolValue(MCSymbolData &Data, const MCAsmLayout &Layout); | |||
90 | static bool isInSymtab(const MCAsmLayout &Layout, const MCSymbolData &Data, | |||
91 | bool Used, bool Renamed); | |||
92 | static bool isLocal(const MCSymbolData &Data, bool isUsedInReloc); | |||
93 | static bool IsELFMetaDataSection(const MCSectionData &SD); | |||
94 | static uint64_t DataSectionSize(const MCSectionData &SD); | |||
95 | static uint64_t GetSectionAddressSize(const MCAsmLayout &Layout, | |||
96 | const MCSectionData &SD); | |||
97 | ||||
98 | void writeDataSectionData(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
99 | const MCSectionData &SD); | |||
100 | ||||
101 | /// Helper struct for containing some precomputed information on symbols. | |||
102 | struct ELFSymbolData { | |||
103 | MCSymbolData *SymbolData; | |||
104 | uint64_t StringIndex; | |||
105 | uint32_t SectionIndex; | |||
106 | StringRef Name; | |||
107 | ||||
108 | // Support lexicographic sorting. | |||
109 | bool operator<(const ELFSymbolData &RHS) const { | |||
110 | unsigned LHSType = MCELF::GetType(*SymbolData); | |||
111 | unsigned RHSType = MCELF::GetType(*RHS.SymbolData); | |||
112 | if (LHSType == ELF::STT_SECTION && RHSType != ELF::STT_SECTION) | |||
113 | return false; | |||
114 | if (LHSType != ELF::STT_SECTION && RHSType == ELF::STT_SECTION) | |||
115 | return true; | |||
116 | if (LHSType == ELF::STT_SECTION && RHSType == ELF::STT_SECTION) | |||
117 | return SectionIndex < RHS.SectionIndex; | |||
118 | return Name < RHS.Name; | |||
119 | } | |||
120 | }; | |||
121 | ||||
122 | /// The target specific ELF writer instance. | |||
123 | std::unique_ptr<MCELFObjectTargetWriter> TargetObjectWriter; | |||
124 | ||||
125 | SmallPtrSet<const MCSymbol *, 16> UsedInReloc; | |||
126 | SmallPtrSet<const MCSymbol *, 16> WeakrefUsedInReloc; | |||
127 | DenseMap<const MCSymbol *, const MCSymbol *> Renames; | |||
128 | ||||
129 | llvm::DenseMap<const MCSectionData *, std::vector<ELFRelocationEntry>> | |||
130 | Relocations; | |||
131 | StringTableBuilder ShStrTabBuilder; | |||
132 | ||||
133 | /// @} | |||
134 | /// @name Symbol Table Data | |||
135 | /// @{ | |||
136 | ||||
137 | StringTableBuilder StrTabBuilder; | |||
138 | std::vector<uint64_t> FileSymbolData; | |||
139 | std::vector<ELFSymbolData> LocalSymbolData; | |||
140 | std::vector<ELFSymbolData> ExternalSymbolData; | |||
141 | std::vector<ELFSymbolData> UndefinedSymbolData; | |||
142 | ||||
143 | /// @} | |||
144 | ||||
145 | bool NeedsGOT; | |||
146 | ||||
147 | // This holds the symbol table index of the last local symbol. | |||
148 | unsigned LastLocalSymbolIndex; | |||
149 | // This holds the .strtab section index. | |||
150 | unsigned StringTableIndex; | |||
151 | // This holds the .symtab section index. | |||
152 | unsigned SymbolTableIndex; | |||
153 | ||||
154 | unsigned ShstrtabIndex; | |||
155 | ||||
156 | ||||
157 | // TargetObjectWriter wrappers. | |||
158 | bool is64Bit() const { return TargetObjectWriter->is64Bit(); } | |||
159 | bool hasRelocationAddend() const { | |||
160 | return TargetObjectWriter->hasRelocationAddend(); | |||
161 | } | |||
162 | unsigned GetRelocType(const MCValue &Target, const MCFixup &Fixup, | |||
163 | bool IsPCRel) const { | |||
164 | return TargetObjectWriter->GetRelocType(Target, Fixup, IsPCRel); | |||
165 | } | |||
166 | ||||
167 | public: | |||
168 | ELFObjectWriter(MCELFObjectTargetWriter *MOTW, raw_pwrite_stream &OS, | |||
169 | bool IsLittleEndian) | |||
170 | : MCObjectWriter(OS, IsLittleEndian), FWriter(IsLittleEndian), | |||
171 | TargetObjectWriter(MOTW), NeedsGOT(false) {} | |||
172 | ||||
173 | void reset() override { | |||
174 | UsedInReloc.clear(); | |||
175 | WeakrefUsedInReloc.clear(); | |||
176 | Renames.clear(); | |||
177 | Relocations.clear(); | |||
178 | ShStrTabBuilder.clear(); | |||
179 | StrTabBuilder.clear(); | |||
180 | FileSymbolData.clear(); | |||
181 | LocalSymbolData.clear(); | |||
182 | ExternalSymbolData.clear(); | |||
183 | UndefinedSymbolData.clear(); | |||
184 | MCObjectWriter::reset(); | |||
185 | } | |||
186 | ||||
187 | ~ELFObjectWriter() override; | |||
188 | ||||
189 | void WriteWord(uint64_t W) { | |||
190 | if (is64Bit()) | |||
191 | Write64(W); | |||
192 | else | |||
193 | Write32(W); | |||
194 | } | |||
195 | ||||
196 | template <typename T> void write(MCDataFragment &F, T Value) { | |||
197 | FWriter.write(F, Value); | |||
198 | } | |||
199 | ||||
200 | void WriteHeader(const MCAssembler &Asm, | |||
201 | unsigned NumberOfSections); | |||
202 | ||||
203 | void WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, | |||
204 | const MCAsmLayout &Layout); | |||
205 | ||||
206 | void WriteSymbolTable(MCDataFragment *SymtabF, MCAssembler &Asm, | |||
207 | const MCAsmLayout &Layout, | |||
208 | SectionIndexMapTy &SectionIndexMap); | |||
209 | ||||
210 | bool shouldRelocateWithSymbol(const MCAssembler &Asm, | |||
211 | const MCSymbolRefExpr *RefA, | |||
212 | const MCSymbolData *SD, uint64_t C, | |||
213 | unsigned Type) const; | |||
214 | ||||
215 | void RecordRelocation(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
216 | const MCFragment *Fragment, const MCFixup &Fixup, | |||
217 | MCValue Target, bool &IsPCRel, | |||
218 | uint64_t &FixedValue) override; | |||
219 | ||||
220 | uint64_t getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |||
221 | const MCSymbol *S); | |||
222 | ||||
223 | // Map from a group section to the signature symbol | |||
224 | typedef DenseMap<const MCSectionELF*, const MCSymbol*> GroupMapTy; | |||
225 | // Map from a signature symbol to the group section | |||
226 | typedef DenseMap<const MCSymbol*, const MCSectionELF*> RevGroupMapTy; | |||
227 | // Map from a section to its offset | |||
228 | typedef DenseMap<const MCSectionELF*, uint64_t> SectionOffsetMapTy; | |||
229 | ||||
230 | /// Compute the symbol table data | |||
231 | /// | |||
232 | /// \param Asm - The assembler. | |||
233 | /// \param SectionIndexMap - Maps a section to its index. | |||
234 | /// \param RevGroupMap - Maps a signature symbol to the group section. | |||
235 | void computeSymbolTable(MCAssembler &Asm, const MCAsmLayout &Layout, | |||
236 | const SectionIndexMapTy &SectionIndexMap, | |||
237 | const RevGroupMapTy &RevGroupMap); | |||
238 | ||||
239 | void computeIndexMap(MCAssembler &Asm, SectionIndexMapTy &SectionIndexMap); | |||
240 | ||||
241 | MCSectionData *createRelocationSection(MCAssembler &Asm, | |||
242 | const MCSectionData &SD); | |||
243 | ||||
244 | void CompressDebugSections(MCAssembler &Asm, MCAsmLayout &Layout); | |||
245 | ||||
246 | void WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout); | |||
247 | ||||
248 | void CreateMetadataSections(MCAssembler &Asm, MCAsmLayout &Layout, | |||
249 | SectionIndexMapTy &SectionIndexMap); | |||
250 | ||||
251 | // Create the sections that show up in the symbol table. Currently | |||
252 | // those are the .note.GNU-stack section and the group sections. | |||
253 | void createIndexedSections(MCAssembler &Asm, MCAsmLayout &Layout, | |||
254 | GroupMapTy &GroupMap, RevGroupMapTy &RevGroupMap, | |||
255 | SectionIndexMapTy &SectionIndexMap); | |||
256 | ||||
257 | void ExecutePostLayoutBinding(MCAssembler &Asm, | |||
258 | const MCAsmLayout &Layout) override; | |||
259 | ||||
260 | void writeSectionHeader(ArrayRef<const MCSectionELF *> Sections, | |||
261 | MCAssembler &Asm, const GroupMapTy &GroupMap, | |||
262 | const MCAsmLayout &Layout, | |||
263 | const SectionIndexMapTy &SectionIndexMap, | |||
264 | const SectionOffsetMapTy &SectionOffsetMap); | |||
265 | ||||
266 | void WriteSecHdrEntry(uint32_t Name, uint32_t Type, uint64_t Flags, | |||
267 | uint64_t Address, uint64_t Offset, | |||
268 | uint64_t Size, uint32_t Link, uint32_t Info, | |||
269 | uint64_t Alignment, uint64_t EntrySize); | |||
270 | ||||
271 | void WriteRelocationsFragment(const MCAssembler &Asm, | |||
272 | MCDataFragment *F, | |||
273 | const MCSectionData *SD); | |||
274 | ||||
275 | bool | |||
276 | IsSymbolRefDifferenceFullyResolvedImpl(const MCAssembler &Asm, | |||
277 | const MCSymbolData &DataA, | |||
278 | const MCFragment &FB, | |||
279 | bool InSet, | |||
280 | bool IsPCRel) const override; | |||
281 | ||||
282 | bool isWeak(const MCSymbolData &SD) const override; | |||
283 | ||||
284 | void WriteObject(MCAssembler &Asm, const MCAsmLayout &Layout) override; | |||
285 | void writeSection(MCAssembler &Asm, | |||
286 | const SectionIndexMapTy &SectionIndexMap, | |||
287 | uint32_t GroupSymbolIndex, | |||
288 | uint64_t Offset, uint64_t Size, uint64_t Alignment, | |||
289 | const MCSectionELF &Section); | |||
290 | }; | |||
291 | } | |||
292 | ||||
293 | FragmentWriter::FragmentWriter(bool IsLittleEndian) | |||
294 | : IsLittleEndian(IsLittleEndian) {} | |||
295 | ||||
296 | template <typename T> void FragmentWriter::write(MCDataFragment &F, T Val) { | |||
297 | if (IsLittleEndian) | |||
298 | Val = support::endian::byte_swap<T, support::little>(Val); | |||
299 | else | |||
300 | Val = support::endian::byte_swap<T, support::big>(Val); | |||
301 | const char *Start = (const char *)&Val; | |||
302 | F.getContents().append(Start, Start + sizeof(T)); | |||
303 | } | |||
304 | ||||
305 | void SymbolTableWriter::createSymtabShndx() { | |||
306 | if (ShndxF) | |||
307 | return; | |||
308 | ||||
309 | MCContext &Ctx = Asm.getContext(); | |||
310 | const MCSectionELF *SymtabShndxSection = | |||
311 | Ctx.getELFSection(".symtab_shndxr", ELF::SHT_SYMTAB_SHNDX, 0, 4, ""); | |||
312 | MCSectionData *SymtabShndxSD = | |||
313 | &Asm.getOrCreateSectionData(*SymtabShndxSection); | |||
314 | SymtabShndxSD->setAlignment(4); | |||
315 | ShndxF = new MCDataFragment(SymtabShndxSD); | |||
316 | unsigned Index = SectionIndexMap.size() + 1; | |||
317 | SectionIndexMap[SymtabShndxSection] = Index; | |||
318 | ||||
319 | for (unsigned I = 0; I < NumWritten; ++I) | |||
320 | write(*ShndxF, uint32_t(0)); | |||
321 | } | |||
322 | ||||
323 | template <typename T> | |||
324 | void SymbolTableWriter::write(MCDataFragment &F, T Value) { | |||
325 | FWriter.write(F, Value); | |||
326 | } | |||
327 | ||||
328 | SymbolTableWriter::SymbolTableWriter(MCAssembler &Asm, FragmentWriter &FWriter, | |||
329 | bool Is64Bit, | |||
330 | SectionIndexMapTy &SectionIndexMap, | |||
331 | MCDataFragment *SymtabF) | |||
332 | : Asm(Asm), FWriter(FWriter), Is64Bit(Is64Bit), | |||
333 | SectionIndexMap(SectionIndexMap), SymtabF(SymtabF), ShndxF(nullptr), | |||
334 | NumWritten(0) {} | |||
335 | ||||
336 | void SymbolTableWriter::writeSymbol(uint32_t name, uint8_t info, uint64_t value, | |||
337 | uint64_t size, uint8_t other, | |||
338 | uint32_t shndx, bool Reserved) { | |||
339 | bool LargeIndex = shndx >= ELF::SHN_LORESERVE && !Reserved; | |||
340 | ||||
341 | if (LargeIndex) | |||
342 | createSymtabShndx(); | |||
343 | ||||
344 | if (ShndxF) { | |||
345 | if (LargeIndex) | |||
346 | write(*ShndxF, shndx); | |||
347 | else | |||
348 | write(*ShndxF, uint32_t(0)); | |||
349 | } | |||
350 | ||||
351 | uint16_t Index = LargeIndex ? uint16_t(ELF::SHN_XINDEX) : shndx; | |||
352 | ||||
353 | if (Is64Bit) { | |||
354 | write(*SymtabF, name); // st_name | |||
355 | write(*SymtabF, info); // st_info | |||
356 | write(*SymtabF, other); // st_other | |||
357 | write(*SymtabF, Index); // st_shndx | |||
358 | write(*SymtabF, value); // st_value | |||
359 | write(*SymtabF, size); // st_size | |||
360 | } else { | |||
361 | write(*SymtabF, name); // st_name | |||
362 | write(*SymtabF, uint32_t(value)); // st_value | |||
363 | write(*SymtabF, uint32_t(size)); // st_size | |||
364 | write(*SymtabF, info); // st_info | |||
365 | write(*SymtabF, other); // st_other | |||
366 | write(*SymtabF, Index); // st_shndx | |||
367 | } | |||
368 | ||||
369 | ++NumWritten; | |||
370 | } | |||
371 | ||||
372 | bool ELFObjectWriter::isFixupKindPCRel(const MCAssembler &Asm, unsigned Kind) { | |||
373 | const MCFixupKindInfo &FKI = | |||
374 | Asm.getBackend().getFixupKindInfo((MCFixupKind) Kind); | |||
375 | ||||
376 | return FKI.Flags & MCFixupKindInfo::FKF_IsPCRel; | |||
377 | } | |||
378 | ||||
379 | bool ELFObjectWriter::RelocNeedsGOT(MCSymbolRefExpr::VariantKind Variant) { | |||
380 | switch (Variant) { | |||
381 | default: | |||
382 | return false; | |||
383 | case MCSymbolRefExpr::VK_GOT: | |||
384 | case MCSymbolRefExpr::VK_PLT: | |||
385 | case MCSymbolRefExpr::VK_GOTPCREL: | |||
386 | case MCSymbolRefExpr::VK_GOTOFF: | |||
387 | case MCSymbolRefExpr::VK_TPOFF: | |||
388 | case MCSymbolRefExpr::VK_TLSGD: | |||
389 | case MCSymbolRefExpr::VK_GOTTPOFF: | |||
390 | case MCSymbolRefExpr::VK_INDNTPOFF: | |||
391 | case MCSymbolRefExpr::VK_NTPOFF: | |||
392 | case MCSymbolRefExpr::VK_GOTNTPOFF: | |||
393 | case MCSymbolRefExpr::VK_TLSLDM: | |||
394 | case MCSymbolRefExpr::VK_DTPOFF: | |||
395 | case MCSymbolRefExpr::VK_TLSLD: | |||
396 | return true; | |||
397 | } | |||
398 | } | |||
399 | ||||
400 | ELFObjectWriter::~ELFObjectWriter() | |||
401 | {} | |||
402 | ||||
403 | // Emit the ELF header. | |||
404 | void ELFObjectWriter::WriteHeader(const MCAssembler &Asm, | |||
405 | unsigned NumberOfSections) { | |||
406 | // ELF Header | |||
407 | // ---------- | |||
408 | // | |||
409 | // Note | |||
410 | // ---- | |||
411 | // emitWord method behaves differently for ELF32 and ELF64, writing | |||
412 | // 4 bytes in the former and 8 in the latter. | |||
413 | ||||
414 | WriteBytes(ELF::ElfMagic); // e_ident[EI_MAG0] to e_ident[EI_MAG3] | |||
415 | ||||
416 | Write8(is64Bit() ? ELF::ELFCLASS64 : ELF::ELFCLASS32); // e_ident[EI_CLASS] | |||
417 | ||||
418 | // e_ident[EI_DATA] | |||
419 | Write8(isLittleEndian() ? ELF::ELFDATA2LSB : ELF::ELFDATA2MSB); | |||
420 | ||||
421 | Write8(ELF::EV_CURRENT); // e_ident[EI_VERSION] | |||
422 | // e_ident[EI_OSABI] | |||
423 | Write8(TargetObjectWriter->getOSABI()); | |||
424 | Write8(0); // e_ident[EI_ABIVERSION] | |||
425 | ||||
426 | WriteZeros(ELF::EI_NIDENT - ELF::EI_PAD); | |||
427 | ||||
428 | Write16(ELF::ET_REL); // e_type | |||
429 | ||||
430 | Write16(TargetObjectWriter->getEMachine()); // e_machine = target | |||
431 | ||||
432 | Write32(ELF::EV_CURRENT); // e_version | |||
433 | WriteWord(0); // e_entry, no entry point in .o file | |||
434 | WriteWord(0); // e_phoff, no program header for .o | |||
435 | WriteWord(0); // e_shoff = sec hdr table off in bytes | |||
436 | ||||
437 | // e_flags = whatever the target wants | |||
438 | Write32(Asm.getELFHeaderEFlags()); | |||
439 | ||||
440 | // e_ehsize = ELF header size | |||
441 | Write16(is64Bit() ? sizeof(ELF::Elf64_Ehdr) : sizeof(ELF::Elf32_Ehdr)); | |||
442 | ||||
443 | Write16(0); // e_phentsize = prog header entry size | |||
444 | Write16(0); // e_phnum = # prog header entries = 0 | |||
445 | ||||
446 | // e_shentsize = Section header entry size | |||
447 | Write16(is64Bit() ? sizeof(ELF::Elf64_Shdr) : sizeof(ELF::Elf32_Shdr)); | |||
448 | ||||
449 | // e_shnum = # of section header ents | |||
450 | if (NumberOfSections >= ELF::SHN_LORESERVE) | |||
451 | Write16(ELF::SHN_UNDEF); | |||
452 | else | |||
453 | Write16(NumberOfSections); | |||
454 | ||||
455 | // e_shstrndx = Section # of '.shstrtab' | |||
456 | if (ShstrtabIndex >= ELF::SHN_LORESERVE) | |||
457 | Write16(ELF::SHN_XINDEX); | |||
458 | else | |||
459 | Write16(ShstrtabIndex); | |||
460 | } | |||
461 | ||||
462 | uint64_t ELFObjectWriter::SymbolValue(MCSymbolData &Data, | |||
463 | const MCAsmLayout &Layout) { | |||
464 | if (Data.isCommon() && Data.isExternal()) | |||
465 | return Data.getCommonAlignment(); | |||
466 | ||||
467 | uint64_t Res; | |||
468 | if (!Layout.getSymbolOffset(&Data, Res)) | |||
469 | return 0; | |||
470 | ||||
471 | if (Layout.getAssembler().isThumbFunc(&Data.getSymbol())) | |||
472 | Res |= 1; | |||
473 | ||||
474 | return Res; | |||
475 | } | |||
476 | ||||
477 | void ELFObjectWriter::ExecutePostLayoutBinding(MCAssembler &Asm, | |||
478 | const MCAsmLayout &Layout) { | |||
479 | // The presence of symbol versions causes undefined symbols and | |||
480 | // versions declared with @@@ to be renamed. | |||
481 | ||||
482 | for (MCSymbolData &OriginalData : Asm.symbols()) { | |||
483 | const MCSymbol &Alias = OriginalData.getSymbol(); | |||
484 | ||||
485 | // Not an alias. | |||
486 | if (!Alias.isVariable()) | |||
487 | continue; | |||
488 | auto *Ref = dyn_cast<MCSymbolRefExpr>(Alias.getVariableValue()); | |||
489 | if (!Ref) | |||
490 | continue; | |||
491 | const MCSymbol &Symbol = Ref->getSymbol(); | |||
492 | MCSymbolData &SD = Asm.getSymbolData(Symbol); | |||
493 | ||||
494 | StringRef AliasName = Alias.getName(); | |||
495 | size_t Pos = AliasName.find('@'); | |||
496 | if (Pos == StringRef::npos) | |||
497 | continue; | |||
498 | ||||
499 | // Aliases defined with .symvar copy the binding from the symbol they alias. | |||
500 | // This is the first place we are able to copy this information. | |||
501 | OriginalData.setExternal(SD.isExternal()); | |||
502 | MCELF::SetBinding(OriginalData, MCELF::GetBinding(SD)); | |||
503 | ||||
504 | StringRef Rest = AliasName.substr(Pos); | |||
505 | if (!Symbol.isUndefined() && !Rest.startswith("@@@")) | |||
506 | continue; | |||
507 | ||||
508 | // FIXME: produce a better error message. | |||
509 | if (Symbol.isUndefined() && Rest.startswith("@@") && | |||
510 | !Rest.startswith("@@@")) | |||
511 | report_fatal_error("A @@ version cannot be undefined"); | |||
512 | ||||
513 | Renames.insert(std::make_pair(&Symbol, &Alias)); | |||
514 | } | |||
515 | } | |||
516 | ||||
517 | static uint8_t mergeTypeForSet(uint8_t origType, uint8_t newType) { | |||
518 | uint8_t Type = newType; | |||
519 | ||||
520 | // Propagation rules: | |||
521 | // IFUNC > FUNC > OBJECT > NOTYPE | |||
522 | // TLS_OBJECT > OBJECT > NOTYPE | |||
523 | // | |||
524 | // dont let the new type degrade the old type | |||
525 | switch (origType) { | |||
526 | default: | |||
527 | break; | |||
528 | case ELF::STT_GNU_IFUNC: | |||
529 | if (Type == ELF::STT_FUNC || Type == ELF::STT_OBJECT || | |||
530 | Type == ELF::STT_NOTYPE || Type == ELF::STT_TLS) | |||
531 | Type = ELF::STT_GNU_IFUNC; | |||
532 | break; | |||
533 | case ELF::STT_FUNC: | |||
534 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || | |||
535 | Type == ELF::STT_TLS) | |||
536 | Type = ELF::STT_FUNC; | |||
537 | break; | |||
538 | case ELF::STT_OBJECT: | |||
539 | if (Type == ELF::STT_NOTYPE) | |||
540 | Type = ELF::STT_OBJECT; | |||
541 | break; | |||
542 | case ELF::STT_TLS: | |||
543 | if (Type == ELF::STT_OBJECT || Type == ELF::STT_NOTYPE || | |||
544 | Type == ELF::STT_GNU_IFUNC || Type == ELF::STT_FUNC) | |||
545 | Type = ELF::STT_TLS; | |||
546 | break; | |||
547 | } | |||
548 | ||||
549 | return Type; | |||
550 | } | |||
551 | ||||
552 | void ELFObjectWriter::WriteSymbol(SymbolTableWriter &Writer, ELFSymbolData &MSD, | |||
553 | const MCAsmLayout &Layout) { | |||
554 | MCSymbolData &OrigData = *MSD.SymbolData; | |||
555 | assert((!OrigData.getFragment() ||(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 558, __PRETTY_FUNCTION__)) | |||
556 | (&OrigData.getFragment()->getParent()->getSection() ==(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 558, __PRETTY_FUNCTION__)) | |||
557 | &OrigData.getSymbol().getSection())) &&(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 558, __PRETTY_FUNCTION__)) | |||
558 | "The symbol's section doesn't match the fragment's symbol")(((!OrigData.getFragment() || (&OrigData.getFragment()-> getParent()->getSection() == &OrigData.getSymbol().getSection ())) && "The symbol's section doesn't match the fragment's symbol" ) ? static_cast<void> (0) : __assert_fail ("(!OrigData.getFragment() || (&OrigData.getFragment()->getParent()->getSection() == &OrigData.getSymbol().getSection())) && \"The symbol's section doesn't match the fragment's symbol\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 558, __PRETTY_FUNCTION__)); | |||
559 | const MCSymbol *Base = Layout.getBaseSymbol(OrigData.getSymbol()); | |||
560 | ||||
561 | // This has to be in sync with when computeSymbolTable uses SHN_ABS or | |||
562 | // SHN_COMMON. | |||
563 | bool IsReserved = !Base || OrigData.isCommon(); | |||
564 | ||||
565 | // Binding and Type share the same byte as upper and lower nibbles | |||
566 | uint8_t Binding = MCELF::GetBinding(OrigData); | |||
567 | uint8_t Type = MCELF::GetType(OrigData); | |||
568 | MCSymbolData *BaseSD = nullptr; | |||
569 | if (Base) { | |||
570 | BaseSD = &Layout.getAssembler().getSymbolData(*Base); | |||
571 | Type = mergeTypeForSet(Type, MCELF::GetType(*BaseSD)); | |||
572 | } | |||
573 | uint8_t Info = (Binding << ELF_STB_Shift) | (Type << ELF_STT_Shift); | |||
574 | ||||
575 | // Other and Visibility share the same byte with Visibility using the lower | |||
576 | // 2 bits | |||
577 | uint8_t Visibility = MCELF::GetVisibility(OrigData); | |||
578 | uint8_t Other = MCELF::getOther(OrigData) << (ELF_STO_Shift - ELF_STV_Shift); | |||
579 | Other |= Visibility; | |||
580 | ||||
581 | uint64_t Value = SymbolValue(OrigData, Layout); | |||
582 | uint64_t Size = 0; | |||
583 | ||||
584 | const MCExpr *ESize = OrigData.getSize(); | |||
585 | if (!ESize && Base) | |||
586 | ESize = BaseSD->getSize(); | |||
587 | ||||
588 | if (ESize) { | |||
589 | int64_t Res; | |||
590 | if (!ESize->evaluateKnownAbsolute(Res, Layout)) | |||
591 | report_fatal_error("Size expression must be absolute."); | |||
592 | Size = Res; | |||
593 | } | |||
594 | ||||
595 | // Write out the symbol table entry | |||
596 | Writer.writeSymbol(MSD.StringIndex, Info, Value, Size, Other, | |||
597 | MSD.SectionIndex, IsReserved); | |||
598 | } | |||
599 | ||||
600 | void ELFObjectWriter::WriteSymbolTable(MCDataFragment *SymtabF, | |||
601 | MCAssembler &Asm, | |||
602 | const MCAsmLayout &Layout, | |||
603 | SectionIndexMapTy &SectionIndexMap) { | |||
604 | // The string table must be emitted first because we need the index | |||
605 | // into the string table for all the symbol names. | |||
606 | ||||
607 | // FIXME: Make sure the start of the symbol table is aligned. | |||
608 | ||||
609 | SymbolTableWriter Writer(Asm, FWriter, is64Bit(), SectionIndexMap, SymtabF); | |||
610 | ||||
611 | // The first entry is the undefined symbol entry. | |||
612 | Writer.writeSymbol(0, 0, 0, 0, 0, 0, false); | |||
613 | ||||
614 | for (unsigned i = 0, e = FileSymbolData.size(); i != e; ++i) { | |||
615 | Writer.writeSymbol(FileSymbolData[i], ELF::STT_FILE | ELF::STB_LOCAL, 0, 0, | |||
616 | ELF::STV_DEFAULT, ELF::SHN_ABS, true); | |||
617 | } | |||
618 | ||||
619 | // Write the symbol table entries. | |||
620 | LastLocalSymbolIndex = FileSymbolData.size() + LocalSymbolData.size() + 1; | |||
621 | ||||
622 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) { | |||
623 | ELFSymbolData &MSD = LocalSymbolData[i]; | |||
624 | WriteSymbol(Writer, MSD, Layout); | |||
625 | } | |||
626 | ||||
627 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) { | |||
628 | ELFSymbolData &MSD = ExternalSymbolData[i]; | |||
629 | MCSymbolData &Data = *MSD.SymbolData; | |||
630 | assert(((Data.getFlags() & ELF_STB_Global) ||((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 632, __PRETTY_FUNCTION__)) | |||
631 | (Data.getFlags() & ELF_STB_Weak)) &&((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 632, __PRETTY_FUNCTION__)) | |||
632 | "External symbol requires STB_GLOBAL or STB_WEAK flag")((((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && "External symbol requires STB_GLOBAL or STB_WEAK flag" ) ? static_cast<void> (0) : __assert_fail ("((Data.getFlags() & ELF_STB_Global) || (Data.getFlags() & ELF_STB_Weak)) && \"External symbol requires STB_GLOBAL or STB_WEAK flag\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 632, __PRETTY_FUNCTION__)); | |||
633 | WriteSymbol(Writer, MSD, Layout); | |||
634 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) | |||
635 | LastLocalSymbolIndex++; | |||
636 | } | |||
637 | ||||
638 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) { | |||
639 | ELFSymbolData &MSD = UndefinedSymbolData[i]; | |||
640 | MCSymbolData &Data = *MSD.SymbolData; | |||
641 | WriteSymbol(Writer, MSD, Layout); | |||
642 | if (MCELF::GetBinding(Data) == ELF::STB_LOCAL) | |||
643 | LastLocalSymbolIndex++; | |||
644 | } | |||
645 | } | |||
646 | ||||
647 | // It is always valid to create a relocation with a symbol. It is preferable | |||
648 | // to use a relocation with a section if that is possible. Using the section | |||
649 | // allows us to omit some local symbols from the symbol table. | |||
650 | bool ELFObjectWriter::shouldRelocateWithSymbol(const MCAssembler &Asm, | |||
651 | const MCSymbolRefExpr *RefA, | |||
652 | const MCSymbolData *SD, | |||
653 | uint64_t C, | |||
654 | unsigned Type) const { | |||
655 | // A PCRel relocation to an absolute value has no symbol (or section). We | |||
656 | // represent that with a relocation to a null section. | |||
657 | if (!RefA) | |||
658 | return false; | |||
659 | ||||
660 | MCSymbolRefExpr::VariantKind Kind = RefA->getKind(); | |||
661 | switch (Kind) { | |||
662 | default: | |||
663 | break; | |||
664 | // The .odp creation emits a relocation against the symbol ".TOC." which | |||
665 | // create a R_PPC64_TOC relocation. However the relocation symbol name | |||
666 | // in final object creation should be NULL, since the symbol does not | |||
667 | // really exist, it is just the reference to TOC base for the current | |||
668 | // object file. Since the symbol is undefined, returning false results | |||
669 | // in a relocation with a null section which is the desired result. | |||
670 | case MCSymbolRefExpr::VK_PPC_TOCBASE: | |||
671 | return false; | |||
672 | ||||
673 | // These VariantKind cause the relocation to refer to something other than | |||
674 | // the symbol itself, like a linker generated table. Since the address of | |||
675 | // symbol is not relevant, we cannot replace the symbol with the | |||
676 | // section and patch the difference in the addend. | |||
677 | case MCSymbolRefExpr::VK_GOT: | |||
678 | case MCSymbolRefExpr::VK_PLT: | |||
679 | case MCSymbolRefExpr::VK_GOTPCREL: | |||
680 | case MCSymbolRefExpr::VK_Mips_GOT: | |||
681 | case MCSymbolRefExpr::VK_PPC_GOT_LO: | |||
682 | case MCSymbolRefExpr::VK_PPC_GOT_HI: | |||
683 | case MCSymbolRefExpr::VK_PPC_GOT_HA: | |||
684 | return true; | |||
685 | } | |||
686 | ||||
687 | // An undefined symbol is not in any section, so the relocation has to point | |||
688 | // to the symbol itself. | |||
689 | const MCSymbol &Sym = SD->getSymbol(); | |||
690 | if (Sym.isUndefined()) | |||
691 | return true; | |||
692 | ||||
693 | unsigned Binding = MCELF::GetBinding(*SD); | |||
694 | switch(Binding) { | |||
695 | default: | |||
696 | llvm_unreachable("Invalid Binding")::llvm::llvm_unreachable_internal("Invalid Binding", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 696); | |||
697 | case ELF::STB_LOCAL: | |||
698 | break; | |||
699 | case ELF::STB_WEAK: | |||
700 | // If the symbol is weak, it might be overridden by a symbol in another | |||
701 | // file. The relocation has to point to the symbol so that the linker | |||
702 | // can update it. | |||
703 | return true; | |||
704 | case ELF::STB_GLOBAL: | |||
705 | // Global ELF symbols can be preempted by the dynamic linker. The relocation | |||
706 | // has to point to the symbol for a reason analogous to the STB_WEAK case. | |||
707 | return true; | |||
708 | } | |||
709 | ||||
710 | // If a relocation points to a mergeable section, we have to be careful. | |||
711 | // If the offset is zero, a relocation with the section will encode the | |||
712 | // same information. With a non-zero offset, the situation is different. | |||
713 | // For example, a relocation can point 42 bytes past the end of a string. | |||
714 | // If we change such a relocation to use the section, the linker would think | |||
715 | // that it pointed to another string and subtracting 42 at runtime will | |||
716 | // produce the wrong value. | |||
717 | auto &Sec = cast<MCSectionELF>(Sym.getSection()); | |||
718 | unsigned Flags = Sec.getFlags(); | |||
719 | if (Flags & ELF::SHF_MERGE) { | |||
720 | if (C != 0) | |||
721 | return true; | |||
722 | ||||
723 | // It looks like gold has a bug (http://sourceware.org/PR16794) and can | |||
724 | // only handle section relocations to mergeable sections if using RELA. | |||
725 | if (!hasRelocationAddend()) | |||
726 | return true; | |||
727 | } | |||
728 | ||||
729 | // Most TLS relocations use a got, so they need the symbol. Even those that | |||
730 | // are just an offset (@tpoff), require a symbol in gold versions before | |||
731 | // 5efeedf61e4fe720fd3e9a08e6c91c10abb66d42 (2014-09-26) which fixed | |||
732 | // http://sourceware.org/PR16773. | |||
733 | if (Flags & ELF::SHF_TLS) | |||
734 | return true; | |||
735 | ||||
736 | // If the symbol is a thumb function the final relocation must set the lowest | |||
737 | // bit. With a symbol that is done by just having the symbol have that bit | |||
738 | // set, so we would lose the bit if we relocated with the section. | |||
739 | // FIXME: We could use the section but add the bit to the relocation value. | |||
740 | if (Asm.isThumbFunc(&Sym)) | |||
741 | return true; | |||
742 | ||||
743 | if (TargetObjectWriter->needsRelocateWithSymbol(*SD, Type)) | |||
744 | return true; | |||
745 | return false; | |||
746 | } | |||
747 | ||||
748 | static const MCSymbol *getWeakRef(const MCSymbolRefExpr &Ref) { | |||
749 | const MCSymbol &Sym = Ref.getSymbol(); | |||
750 | ||||
751 | if (Ref.getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
752 | return &Sym; | |||
753 | ||||
754 | if (!Sym.isVariable()) | |||
755 | return nullptr; | |||
756 | ||||
757 | const MCExpr *Expr = Sym.getVariableValue(); | |||
758 | const auto *Inner = dyn_cast<MCSymbolRefExpr>(Expr); | |||
759 | if (!Inner) | |||
760 | return nullptr; | |||
761 | ||||
762 | if (Inner->getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
763 | return &Inner->getSymbol(); | |||
764 | return nullptr; | |||
765 | } | |||
766 | ||||
767 | // True if the assembler knows nothing about the final value of the symbol. | |||
768 | // This doesn't cover the comdat issues, since in those cases the assembler | |||
769 | // can at least know that all symbols in the section will move together. | |||
770 | static bool isWeak(const MCSymbolData &D) { | |||
771 | if (MCELF::GetType(D) == ELF::STT_GNU_IFUNC) | |||
772 | return true; | |||
773 | ||||
774 | switch (MCELF::GetBinding(D)) { | |||
775 | default: | |||
776 | llvm_unreachable("Unknown binding")::llvm::llvm_unreachable_internal("Unknown binding", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 776); | |||
777 | case ELF::STB_LOCAL: | |||
778 | return false; | |||
779 | case ELF::STB_GLOBAL: | |||
780 | return false; | |||
781 | case ELF::STB_WEAK: | |||
782 | case ELF::STB_GNU_UNIQUE: | |||
783 | return true; | |||
784 | } | |||
785 | } | |||
786 | ||||
787 | void ELFObjectWriter::RecordRelocation(MCAssembler &Asm, | |||
788 | const MCAsmLayout &Layout, | |||
789 | const MCFragment *Fragment, | |||
790 | const MCFixup &Fixup, MCValue Target, | |||
791 | bool &IsPCRel, uint64_t &FixedValue) { | |||
792 | const MCSectionData *FixupSection = Fragment->getParent(); | |||
793 | uint64_t C = Target.getConstant(); | |||
794 | uint64_t FixupOffset = Layout.getFragmentOffset(Fragment) + Fixup.getOffset(); | |||
795 | ||||
796 | if (const MCSymbolRefExpr *RefB = Target.getSymB()) { | |||
797 | assert(RefB->getKind() == MCSymbolRefExpr::VK_None &&((RefB->getKind() == MCSymbolRefExpr::VK_None && "Should not have constructed this" ) ? static_cast<void> (0) : __assert_fail ("RefB->getKind() == MCSymbolRefExpr::VK_None && \"Should not have constructed this\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 798, __PRETTY_FUNCTION__)) | |||
798 | "Should not have constructed this")((RefB->getKind() == MCSymbolRefExpr::VK_None && "Should not have constructed this" ) ? static_cast<void> (0) : __assert_fail ("RefB->getKind() == MCSymbolRefExpr::VK_None && \"Should not have constructed this\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 798, __PRETTY_FUNCTION__)); | |||
799 | ||||
800 | // Let A, B and C being the components of Target and R be the location of | |||
801 | // the fixup. If the fixup is not pcrel, we want to compute (A - B + C). | |||
802 | // If it is pcrel, we want to compute (A - B + C - R). | |||
803 | ||||
804 | // In general, ELF has no relocations for -B. It can only represent (A + C) | |||
805 | // or (A + C - R). If B = R + K and the relocation is not pcrel, we can | |||
806 | // replace B to implement it: (A - R - K + C) | |||
807 | if (IsPCRel) | |||
808 | Asm.getContext().FatalError( | |||
809 | Fixup.getLoc(), | |||
810 | "No relocation available to represent this relative expression"); | |||
811 | ||||
812 | const MCSymbol &SymB = RefB->getSymbol(); | |||
813 | ||||
814 | if (SymB.isUndefined()) | |||
815 | Asm.getContext().FatalError( | |||
816 | Fixup.getLoc(), | |||
817 | Twine("symbol '") + SymB.getName() + | |||
818 | "' can not be undefined in a subtraction expression"); | |||
819 | ||||
820 | assert(!SymB.isAbsolute() && "Should have been folded")((!SymB.isAbsolute() && "Should have been folded") ? static_cast <void> (0) : __assert_fail ("!SymB.isAbsolute() && \"Should have been folded\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 820, __PRETTY_FUNCTION__)); | |||
821 | const MCSection &SecB = SymB.getSection(); | |||
822 | if (&SecB != &FixupSection->getSection()) | |||
823 | Asm.getContext().FatalError( | |||
824 | Fixup.getLoc(), "Cannot represent a difference across sections"); | |||
825 | ||||
826 | const MCSymbolData &SymBD = Asm.getSymbolData(SymB); | |||
827 | if (::isWeak(SymBD)) | |||
828 | Asm.getContext().FatalError( | |||
829 | Fixup.getLoc(), "Cannot represent a subtraction with a weak symbol"); | |||
830 | ||||
831 | uint64_t SymBOffset = Layout.getSymbolOffset(&SymBD); | |||
832 | uint64_t K = SymBOffset - FixupOffset; | |||
833 | IsPCRel = true; | |||
834 | C -= K; | |||
835 | } | |||
836 | ||||
837 | // We either rejected the fixup or folded B into C at this point. | |||
838 | const MCSymbolRefExpr *RefA = Target.getSymA(); | |||
839 | const MCSymbol *SymA = RefA ? &RefA->getSymbol() : nullptr; | |||
840 | const MCSymbolData *SymAD = SymA ? &Asm.getSymbolData(*SymA) : nullptr; | |||
841 | ||||
842 | unsigned Type = GetRelocType(Target, Fixup, IsPCRel); | |||
843 | bool RelocateWithSymbol = shouldRelocateWithSymbol(Asm, RefA, SymAD, C, Type); | |||
844 | if (!RelocateWithSymbol && SymA && !SymA->isUndefined()) | |||
845 | C += Layout.getSymbolOffset(SymAD); | |||
846 | ||||
847 | uint64_t Addend = 0; | |||
848 | if (hasRelocationAddend()) { | |||
849 | Addend = C; | |||
850 | C = 0; | |||
851 | } | |||
852 | ||||
853 | FixedValue = C; | |||
854 | ||||
855 | // FIXME: What is this!?!? | |||
856 | MCSymbolRefExpr::VariantKind Modifier = | |||
857 | RefA ? RefA->getKind() : MCSymbolRefExpr::VK_None; | |||
858 | if (RelocNeedsGOT(Modifier)) | |||
859 | NeedsGOT = true; | |||
860 | ||||
861 | if (!RelocateWithSymbol) { | |||
862 | const MCSection *SecA = | |||
863 | (SymA && !SymA->isUndefined()) ? &SymA->getSection() : nullptr; | |||
864 | auto *ELFSec = cast_or_null<MCSectionELF>(SecA); | |||
865 | MCSymbol *SectionSymbol = | |||
866 | ELFSec ? Asm.getContext().getOrCreateSectionSymbol(*ELFSec) | |||
867 | : nullptr; | |||
868 | ELFRelocationEntry Rec(FixupOffset, SectionSymbol, Type, Addend); | |||
869 | Relocations[FixupSection].push_back(Rec); | |||
870 | return; | |||
871 | } | |||
872 | ||||
873 | if (SymA) { | |||
874 | if (const MCSymbol *R = Renames.lookup(SymA)) | |||
875 | SymA = R; | |||
876 | ||||
877 | if (const MCSymbol *WeakRef = getWeakRef(*RefA)) | |||
878 | WeakrefUsedInReloc.insert(WeakRef); | |||
879 | else | |||
880 | UsedInReloc.insert(SymA); | |||
881 | } | |||
882 | ELFRelocationEntry Rec(FixupOffset, SymA, Type, Addend); | |||
883 | Relocations[FixupSection].push_back(Rec); | |||
884 | return; | |||
885 | } | |||
886 | ||||
887 | ||||
888 | uint64_t | |||
889 | ELFObjectWriter::getSymbolIndexInSymbolTable(const MCAssembler &Asm, | |||
890 | const MCSymbol *S) { | |||
891 | const MCSymbolData &SD = Asm.getSymbolData(*S); | |||
892 | return SD.getIndex(); | |||
893 | } | |||
894 | ||||
895 | bool ELFObjectWriter::isInSymtab(const MCAsmLayout &Layout, | |||
896 | const MCSymbolData &Data, bool Used, | |||
897 | bool Renamed) { | |||
898 | const MCSymbol &Symbol = Data.getSymbol(); | |||
899 | if (Symbol.isVariable()) { | |||
900 | const MCExpr *Expr = Symbol.getVariableValue(); | |||
901 | if (const MCSymbolRefExpr *Ref = dyn_cast<MCSymbolRefExpr>(Expr)) { | |||
902 | if (Ref->getKind() == MCSymbolRefExpr::VK_WEAKREF) | |||
903 | return false; | |||
904 | } | |||
905 | } | |||
906 | ||||
907 | if (Used) | |||
908 | return true; | |||
909 | ||||
910 | if (Renamed) | |||
911 | return false; | |||
912 | ||||
913 | if (Symbol.getName() == "_GLOBAL_OFFSET_TABLE_") | |||
914 | return true; | |||
915 | ||||
916 | if (Symbol.isVariable()) { | |||
917 | const MCSymbol *Base = Layout.getBaseSymbol(Symbol); | |||
918 | if (Base && Base->isUndefined()) | |||
919 | return false; | |||
920 | } | |||
921 | ||||
922 | bool IsGlobal = MCELF::GetBinding(Data) == ELF::STB_GLOBAL; | |||
923 | if (!Symbol.isVariable() && Symbol.isUndefined() && !IsGlobal) | |||
924 | return false; | |||
925 | ||||
926 | if (Symbol.isTemporary()) | |||
927 | return false; | |||
928 | ||||
929 | return true; | |||
930 | } | |||
931 | ||||
932 | bool ELFObjectWriter::isLocal(const MCSymbolData &Data, bool isUsedInReloc) { | |||
933 | if (Data.isExternal()) | |||
934 | return false; | |||
935 | ||||
936 | const MCSymbol &Symbol = Data.getSymbol(); | |||
937 | if (Symbol.isDefined()) | |||
938 | return true; | |||
939 | ||||
940 | if (isUsedInReloc) | |||
941 | return false; | |||
942 | ||||
943 | return true; | |||
944 | } | |||
945 | ||||
946 | void ELFObjectWriter::computeIndexMap(MCAssembler &Asm, | |||
947 | SectionIndexMapTy &SectionIndexMap) { | |||
948 | unsigned Index = 1; | |||
949 | for (MCAssembler::iterator it = Asm.begin(), | |||
950 | ie = Asm.end(); it != ie; ++it) { | |||
951 | const MCSectionELF &Section = | |||
952 | static_cast<const MCSectionELF &>(it->getSection()); | |||
953 | if (Section.getType() != ELF::SHT_GROUP) | |||
954 | continue; | |||
955 | SectionIndexMap[&Section] = Index++; | |||
956 | } | |||
957 | ||||
958 | std::vector<const MCSectionELF *> RelSections; | |||
959 | ||||
960 | for (MCAssembler::iterator it = Asm.begin(), | |||
961 | ie = Asm.end(); it != ie; ++it) { | |||
962 | const MCSectionData &SD = *it; | |||
963 | const MCSectionELF &Section = | |||
964 | static_cast<const MCSectionELF &>(SD.getSection()); | |||
965 | if (Section.getType() == ELF::SHT_GROUP || | |||
966 | Section.getType() == ELF::SHT_REL || | |||
967 | Section.getType() == ELF::SHT_RELA) | |||
968 | continue; | |||
969 | SectionIndexMap[&Section] = Index++; | |||
970 | if (MCSectionData *RelSD = createRelocationSection(Asm, SD)) { | |||
971 | const MCSectionELF *RelSection = | |||
972 | static_cast<const MCSectionELF *>(&RelSD->getSection()); | |||
973 | RelSections.push_back(RelSection); | |||
974 | } | |||
975 | } | |||
976 | ||||
977 | // Put relocation sections close together. The linker reads them | |||
978 | // first, so this improves cache locality. | |||
979 | for (const MCSectionELF * Sec: RelSections) | |||
980 | SectionIndexMap[Sec] = Index++; | |||
981 | } | |||
982 | ||||
983 | void ELFObjectWriter::computeSymbolTable( | |||
984 | MCAssembler &Asm, const MCAsmLayout &Layout, | |||
985 | const SectionIndexMapTy &SectionIndexMap, | |||
986 | const RevGroupMapTy &RevGroupMap) { | |||
987 | // FIXME: Is this the correct place to do this? | |||
988 | // FIXME: Why is an undefined reference to _GLOBAL_OFFSET_TABLE_ needed? | |||
989 | if (NeedsGOT) { | |||
990 | StringRef Name = "_GLOBAL_OFFSET_TABLE_"; | |||
991 | MCSymbol *Sym = Asm.getContext().GetOrCreateSymbol(Name); | |||
992 | MCSymbolData &Data = Asm.getOrCreateSymbolData(*Sym); | |||
993 | Data.setExternal(true); | |||
994 | MCELF::SetBinding(Data, ELF::STB_GLOBAL); | |||
995 | } | |||
996 | ||||
997 | // Add the data for the symbols. | |||
998 | for (MCSymbolData &SD : Asm.symbols()) { | |||
999 | const MCSymbol &Symbol = SD.getSymbol(); | |||
1000 | ||||
1001 | bool Used = UsedInReloc.count(&Symbol); | |||
1002 | bool WeakrefUsed = WeakrefUsedInReloc.count(&Symbol); | |||
1003 | bool isSignature = RevGroupMap.count(&Symbol); | |||
1004 | ||||
1005 | if (!isInSymtab(Layout, SD, | |||
1006 | Used || WeakrefUsed || isSignature, | |||
1007 | Renames.count(&Symbol))) | |||
1008 | continue; | |||
1009 | ||||
1010 | ELFSymbolData MSD; | |||
1011 | MSD.SymbolData = &SD; | |||
1012 | const MCSymbol *BaseSymbol = Layout.getBaseSymbol(Symbol); | |||
1013 | ||||
1014 | // Undefined symbols are global, but this is the first place we | |||
1015 | // are able to set it. | |||
1016 | bool Local = isLocal(SD, Used); | |||
1017 | if (!Local && MCELF::GetBinding(SD) == ELF::STB_LOCAL) { | |||
1018 | assert(BaseSymbol)((BaseSymbol) ? static_cast<void> (0) : __assert_fail ( "BaseSymbol", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1018, __PRETTY_FUNCTION__)); | |||
1019 | MCSymbolData &BaseData = Asm.getSymbolData(*BaseSymbol); | |||
1020 | MCELF::SetBinding(SD, ELF::STB_GLOBAL); | |||
1021 | MCELF::SetBinding(BaseData, ELF::STB_GLOBAL); | |||
1022 | } | |||
1023 | ||||
1024 | if (!BaseSymbol) { | |||
1025 | MSD.SectionIndex = ELF::SHN_ABS; | |||
1026 | } else if (SD.isCommon()) { | |||
1027 | assert(!Local)((!Local) ? static_cast<void> (0) : __assert_fail ("!Local" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1027, __PRETTY_FUNCTION__)); | |||
1028 | MSD.SectionIndex = ELF::SHN_COMMON; | |||
1029 | } else if (BaseSymbol->isUndefined()) { | |||
1030 | if (isSignature && !Used) | |||
1031 | MSD.SectionIndex = SectionIndexMap.lookup(RevGroupMap.lookup(&Symbol)); | |||
1032 | else | |||
1033 | MSD.SectionIndex = ELF::SHN_UNDEF; | |||
1034 | if (!Used && WeakrefUsed) | |||
1035 | MCELF::SetBinding(SD, ELF::STB_WEAK); | |||
1036 | } else { | |||
1037 | const MCSectionELF &Section = | |||
1038 | static_cast<const MCSectionELF&>(BaseSymbol->getSection()); | |||
1039 | MSD.SectionIndex = SectionIndexMap.lookup(&Section); | |||
1040 | assert(MSD.SectionIndex && "Invalid section index!")((MSD.SectionIndex && "Invalid section index!") ? static_cast <void> (0) : __assert_fail ("MSD.SectionIndex && \"Invalid section index!\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1040, __PRETTY_FUNCTION__)); | |||
1041 | } | |||
1042 | ||||
1043 | // The @@@ in symbol version is replaced with @ in undefined symbols and @@ | |||
1044 | // in defined ones. | |||
1045 | // | |||
1046 | // FIXME: All name handling should be done before we get to the writer, | |||
1047 | // including dealing with GNU-style version suffixes. Fixing this isn't | |||
1048 | // trivial. | |||
1049 | // | |||
1050 | // We thus have to be careful to not perform the symbol version replacement | |||
1051 | // blindly: | |||
1052 | // | |||
1053 | // The ELF format is used on Windows by the MCJIT engine. Thus, on | |||
1054 | // Windows, the ELFObjectWriter can encounter symbols mangled using the MS | |||
1055 | // Visual Studio C++ name mangling scheme. Symbols mangled using the MSVC | |||
1056 | // C++ name mangling can legally have "@@@" as a sub-string. In that case, | |||
1057 | // the EFLObjectWriter should not interpret the "@@@" sub-string as | |||
1058 | // specifying GNU-style symbol versioning. The ELFObjectWriter therefore | |||
1059 | // checks for the MSVC C++ name mangling prefix which is either "?", "@?", | |||
1060 | // "__imp_?" or "__imp_@?". | |||
1061 | // | |||
1062 | // It would have been interesting to perform the MS mangling prefix check | |||
1063 | // only when the target triple is of the form *-pc-windows-elf. But, it | |||
1064 | // seems that this information is not easily accessible from the | |||
1065 | // ELFObjectWriter. | |||
1066 | StringRef Name = Symbol.getName(); | |||
1067 | if (!Name.startswith("?") && !Name.startswith("@?") && | |||
1068 | !Name.startswith("__imp_?") && !Name.startswith("__imp_@?")) { | |||
1069 | // This symbol isn't following the MSVC C++ name mangling convention. We | |||
1070 | // can thus safely interpret the @@@ in symbol names as specifying symbol | |||
1071 | // versioning. | |||
1072 | SmallString<32> Buf; | |||
1073 | size_t Pos = Name.find("@@@"); | |||
1074 | if (Pos != StringRef::npos) { | |||
1075 | Buf += Name.substr(0, Pos); | |||
1076 | unsigned Skip = MSD.SectionIndex == ELF::SHN_UNDEF ? 2 : 1; | |||
1077 | Buf += Name.substr(Pos + Skip); | |||
1078 | Name = Buf; | |||
1079 | } | |||
1080 | } | |||
1081 | ||||
1082 | // Sections have their own string table | |||
1083 | if (MCELF::GetType(SD) != ELF::STT_SECTION) | |||
1084 | MSD.Name = StrTabBuilder.add(Name); | |||
1085 | ||||
1086 | if (MSD.SectionIndex == ELF::SHN_UNDEF) | |||
1087 | UndefinedSymbolData.push_back(MSD); | |||
1088 | else if (Local) | |||
1089 | LocalSymbolData.push_back(MSD); | |||
1090 | else | |||
1091 | ExternalSymbolData.push_back(MSD); | |||
1092 | } | |||
1093 | ||||
1094 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) | |||
1095 | StrTabBuilder.add(*i); | |||
1096 | ||||
1097 | StrTabBuilder.finalize(StringTableBuilder::ELF); | |||
1098 | ||||
1099 | for (auto i = Asm.file_names_begin(), e = Asm.file_names_end(); i != e; ++i) | |||
1100 | FileSymbolData.push_back(StrTabBuilder.getOffset(*i)); | |||
1101 | ||||
1102 | for (ELFSymbolData &MSD : LocalSymbolData) | |||
1103 | MSD.StringIndex = MCELF::GetType(*MSD.SymbolData) == ELF::STT_SECTION | |||
1104 | ? 0 | |||
1105 | : StrTabBuilder.getOffset(MSD.Name); | |||
1106 | for (ELFSymbolData &MSD : ExternalSymbolData) | |||
1107 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); | |||
1108 | for (ELFSymbolData& MSD : UndefinedSymbolData) | |||
1109 | MSD.StringIndex = StrTabBuilder.getOffset(MSD.Name); | |||
1110 | ||||
1111 | // Symbols are required to be in lexicographic order. | |||
1112 | array_pod_sort(LocalSymbolData.begin(), LocalSymbolData.end()); | |||
1113 | array_pod_sort(ExternalSymbolData.begin(), ExternalSymbolData.end()); | |||
1114 | array_pod_sort(UndefinedSymbolData.begin(), UndefinedSymbolData.end()); | |||
1115 | ||||
1116 | // Set the symbol indices. Local symbols must come before all other | |||
1117 | // symbols with non-local bindings. | |||
1118 | unsigned Index = FileSymbolData.size() + 1; | |||
1119 | for (unsigned i = 0, e = LocalSymbolData.size(); i != e; ++i) | |||
1120 | LocalSymbolData[i].SymbolData->setIndex(Index++); | |||
1121 | ||||
1122 | for (unsigned i = 0, e = ExternalSymbolData.size(); i != e; ++i) | |||
1123 | ExternalSymbolData[i].SymbolData->setIndex(Index++); | |||
1124 | for (unsigned i = 0, e = UndefinedSymbolData.size(); i != e; ++i) | |||
1125 | UndefinedSymbolData[i].SymbolData->setIndex(Index++); | |||
1126 | } | |||
1127 | ||||
1128 | MCSectionData * | |||
1129 | ELFObjectWriter::createRelocationSection(MCAssembler &Asm, | |||
1130 | const MCSectionData &SD) { | |||
1131 | if (Relocations[&SD].empty()) | |||
1132 | return nullptr; | |||
1133 | ||||
1134 | MCContext &Ctx = Asm.getContext(); | |||
1135 | const MCSectionELF &Section = | |||
1136 | static_cast<const MCSectionELF &>(SD.getSection()); | |||
1137 | ||||
1138 | const StringRef SectionName = Section.getSectionName(); | |||
1139 | std::string RelaSectionName = hasRelocationAddend() ? ".rela" : ".rel"; | |||
1140 | RelaSectionName += SectionName; | |||
1141 | ||||
1142 | unsigned EntrySize; | |||
1143 | if (hasRelocationAddend()) | |||
1144 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rela) : sizeof(ELF::Elf32_Rela); | |||
1145 | else | |||
1146 | EntrySize = is64Bit() ? sizeof(ELF::Elf64_Rel) : sizeof(ELF::Elf32_Rel); | |||
1147 | ||||
1148 | unsigned Flags = 0; | |||
1149 | if (Section.getFlags() & ELF::SHF_GROUP) | |||
1150 | Flags = ELF::SHF_GROUP; | |||
1151 | ||||
1152 | const MCSectionELF *RelaSection = Ctx.createELFRelSection( | |||
1153 | RelaSectionName, hasRelocationAddend() ? ELF::SHT_RELA : ELF::SHT_REL, | |||
1154 | Flags, EntrySize, Section.getGroup(), &Section); | |||
1155 | return &Asm.getOrCreateSectionData(*RelaSection); | |||
1156 | } | |||
1157 | ||||
1158 | static SmallVector<char, 128> | |||
1159 | getUncompressedData(MCAsmLayout &Layout, | |||
1160 | MCSectionData::FragmentListType &Fragments) { | |||
1161 | SmallVector<char, 128> UncompressedData; | |||
1162 | for (const MCFragment &F : Fragments) { | |||
1163 | const SmallVectorImpl<char> *Contents; | |||
1164 | switch (F.getKind()) { | |||
1165 | case MCFragment::FT_Data: | |||
1166 | Contents = &cast<MCDataFragment>(F).getContents(); | |||
1167 | break; | |||
1168 | case MCFragment::FT_Dwarf: | |||
1169 | Contents = &cast<MCDwarfLineAddrFragment>(F).getContents(); | |||
1170 | break; | |||
1171 | case MCFragment::FT_DwarfFrame: | |||
1172 | Contents = &cast<MCDwarfCallFrameFragment>(F).getContents(); | |||
1173 | break; | |||
1174 | default: | |||
1175 | llvm_unreachable(::llvm::llvm_unreachable_internal("Not expecting any other fragment types in a debug_* section" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1176) | |||
1176 | "Not expecting any other fragment types in a debug_* section")::llvm::llvm_unreachable_internal("Not expecting any other fragment types in a debug_* section" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1176); | |||
1177 | } | |||
1178 | UncompressedData.append(Contents->begin(), Contents->end()); | |||
1179 | } | |||
1180 | return UncompressedData; | |||
1181 | } | |||
1182 | ||||
1183 | // Include the debug info compression header: | |||
1184 | // "ZLIB" followed by 8 bytes representing the uncompressed size of the section, | |||
1185 | // useful for consumers to preallocate a buffer to decompress into. | |||
1186 | static bool | |||
1187 | prependCompressionHeader(uint64_t Size, | |||
1188 | SmallVectorImpl<char> &CompressedContents) { | |||
1189 | const StringRef Magic = "ZLIB"; | |||
1190 | if (Size <= Magic.size() + sizeof(Size) + CompressedContents.size()) | |||
1191 | return false; | |||
1192 | if (sys::IsLittleEndianHost) | |||
1193 | sys::swapByteOrder(Size); | |||
1194 | CompressedContents.insert(CompressedContents.begin(), | |||
1195 | Magic.size() + sizeof(Size), 0); | |||
1196 | std::copy(Magic.begin(), Magic.end(), CompressedContents.begin()); | |||
1197 | std::copy(reinterpret_cast<char *>(&Size), | |||
1198 | reinterpret_cast<char *>(&Size + 1), | |||
1199 | CompressedContents.begin() + Magic.size()); | |||
1200 | return true; | |||
1201 | } | |||
1202 | ||||
1203 | // Return a single fragment containing the compressed contents of the whole | |||
1204 | // section. Null if the section was not compressed for any reason. | |||
1205 | static std::unique_ptr<MCDataFragment> | |||
1206 | getCompressedFragment(MCAsmLayout &Layout, | |||
1207 | MCSectionData::FragmentListType &Fragments) { | |||
1208 | std::unique_ptr<MCDataFragment> CompressedFragment(new MCDataFragment()); | |||
1209 | ||||
1210 | // Gather the uncompressed data from all the fragments, recording the | |||
1211 | // alignment fragment, if seen, and any fixups. | |||
1212 | SmallVector<char, 128> UncompressedData = | |||
1213 | getUncompressedData(Layout, Fragments); | |||
1214 | ||||
1215 | SmallVectorImpl<char> &CompressedContents = CompressedFragment->getContents(); | |||
1216 | ||||
1217 | zlib::Status Success = zlib::compress( | |||
1218 | StringRef(UncompressedData.data(), UncompressedData.size()), | |||
1219 | CompressedContents); | |||
1220 | if (Success != zlib::StatusOK) | |||
1221 | return nullptr; | |||
1222 | ||||
1223 | if (!prependCompressionHeader(UncompressedData.size(), CompressedContents)) | |||
1224 | return nullptr; | |||
1225 | ||||
1226 | return CompressedFragment; | |||
1227 | } | |||
1228 | ||||
1229 | typedef DenseMap<const MCSectionData *, std::vector<MCSymbolData *>> | |||
1230 | DefiningSymbolMap; | |||
1231 | ||||
1232 | static void UpdateSymbols(const MCAsmLayout &Layout, | |||
1233 | const std::vector<MCSymbolData *> &Symbols, | |||
1234 | MCFragment &NewFragment) { | |||
1235 | for (MCSymbolData *Sym : Symbols) { | |||
1236 | Sym->setOffset(Sym->getOffset() + | |||
1237 | Layout.getFragmentOffset(Sym->getFragment())); | |||
1238 | Sym->setFragment(&NewFragment); | |||
1239 | } | |||
1240 | } | |||
1241 | ||||
1242 | static void CompressDebugSection(MCAssembler &Asm, MCAsmLayout &Layout, | |||
1243 | const DefiningSymbolMap &DefiningSymbols, | |||
1244 | const MCSectionELF &Section, | |||
1245 | MCSectionData &SD) { | |||
1246 | StringRef SectionName = Section.getSectionName(); | |||
1247 | MCSectionData::FragmentListType &Fragments = SD.getFragmentList(); | |||
1248 | ||||
1249 | std::unique_ptr<MCDataFragment> CompressedFragment = | |||
1250 | getCompressedFragment(Layout, Fragments); | |||
1251 | ||||
1252 | // Leave the section as-is if the fragments could not be compressed. | |||
1253 | if (!CompressedFragment) | |||
1254 | return; | |||
1255 | ||||
1256 | // Update the fragment+offsets of any symbols referring to fragments in this | |||
1257 | // section to refer to the new fragment. | |||
1258 | auto I = DefiningSymbols.find(&SD); | |||
1259 | if (I != DefiningSymbols.end()) | |||
1260 | UpdateSymbols(Layout, I->second, *CompressedFragment); | |||
1261 | ||||
1262 | // Invalidate the layout for the whole section since it will have new and | |||
1263 | // different fragments now. | |||
1264 | Layout.invalidateFragmentsFrom(&Fragments.front()); | |||
1265 | Fragments.clear(); | |||
1266 | ||||
1267 | // Complete the initialization of the new fragment | |||
1268 | CompressedFragment->setParent(&SD); | |||
1269 | CompressedFragment->setLayoutOrder(0); | |||
1270 | Fragments.push_back(CompressedFragment.release()); | |||
1271 | ||||
1272 | // Rename from .debug_* to .zdebug_* | |||
1273 | Asm.getContext().renameELFSection(&Section, | |||
1274 | (".z" + SectionName.drop_front(1)).str()); | |||
1275 | } | |||
1276 | ||||
1277 | void ELFObjectWriter::CompressDebugSections(MCAssembler &Asm, | |||
1278 | MCAsmLayout &Layout) { | |||
1279 | if (!Asm.getContext().getAsmInfo()->compressDebugSections()) | |||
1280 | return; | |||
1281 | ||||
1282 | DefiningSymbolMap DefiningSymbols; | |||
1283 | ||||
1284 | for (MCSymbolData &SD : Asm.symbols()) | |||
1285 | if (MCFragment *F = SD.getFragment()) | |||
1286 | DefiningSymbols[F->getParent()].push_back(&SD); | |||
1287 | ||||
1288 | for (MCSectionData &SD : Asm) { | |||
1289 | const MCSectionELF &Section = | |||
1290 | static_cast<const MCSectionELF &>(SD.getSection()); | |||
1291 | StringRef SectionName = Section.getSectionName(); | |||
1292 | ||||
1293 | // Compressing debug_frame requires handling alignment fragments which is | |||
1294 | // more work (possibly generalizing MCAssembler.cpp:writeFragment to allow | |||
1295 | // for writing to arbitrary buffers) for little benefit. | |||
1296 | if (!SectionName.startswith(".debug_") || SectionName == ".debug_frame") | |||
1297 | continue; | |||
1298 | ||||
1299 | CompressDebugSection(Asm, Layout, DefiningSymbols, Section, SD); | |||
1300 | } | |||
1301 | } | |||
1302 | ||||
1303 | void ELFObjectWriter::WriteRelocations(MCAssembler &Asm, MCAsmLayout &Layout) { | |||
1304 | for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { | |||
| ||||
| ||||
1305 | MCSectionData &RelSD = *it; | |||
1306 | const MCSectionELF &RelSection = | |||
1307 | static_cast<const MCSectionELF &>(RelSD.getSection()); | |||
1308 | ||||
1309 | unsigned Type = RelSection.getType(); | |||
1310 | if (Type != ELF::SHT_REL && Type != ELF::SHT_RELA) | |||
1311 | continue; | |||
1312 | ||||
1313 | const MCSectionELF *Section = RelSection.getAssociatedSection(); | |||
1314 | MCSectionData &SD = Asm.getOrCreateSectionData(*Section); | |||
1315 | RelSD.setAlignment(is64Bit() ? 8 : 4); | |||
1316 | ||||
1317 | MCDataFragment *F = new MCDataFragment(&RelSD); | |||
1318 | WriteRelocationsFragment(Asm, F, &SD); | |||
1319 | } | |||
1320 | } | |||
1321 | ||||
1322 | void ELFObjectWriter::WriteSecHdrEntry(uint32_t Name, uint32_t Type, | |||
1323 | uint64_t Flags, uint64_t Address, | |||
1324 | uint64_t Offset, uint64_t Size, | |||
1325 | uint32_t Link, uint32_t Info, | |||
1326 | uint64_t Alignment, | |||
1327 | uint64_t EntrySize) { | |||
1328 | Write32(Name); // sh_name: index into string table | |||
1329 | Write32(Type); // sh_type | |||
1330 | WriteWord(Flags); // sh_flags | |||
1331 | WriteWord(Address); // sh_addr | |||
1332 | WriteWord(Offset); // sh_offset | |||
1333 | WriteWord(Size); // sh_size | |||
1334 | Write32(Link); // sh_link | |||
1335 | Write32(Info); // sh_info | |||
1336 | WriteWord(Alignment); // sh_addralign | |||
1337 | WriteWord(EntrySize); // sh_entsize | |||
1338 | } | |||
1339 | ||||
1340 | void ELFObjectWriter::WriteRelocationsFragment(const MCAssembler &Asm, | |||
1341 | MCDataFragment *F, | |||
1342 | const MCSectionData *SD) { | |||
1343 | std::vector<ELFRelocationEntry> &Relocs = Relocations[SD]; | |||
1344 | ||||
1345 | // Sort the relocation entries. Most targets just sort by Offset, but some | |||
1346 | // (e.g., MIPS) have additional constraints. | |||
1347 | TargetObjectWriter->sortRelocs(Asm, Relocs); | |||
1348 | ||||
1349 | for (unsigned i = 0, e = Relocs.size(); i != e; ++i) { | |||
1350 | const ELFRelocationEntry &Entry = Relocs[e - i - 1]; | |||
1351 | unsigned Index = | |||
1352 | Entry.Symbol ? getSymbolIndexInSymbolTable(Asm, Entry.Symbol) : 0; | |||
1353 | ||||
1354 | if (is64Bit()) { | |||
1355 | write(*F, Entry.Offset); | |||
1356 | if (TargetObjectWriter->isN64()) { | |||
1357 | write(*F, uint32_t(Index)); | |||
1358 | ||||
1359 | write(*F, TargetObjectWriter->getRSsym(Entry.Type)); | |||
1360 | write(*F, TargetObjectWriter->getRType3(Entry.Type)); | |||
1361 | write(*F, TargetObjectWriter->getRType2(Entry.Type)); | |||
1362 | write(*F, TargetObjectWriter->getRType(Entry.Type)); | |||
1363 | } else { | |||
1364 | struct ELF::Elf64_Rela ERE64; | |||
1365 | ERE64.setSymbolAndType(Index, Entry.Type); | |||
1366 | write(*F, ERE64.r_info); | |||
1367 | } | |||
1368 | if (hasRelocationAddend()) | |||
1369 | write(*F, Entry.Addend); | |||
1370 | } else { | |||
1371 | write(*F, uint32_t(Entry.Offset)); | |||
1372 | ||||
1373 | struct ELF::Elf32_Rela ERE32; | |||
1374 | ERE32.setSymbolAndType(Index, Entry.Type); | |||
1375 | write(*F, ERE32.r_info); | |||
1376 | ||||
1377 | if (hasRelocationAddend()) | |||
1378 | write(*F, uint32_t(Entry.Addend)); | |||
1379 | } | |||
1380 | } | |||
1381 | } | |||
1382 | ||||
1383 | void ELFObjectWriter::CreateMetadataSections( | |||
1384 | MCAssembler &Asm, MCAsmLayout &Layout, SectionIndexMapTy &SectionIndexMap) { | |||
1385 | MCContext &Ctx = Asm.getContext(); | |||
1386 | MCDataFragment *F; | |||
1387 | ||||
1388 | unsigned EntrySize = is64Bit() ? ELF::SYMENTRY_SIZE64 : ELF::SYMENTRY_SIZE32; | |||
1389 | ||||
1390 | // We construct .shstrtab, .symtab and .strtab in this order to match gnu as. | |||
1391 | const MCSectionELF *ShstrtabSection = | |||
1392 | Ctx.getELFSection(".shstrtab", ELF::SHT_STRTAB, 0); | |||
1393 | MCSectionData &ShstrtabSD = Asm.getOrCreateSectionData(*ShstrtabSection); | |||
1394 | ShstrtabSD.setAlignment(1); | |||
1395 | ShstrtabIndex = SectionIndexMap.size() + 1; | |||
1396 | SectionIndexMap[ShstrtabSection] = ShstrtabIndex; | |||
1397 | ||||
1398 | const MCSectionELF *SymtabSection = | |||
1399 | Ctx.getELFSection(".symtab", ELF::SHT_SYMTAB, 0, | |||
1400 | EntrySize, ""); | |||
1401 | MCSectionData &SymtabSD = Asm.getOrCreateSectionData(*SymtabSection); | |||
1402 | SymtabSD.setAlignment(is64Bit() ? 8 : 4); | |||
1403 | SymbolTableIndex = SectionIndexMap.size() + 1; | |||
1404 | SectionIndexMap[SymtabSection] = SymbolTableIndex; | |||
1405 | ||||
1406 | const MCSectionELF *StrtabSection; | |||
1407 | StrtabSection = Ctx.getELFSection(".strtab", ELF::SHT_STRTAB, 0); | |||
1408 | MCSectionData &StrtabSD = Asm.getOrCreateSectionData(*StrtabSection); | |||
1409 | StrtabSD.setAlignment(1); | |||
1410 | StringTableIndex = SectionIndexMap.size() + 1; | |||
1411 | SectionIndexMap[StrtabSection] = StringTableIndex; | |||
1412 | ||||
1413 | // Symbol table | |||
1414 | F = new MCDataFragment(&SymtabSD); | |||
1415 | WriteSymbolTable(F, Asm, Layout, SectionIndexMap); | |||
1416 | ||||
1417 | F = new MCDataFragment(&StrtabSD); | |||
1418 | F->getContents().append(StrTabBuilder.data().begin(), | |||
1419 | StrTabBuilder.data().end()); | |||
1420 | ||||
1421 | F = new MCDataFragment(&ShstrtabSD); | |||
1422 | ||||
1423 | // Section header string table. | |||
1424 | for (auto it = Asm.begin(), ie = Asm.end(); it != ie; ++it) { | |||
1425 | const MCSectionELF &Section = | |||
1426 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1427 | ShStrTabBuilder.add(Section.getSectionName()); | |||
1428 | } | |||
1429 | ShStrTabBuilder.finalize(StringTableBuilder::ELF); | |||
1430 | F->getContents().append(ShStrTabBuilder.data().begin(), | |||
1431 | ShStrTabBuilder.data().end()); | |||
1432 | } | |||
1433 | ||||
1434 | void ELFObjectWriter::createIndexedSections( | |||
1435 | MCAssembler &Asm, MCAsmLayout &Layout, GroupMapTy &GroupMap, | |||
1436 | RevGroupMapTy &RevGroupMap, SectionIndexMapTy &SectionIndexMap) { | |||
1437 | MCContext &Ctx = Asm.getContext(); | |||
1438 | ||||
1439 | // Build the groups | |||
1440 | for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | |||
1441 | it != ie; ++it) { | |||
1442 | const MCSectionELF &Section = | |||
1443 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1444 | if (!(Section.getFlags() & ELF::SHF_GROUP)) | |||
1445 | continue; | |||
1446 | ||||
1447 | const MCSymbol *SignatureSymbol = Section.getGroup(); | |||
1448 | Asm.getOrCreateSymbolData(*SignatureSymbol); | |||
1449 | const MCSectionELF *&Group = RevGroupMap[SignatureSymbol]; | |||
1450 | if (!Group) { | |||
1451 | Group = Ctx.CreateELFGroupSection(); | |||
1452 | MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | |||
1453 | Data.setAlignment(4); | |||
1454 | MCDataFragment *F = new MCDataFragment(&Data); | |||
1455 | write(*F, uint32_t(ELF::GRP_COMDAT)); | |||
1456 | } | |||
1457 | GroupMap[Group] = SignatureSymbol; | |||
1458 | } | |||
1459 | ||||
1460 | computeIndexMap(Asm, SectionIndexMap); | |||
1461 | ||||
1462 | // Add sections to the groups | |||
1463 | for (MCAssembler::const_iterator it = Asm.begin(), ie = Asm.end(); | |||
1464 | it != ie; ++it) { | |||
1465 | const MCSectionELF &Section = | |||
1466 | static_cast<const MCSectionELF&>(it->getSection()); | |||
1467 | if (!(Section.getFlags() & ELF::SHF_GROUP)) | |||
1468 | continue; | |||
1469 | const MCSectionELF *Group = RevGroupMap[Section.getGroup()]; | |||
1470 | MCSectionData &Data = Asm.getOrCreateSectionData(*Group); | |||
1471 | // FIXME: we could use the previous fragment | |||
1472 | MCDataFragment *F = new MCDataFragment(&Data); | |||
1473 | uint32_t Index = SectionIndexMap.lookup(&Section); | |||
1474 | write(*F, Index); | |||
1475 | } | |||
1476 | } | |||
1477 | ||||
1478 | void ELFObjectWriter::writeSection(MCAssembler &Asm, | |||
1479 | const SectionIndexMapTy &SectionIndexMap, | |||
1480 | uint32_t GroupSymbolIndex, | |||
1481 | uint64_t Offset, uint64_t Size, | |||
1482 | uint64_t Alignment, | |||
1483 | const MCSectionELF &Section) { | |||
1484 | uint64_t sh_link = 0; | |||
1485 | uint64_t sh_info = 0; | |||
1486 | ||||
1487 | switch(Section.getType()) { | |||
1488 | default: | |||
1489 | // Nothing to do. | |||
1490 | break; | |||
1491 | ||||
1492 | case ELF::SHT_DYNAMIC: | |||
1493 | sh_link = ShStrTabBuilder.getOffset(Section.getSectionName()); | |||
1494 | break; | |||
1495 | ||||
1496 | case ELF::SHT_REL: | |||
1497 | case ELF::SHT_RELA: { | |||
1498 | sh_link = SymbolTableIndex; | |||
1499 | assert(sh_link && ".symtab not found")((sh_link && ".symtab not found") ? static_cast<void > (0) : __assert_fail ("sh_link && \".symtab not found\"" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1499, __PRETTY_FUNCTION__)); | |||
1500 | const MCSectionELF *InfoSection = Section.getAssociatedSection(); | |||
1501 | sh_info = SectionIndexMap.lookup(InfoSection); | |||
1502 | break; | |||
1503 | } | |||
1504 | ||||
1505 | case ELF::SHT_SYMTAB: | |||
1506 | case ELF::SHT_DYNSYM: | |||
1507 | sh_link = StringTableIndex; | |||
1508 | sh_info = LastLocalSymbolIndex; | |||
1509 | break; | |||
1510 | ||||
1511 | case ELF::SHT_SYMTAB_SHNDX: | |||
1512 | sh_link = SymbolTableIndex; | |||
1513 | break; | |||
1514 | ||||
1515 | case ELF::SHT_GROUP: | |||
1516 | sh_link = SymbolTableIndex; | |||
1517 | sh_info = GroupSymbolIndex; | |||
1518 | break; | |||
1519 | } | |||
1520 | ||||
1521 | if (TargetObjectWriter->getEMachine() == ELF::EM_ARM && | |||
1522 | Section.getType() == ELF::SHT_ARM_EXIDX) | |||
1523 | sh_link = SectionIndexMap.lookup(Section.getAssociatedSection()); | |||
1524 | ||||
1525 | WriteSecHdrEntry(ShStrTabBuilder.getOffset(Section.getSectionName()), | |||
1526 | Section.getType(), | |||
1527 | Section.getFlags(), 0, Offset, Size, sh_link, sh_info, | |||
1528 | Alignment, Section.getEntrySize()); | |||
1529 | } | |||
1530 | ||||
1531 | bool ELFObjectWriter::IsELFMetaDataSection(const MCSectionData &SD) { | |||
1532 | return SD.getOrdinal() == ~UINT32_C(0)0U && | |||
1533 | !SD.getSection().isVirtualSection(); | |||
1534 | } | |||
1535 | ||||
1536 | uint64_t ELFObjectWriter::DataSectionSize(const MCSectionData &SD) { | |||
1537 | uint64_t Ret = 0; | |||
1538 | for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; | |||
1539 | ++i) { | |||
1540 | const MCFragment &F = *i; | |||
1541 | assert(F.getKind() == MCFragment::FT_Data)((F.getKind() == MCFragment::FT_Data) ? static_cast<void> (0) : __assert_fail ("F.getKind() == MCFragment::FT_Data", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1541, __PRETTY_FUNCTION__)); | |||
1542 | Ret += cast<MCDataFragment>(F).getContents().size(); | |||
1543 | } | |||
1544 | return Ret; | |||
1545 | } | |||
1546 | ||||
1547 | uint64_t ELFObjectWriter::GetSectionAddressSize(const MCAsmLayout &Layout, | |||
1548 | const MCSectionData &SD) { | |||
1549 | if (IsELFMetaDataSection(SD)) | |||
1550 | return DataSectionSize(SD); | |||
1551 | return Layout.getSectionAddressSize(&SD); | |||
1552 | } | |||
1553 | ||||
1554 | void ELFObjectWriter::writeDataSectionData(MCAssembler &Asm, | |||
1555 | const MCAsmLayout &Layout, | |||
1556 | const MCSectionData &SD) { | |||
1557 | if (IsELFMetaDataSection(SD)) { | |||
1558 | for (MCSectionData::const_iterator i = SD.begin(), e = SD.end(); i != e; | |||
1559 | ++i) { | |||
1560 | const MCFragment &F = *i; | |||
1561 | assert(F.getKind() == MCFragment::FT_Data)((F.getKind() == MCFragment::FT_Data) ? static_cast<void> (0) : __assert_fail ("F.getKind() == MCFragment::FT_Data", "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1561, __PRETTY_FUNCTION__)); | |||
1562 | WriteBytes(cast<MCDataFragment>(F).getContents()); | |||
1563 | } | |||
1564 | } else { | |||
1565 | Asm.writeSectionData(&SD, Layout); | |||
1566 | } | |||
1567 | } | |||
1568 | ||||
1569 | void ELFObjectWriter::writeSectionHeader( | |||
1570 | ArrayRef<const MCSectionELF *> Sections, MCAssembler &Asm, | |||
1571 | const GroupMapTy &GroupMap, const MCAsmLayout &Layout, | |||
1572 | const SectionIndexMapTy &SectionIndexMap, | |||
1573 | const SectionOffsetMapTy &SectionOffsetMap) { | |||
1574 | const unsigned NumSections = Asm.size(); | |||
1575 | ||||
1576 | // Null section first. | |||
1577 | uint64_t FirstSectionSize = | |||
1578 | (NumSections + 1) >= ELF::SHN_LORESERVE ? NumSections + 1 : 0; | |||
1579 | uint32_t FirstSectionLink = | |||
1580 | ShstrtabIndex >= ELF::SHN_LORESERVE ? ShstrtabIndex : 0; | |||
1581 | WriteSecHdrEntry(0, 0, 0, 0, 0, FirstSectionSize, FirstSectionLink, 0, 0, 0); | |||
1582 | ||||
1583 | for (unsigned i = 0; i < NumSections; ++i) { | |||
1584 | const MCSectionELF &Section = *Sections[i]; | |||
1585 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1586 | uint32_t GroupSymbolIndex; | |||
1587 | if (Section.getType() != ELF::SHT_GROUP) | |||
1588 | GroupSymbolIndex = 0; | |||
1589 | else | |||
1590 | GroupSymbolIndex = getSymbolIndexInSymbolTable(Asm, | |||
1591 | GroupMap.lookup(&Section)); | |||
1592 | ||||
1593 | uint64_t Size = GetSectionAddressSize(Layout, SD); | |||
1594 | ||||
1595 | writeSection(Asm, SectionIndexMap, GroupSymbolIndex, | |||
1596 | SectionOffsetMap.lookup(&Section), Size, SD.getAlignment(), | |||
1597 | Section); | |||
1598 | } | |||
1599 | } | |||
1600 | ||||
1601 | void ELFObjectWriter::WriteObject(MCAssembler &Asm, | |||
1602 | const MCAsmLayout &Layout) { | |||
1603 | GroupMapTy GroupMap; | |||
1604 | RevGroupMapTy RevGroupMap; | |||
1605 | SectionIndexMapTy SectionIndexMap; | |||
1606 | ||||
1607 | CompressDebugSections(Asm, const_cast<MCAsmLayout &>(Layout)); | |||
1608 | createIndexedSections(Asm, const_cast<MCAsmLayout &>(Layout), GroupMap, | |||
1609 | RevGroupMap, SectionIndexMap); | |||
1610 | ||||
1611 | // Compute symbol table information. | |||
1612 | computeSymbolTable(Asm, Layout, SectionIndexMap, RevGroupMap); | |||
1613 | ||||
1614 | WriteRelocations(Asm, const_cast<MCAsmLayout &>(Layout)); | |||
1615 | ||||
1616 | CreateMetadataSections(const_cast<MCAssembler&>(Asm), | |||
1617 | const_cast<MCAsmLayout&>(Layout), | |||
1618 | SectionIndexMap); | |||
1619 | ||||
1620 | unsigned NumSections = Asm.size(); | |||
1621 | std::vector<const MCSectionELF*> Sections; | |||
1622 | Sections.resize(NumSections); | |||
1623 | ||||
1624 | for (auto &Pair : SectionIndexMap) | |||
1625 | Sections[Pair.second - 1] = Pair.first; | |||
1626 | ||||
1627 | SectionOffsetMapTy SectionOffsetMap; | |||
1628 | ||||
1629 | // Write out the ELF header ... | |||
1630 | WriteHeader(Asm, NumSections + 1); | |||
1631 | ||||
1632 | // ... then the sections ... | |||
1633 | for (unsigned i = 0; i < NumSections; ++i) { | |||
1634 | const MCSectionELF &Section = *Sections[i]; | |||
1635 | const MCSectionData &SD = Asm.getOrCreateSectionData(Section); | |||
1636 | uint64_t Padding = OffsetToAlignment(OS.tell(), SD.getAlignment()); | |||
1637 | WriteZeros(Padding); | |||
1638 | ||||
1639 | // Remember the offset into the file for this section. | |||
1640 | SectionOffsetMap[&Section] = OS.tell(); | |||
1641 | ||||
1642 | writeDataSectionData(Asm, Layout, SD); | |||
1643 | } | |||
1644 | ||||
1645 | uint64_t NaturalAlignment = is64Bit() ? 8 : 4; | |||
1646 | uint64_t Padding = OffsetToAlignment(OS.tell(), NaturalAlignment); | |||
1647 | WriteZeros(Padding); | |||
1648 | ||||
1649 | const unsigned SectionHeaderOffset = OS.tell(); | |||
1650 | ||||
1651 | // ... then the section header table ... | |||
1652 | writeSectionHeader(Sections, Asm, GroupMap, Layout, SectionIndexMap, | |||
1653 | SectionOffsetMap); | |||
1654 | ||||
1655 | if (is64Bit()) { | |||
1656 | uint64_t Val = SectionHeaderOffset; | |||
1657 | if (sys::IsLittleEndianHost != IsLittleEndian) | |||
1658 | sys::swapByteOrder(Val); | |||
1659 | OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), | |||
1660 | offsetof(ELF::Elf64_Ehdr, e_shoff)__builtin_offsetof(ELF::Elf64_Ehdr, e_shoff)); | |||
1661 | } else { | |||
1662 | uint32_t Val = SectionHeaderOffset; | |||
1663 | if (sys::IsLittleEndianHost != IsLittleEndian) | |||
1664 | sys::swapByteOrder(Val); | |||
1665 | OS.pwrite(reinterpret_cast<char *>(&Val), sizeof(Val), | |||
1666 | offsetof(ELF::Elf32_Ehdr, e_shoff)__builtin_offsetof(ELF::Elf32_Ehdr, e_shoff)); | |||
1667 | } | |||
1668 | } | |||
1669 | ||||
1670 | bool ELFObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl( | |||
1671 | const MCAssembler &Asm, const MCSymbolData &DataA, const MCFragment &FB, | |||
1672 | bool InSet, bool IsPCRel) const { | |||
1673 | if (IsPCRel) { | |||
1674 | assert(!InSet)((!InSet) ? static_cast<void> (0) : __assert_fail ("!InSet" , "/tmp/buildd/llvm-toolchain-snapshot-3.7~svn235822/lib/MC/ELFObjectWriter.cpp" , 1674, __PRETTY_FUNCTION__)); | |||
1675 | if (::isWeak(DataA)) | |||
1676 | return false; | |||
1677 | } | |||
1678 | return MCObjectWriter::IsSymbolRefDifferenceFullyResolvedImpl(Asm, DataA, FB, | |||
1679 | InSet, IsPCRel); | |||
1680 | } | |||
1681 | ||||
1682 | bool ELFObjectWriter::isWeak(const MCSymbolData &SD) const { | |||
1683 | if (::isWeak(SD)) | |||
1684 | return true; | |||
1685 | ||||
1686 | // It is invalid to replace a reference to a global in a comdat | |||
1687 | // with a reference to a local since out of comdat references | |||
1688 | // to a local are forbidden. | |||
1689 | // We could try to return false for more cases, like the reference | |||
1690 | // being in the same comdat or Sym being an alias to another global, | |||
1691 | // but it is not clear if it is worth the effort. | |||
1692 | if (MCELF::GetBinding(SD) != ELF::STB_GLOBAL) | |||
1693 | return false; | |||
1694 | ||||
1695 | const MCSymbol &Sym = SD.getSymbol(); | |||
1696 | if (!Sym.isInSection()) | |||
1697 | return false; | |||
1698 | ||||
1699 | const auto &Sec = cast<MCSectionELF>(Sym.getSection()); | |||
1700 | return Sec.getGroup(); | |||
1701 | } | |||
1702 | ||||
1703 | MCObjectWriter *llvm::createELFObjectWriter(MCELFObjectTargetWriter *MOTW, | |||
1704 | raw_pwrite_stream &OS, | |||
1705 | bool IsLittleEndian) { | |||
1706 | return new ELFObjectWriter(MOTW, OS, IsLittleEndian); | |||
1707 | } |