1 //===- lib/ReaderWriter/ELF/ELFFile.h -------------------------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #ifndef LLD_READER_WRITER_ELF_FILE_H
11 #define LLD_READER_WRITER_ELF_FILE_H
14 #include <llvm/ADT/MapVector.h>
16 #include <unordered_map>
21 /// \brief Read a binary, find out based on the symbol table contents what kind
22 /// of symbol it is and create corresponding atoms for it
23 template <class ELFT> class ELFFile : public File {
25 typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
26 typedef llvm::object::Elf_Shdr_Impl<ELFT> Elf_Shdr;
27 typedef llvm::object::Elf_Rel_Impl<ELFT, false> Elf_Rel;
28 typedef llvm::object::Elf_Rel_Impl<ELFT, true> Elf_Rela;
29 typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym_Iter Elf_Sym_Iter;
30 typedef typename llvm::object::ELFFile<ELFT>::Elf_Rela_Iter Elf_Rela_Iter;
31 typedef typename llvm::object::ELFFile<ELFT>::Elf_Rel_Iter Elf_Rel_Iter;
32 typedef typename llvm::object::ELFFile<ELFT>::Elf_Word Elf_Word;
34 // A Map is used to hold the atoms that have been divided up
35 // after reading the section that contains Merge String attributes
36 struct MergeSectionKey {
37 MergeSectionKey(const Elf_Shdr *shdr, int64_t offset)
38 : _shdr(shdr), _offset(offset) {}
40 const Elf_Shdr *_shdr;
43 struct MergeSectionEq {
44 int64_t operator()(const MergeSectionKey &k) const {
45 return llvm::hash_combine((int64_t)(k._shdr->sh_name),
48 bool operator()(const MergeSectionKey &lhs,
49 const MergeSectionKey &rhs) const {
50 return ((lhs._shdr->sh_name == rhs._shdr->sh_name) &&
51 (lhs._offset == rhs._offset));
56 MergeString(int64_t offset, StringRef str, const Elf_Shdr *shdr,
57 StringRef sectionName)
58 : _offset(offset), _string(str), _shdr(shdr),
59 _sectionName(sectionName) {}
60 // the offset of this atom
65 const Elf_Shdr *_shdr;
67 StringRef _sectionName;
70 // This is used to find the MergeAtom given a relocation
72 typedef std::vector<ELFMergeAtom<ELFT> *> MergeAtomsT;
74 /// \brief find a mergeAtom given a start offset
76 const Elf_Shdr *_shdr;
78 FindByOffset(const Elf_Shdr *shdr, int64_t offset)
79 : _shdr(shdr), _offset(offset) {}
80 bool operator()(const ELFMergeAtom<ELFT> *a) {
81 int64_t off = a->offset();
82 return (_shdr->sh_name == a->section()) &&
83 ((_offset >= off) && (_offset <= off + (int64_t)a->size()));
87 /// \brief find a merge atom given a offset
88 ELFMergeAtom<ELFT> *findMergeAtom(const Elf_Shdr *shdr, uint64_t offset) {
89 auto it = std::find_if(_mergeAtoms.begin(), _mergeAtoms.end(),
90 FindByOffset(shdr, offset));
91 assert(it != _mergeAtoms.end());
95 typedef std::unordered_map<MergeSectionKey, DefinedAtom *, MergeSectionEq,
96 MergeSectionEq> MergedSectionMapT;
97 typedef typename MergedSectionMapT::iterator MergedSectionMapIterT;
100 ELFFile(StringRef name, ELFLinkingContext &ctx)
101 : File(name, kindObject), _ordinal(0),
102 _doStringsMerge(ctx.mergeCommonStrings()), _useWrap(false), _ctx(ctx) {
103 setLastError(std::error_code());
106 ELFFile(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx)
107 : File(mb->getBufferIdentifier(), kindObject), _mb(std::move(mb)),
108 _ordinal(0), _doStringsMerge(ctx.mergeCommonStrings()),
109 _useWrap(ctx.wrapCalls().size()), _ctx(ctx) {}
111 static ErrorOr<std::unique_ptr<ELFFile>>
112 create(std::unique_ptr<MemoryBuffer> mb, ELFLinkingContext &ctx);
114 virtual Reference::KindArch kindArch();
116 /// \brief Create symbols from LinkingContext.
117 std::error_code createAtomsFromContext();
119 /// \brief Read input sections and populate necessary data structures
120 /// to read them later and create atoms
121 std::error_code createAtomizableSections();
123 /// \brief Create mergeable atoms from sections that have the merge attribute
125 std::error_code createMergeableAtoms();
127 /// \brief Add the symbols that the sections contain. The symbols will be
128 /// converted to atoms for
129 /// Undefined symbols, absolute symbols
130 std::error_code createSymbolsFromAtomizableSections();
132 /// \brief Create individual atoms
133 std::error_code createAtoms();
135 const atom_collection<DefinedAtom> &defined() const override {
136 return _definedAtoms;
139 const atom_collection<UndefinedAtom> &undefined() const override {
140 return _undefinedAtoms;
143 const atom_collection<SharedLibraryAtom> &sharedLibrary() const override {
144 return _sharedLibraryAtoms;
147 const atom_collection<AbsoluteAtom> &absolute() const override {
148 return _absoluteAtoms;
151 Atom *findAtom(const Elf_Sym *sourceSymbol, const Elf_Sym *targetSymbol) {
152 // All references to atoms inside a group are through undefined atoms.
153 Atom *targetAtom = _symbolToAtomMapping.lookup(targetSymbol);
154 StringRef targetSymbolName = targetAtom->name();
155 if (targetAtom->definition() != Atom::definitionRegular)
157 if ((llvm::dyn_cast<DefinedAtom>(targetAtom))->scope() ==
158 DefinedAtom::scopeTranslationUnit)
160 if (!redirectReferenceUsingUndefAtom(sourceSymbol, targetSymbol))
162 auto undefForGroupchild = _undefAtomsForGroupChild.find(targetSymbolName);
163 if (undefForGroupchild != _undefAtomsForGroupChild.end())
164 return undefForGroupchild->getValue();
165 auto undefGroupChildAtom =
166 new (_readerStorage) SimpleUndefinedAtom(*this, targetSymbolName);
167 _undefinedAtoms._atoms.push_back(undefGroupChildAtom);
168 return (_undefAtomsForGroupChild[targetSymbolName] = undefGroupChildAtom);
172 ELFDefinedAtom<ELFT> *createDefinedAtomAndAssignRelocations(
173 StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
174 const Elf_Shdr *section, ArrayRef<uint8_t> symContent,
175 ArrayRef<uint8_t> secContent);
177 std::error_code doParse() override;
179 /// \brief Iterate over Elf_Rela relocations list and create references.
180 virtual void createRelocationReferences(const Elf_Sym *symbol,
181 ArrayRef<uint8_t> content,
182 range<Elf_Rela_Iter> rels);
184 /// \brief Iterate over Elf_Rel relocations list and create references.
185 virtual void createRelocationReferences(const Elf_Sym *symbol,
186 ArrayRef<uint8_t> symContent,
187 ArrayRef<uint8_t> secContent,
188 range<Elf_Rel_Iter> rels);
190 /// \brief After all the Atoms and References are created, update each
191 /// Reference's target with the Atom pointer it refers to.
192 void updateReferences();
194 /// \brief Update the reference if the access corresponds to a merge string
196 void updateReferenceForMergeStringAccess(ELFReference<ELFT> *ref,
197 const Elf_Sym *symbol,
198 const Elf_Shdr *shdr);
200 /// \brief Do we want to ignore the section. Ignored sections are
201 /// not processed to create atoms
202 bool isIgnoredSection(const Elf_Shdr *section);
204 /// \brief Is the current section be treated as a mergeable string section.
205 /// The contents of a mergeable string section are null-terminated strings.
206 /// If the section have mergeable strings, the linker would need to split
207 /// the section into multiple atoms and mark them mergeByContent.
208 bool isMergeableStringSection(const Elf_Shdr *section);
210 /// \brief Returns a new anonymous atom whose size is equal to the
211 /// section size. That atom will be used to represent the entire
212 /// section that have no symbols.
213 ELFDefinedAtom<ELFT> *createSectionAtom(const Elf_Shdr *section,
214 StringRef sectionName,
215 ArrayRef<uint8_t> contents);
217 /// Returns the symbol's content size. The nextSymbol should be null if the
218 /// symbol is the last one in the section.
219 uint64_t symbolContentSize(const Elf_Shdr *section,
220 const Elf_Sym *symbol,
221 const Elf_Sym *nextSymbol);
223 void createEdge(ELFDefinedAtom<ELFT> *from, ELFDefinedAtom<ELFT> *to,
226 /// Get the section name for a section.
227 ErrorOr<StringRef> getSectionName(const Elf_Shdr *shdr) const {
230 return _objFile->getSectionName(shdr);
233 /// Determines if the section occupy memory space.
234 bool sectionOccupiesMemorySpace(const Elf_Shdr *shdr) const {
235 return (shdr->sh_type != llvm::ELF::SHT_NOBITS);
238 /// Return the section contents.
239 ErrorOr<ArrayRef<uint8_t>> getSectionContents(const Elf_Shdr *shdr) const {
240 if (!shdr || !sectionOccupiesMemorySpace(shdr))
241 return ArrayRef<uint8_t>();
242 return _objFile->getSectionContents(shdr);
245 /// Returns true if the symbol is a undefined symbol.
246 bool isUndefinedSymbol(const Elf_Sym *sym) const {
247 return (sym->st_shndx == llvm::ELF::SHN_UNDEF);
250 /// Determines if the target wants to create an atom for a section that has no
251 /// symbol references.
252 bool handleSectionWithNoSymbols(const Elf_Shdr *shdr,
253 std::vector<Elf_Sym_Iter> &syms) const {
254 return shdr && (shdr->sh_type == llvm::ELF::SHT_PROGBITS) && syms.empty();
257 /// Handle creation of atoms for .gnu.linkonce sections.
258 std::error_code handleGnuLinkOnceSection(
259 StringRef sectionName,
260 llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
261 const Elf_Shdr *shdr);
263 // Handle Section groups/COMDAT scetions.
264 std::error_code handleSectionGroup(
265 StringRef signature, StringRef groupSectionName,
266 llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
267 llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> &comdatSections,
268 const Elf_Shdr *shdr);
270 /// Process the Undefined symbol and create an atom for it.
271 ErrorOr<ELFUndefinedAtom<ELFT> *>
272 handleUndefinedSymbol(StringRef symName, const Elf_Sym *sym) {
273 return new (_readerStorage) ELFUndefinedAtom<ELFT>(*this, symName, sym);
276 /// Returns true if the symbol is a absolute symbol.
277 bool isAbsoluteSymbol(const Elf_Sym *sym) const {
278 return (sym->st_shndx == llvm::ELF::SHN_ABS);
281 /// Process the Absolute symbol and create an atom for it.
282 ErrorOr<ELFAbsoluteAtom<ELFT> *>
283 handleAbsoluteSymbol(StringRef symName, const Elf_Sym *sym, int64_t value) {
284 return new (_readerStorage)
285 ELFAbsoluteAtom<ELFT>(*this, symName, sym, value);
288 /// Returns true if the symbol is common symbol. A common symbol represents a
289 /// tentive definition in C. It has name, size and alignment constraint, but
290 /// actual storage has not yet been allocated. (The linker will allocate
291 /// storage for them in the later pass after coalescing tentative symbols by
293 virtual bool isCommonSymbol(const Elf_Sym *symbol) const {
294 return symbol->getType() == llvm::ELF::STT_COMMON ||
295 symbol->st_shndx == llvm::ELF::SHN_COMMON;
298 /// Returns true if the section is a gnulinkonce section.
299 bool isGnuLinkOnceSection(StringRef sectionName) const {
300 return sectionName.startswith(".gnu.linkonce.");
303 /// Returns true if the section is a COMDAT group section.
304 bool isGroupSection(const Elf_Shdr *shdr) const {
305 return (shdr->sh_type == llvm::ELF::SHT_GROUP);
308 /// Returns true if the section is a member of some group.
309 bool isSectionMemberOfGroup(const Elf_Shdr *shdr) const {
310 return (shdr->sh_flags & llvm::ELF::SHF_GROUP);
313 /// Returns correct st_value for the symbol depending on the architecture.
314 /// For most architectures it's just a regular st_value with no changes.
315 virtual uint64_t getSymbolValue(const Elf_Sym *symbol) const {
316 return symbol->st_value;
319 /// Process the common symbol and create an atom for it.
320 virtual ErrorOr<ELFCommonAtom<ELFT> *>
321 handleCommonSymbol(StringRef symName, const Elf_Sym *sym) {
322 return new (_readerStorage) ELFCommonAtom<ELFT>(*this, symName, sym);
325 /// Returns true if the symbol is a defined symbol.
326 virtual bool isDefinedSymbol(const Elf_Sym *sym) const {
327 return (sym->getType() == llvm::ELF::STT_NOTYPE ||
328 sym->getType() == llvm::ELF::STT_OBJECT ||
329 sym->getType() == llvm::ELF::STT_FUNC ||
330 sym->getType() == llvm::ELF::STT_GNU_IFUNC ||
331 sym->getType() == llvm::ELF::STT_SECTION ||
332 sym->getType() == llvm::ELF::STT_FILE ||
333 sym->getType() == llvm::ELF::STT_TLS);
336 /// Process the Defined symbol and create an atom for it.
337 virtual ErrorOr<ELFDefinedAtom<ELFT> *>
338 handleDefinedSymbol(StringRef symName, StringRef sectionName,
339 const Elf_Sym *sym, const Elf_Shdr *sectionHdr,
340 ArrayRef<uint8_t> contentData,
341 unsigned int referenceStart, unsigned int referenceEnd,
342 std::vector<ELFReference<ELFT> *> &referenceList) {
343 return new (_readerStorage) ELFDefinedAtom<ELFT>(
344 *this, symName, sectionName, sym, sectionHdr, contentData,
345 referenceStart, referenceEnd, referenceList);
348 /// Process the Merge string and create an atom for it.
349 ErrorOr<ELFMergeAtom<ELFT> *>
350 handleMergeString(StringRef sectionName, const Elf_Shdr *sectionHdr,
351 ArrayRef<uint8_t> contentData, unsigned int offset) {
352 ELFMergeAtom<ELFT> *mergeAtom = new (_readerStorage)
353 ELFMergeAtom<ELFT>(*this, sectionName, sectionHdr, contentData, offset);
354 const MergeSectionKey mergedSectionKey(sectionHdr, offset);
355 if (_mergedSectionMap.find(mergedSectionKey) == _mergedSectionMap.end())
356 _mergedSectionMap.insert(std::make_pair(mergedSectionKey, mergeAtom));
360 /// References to the sections comprising a group, from sections
361 /// outside the group, must be made via global UNDEF symbols,
362 /// referencing global symbols defined as addresses in the group
363 /// sections. They may not reference local symbols for addresses in
364 /// the group's sections, including section symbols.
365 /// ABI Doc : https://mentorembedded.github.io/cxx-abi/abi/prop-72-comdat.html
366 /// Does the atom need to be redirected using a separate undefined atom?
367 bool redirectReferenceUsingUndefAtom(const Elf_Sym *sourceSymbol,
368 const Elf_Sym *targetSymbol) const;
370 void addReferenceToSymbol(const ELFReference<ELFT> *r, const Elf_Sym *sym) {
371 _referenceToSymbol[r] = sym;
374 const Elf_Sym *findSymbolForReference(const ELFReference<ELFT> *r) const {
375 auto elfReferenceToSymbol = _referenceToSymbol.find(r);
376 if (elfReferenceToSymbol != _referenceToSymbol.end())
377 return elfReferenceToSymbol->second;
381 llvm::BumpPtrAllocator _readerStorage;
382 std::unique_ptr<llvm::object::ELFFile<ELFT> > _objFile;
383 atom_collection_vector<DefinedAtom> _definedAtoms;
384 atom_collection_vector<UndefinedAtom> _undefinedAtoms;
385 atom_collection_vector<SharedLibraryAtom> _sharedLibraryAtoms;
386 atom_collection_vector<AbsoluteAtom> _absoluteAtoms;
388 /// \brief _relocationAddendReferences and _relocationReferences contain the
389 /// list of relocations references. In ELF, if a section named, ".text" has
390 /// relocations will also have a section named ".rel.text" or ".rela.text"
391 /// which will hold the entries.
392 std::unordered_map<StringRef, range<Elf_Rela_Iter>>
393 _relocationAddendReferences;
394 MergedSectionMapT _mergedSectionMap;
395 std::unordered_map<StringRef, range<Elf_Rel_Iter>> _relocationReferences;
396 std::vector<ELFReference<ELFT> *> _references;
397 llvm::DenseMap<const Elf_Sym *, Atom *> _symbolToAtomMapping;
398 llvm::DenseMap<const ELFReference<ELFT> *, const Elf_Sym *>
400 // Group child atoms have a pair corresponding to the signature and the
401 // section header of the section that was used for generating the signature.
402 llvm::DenseMap<const Elf_Sym *, std::pair<StringRef, const Elf_Shdr *>>
404 llvm::StringMap<Atom *> _undefAtomsForGroupChild;
406 /// \brief Atoms that are created for a section that has the merge property
408 MergeAtomsT _mergeAtoms;
410 /// \brief the section and the symbols that are contained within it to create
411 /// used to create atoms
412 llvm::MapVector<const Elf_Shdr *, std::vector<Elf_Sym_Iter>> _sectionSymbols;
414 /// \brief Sections that have merge string property
415 std::vector<const Elf_Shdr *> _mergeStringSections;
417 std::unique_ptr<MemoryBuffer> _mb;
420 /// \brief the cached options relevant while reading the ELF File
421 bool _doStringsMerge;
423 /// \brief Is --wrap on?
426 /// \brief The LinkingContext.
427 ELFLinkingContext &_ctx;
430 llvm::StringMap<UndefinedAtom *> _wrapSymbolMap;
433 /// \brief All atoms are owned by a File. To add linker specific atoms
434 /// the atoms need to be inserted to a file called (RuntimeFile) which
435 /// are basically additional symbols required by libc and other runtime
436 /// libraries part of executing a program. This class provides support
437 /// for adding absolute symbols and undefined symbols
438 template <class ELFT> class RuntimeFile : public ELFFile<ELFT> {
440 typedef llvm::object::Elf_Sym_Impl<ELFT> Elf_Sym;
441 RuntimeFile(ELFLinkingContext &context, StringRef name)
442 : ELFFile<ELFT>(name, context) {}
444 /// \brief add a global absolute atom
445 virtual Atom *addAbsoluteAtom(StringRef symbolName) {
446 assert(!symbolName.empty() && "AbsoluteAtoms must have a name");
447 Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
449 symbol->st_value = 0;
450 symbol->st_shndx = llvm::ELF::SHN_ABS;
451 symbol->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_OBJECT);
452 symbol->setVisibility(llvm::ELF::STV_DEFAULT);
454 auto newAtom = this->handleAbsoluteSymbol(symbolName, symbol, -1);
455 this->_absoluteAtoms._atoms.push_back(*newAtom);
459 /// \brief add an undefined atom
460 virtual Atom *addUndefinedAtom(StringRef symbolName) {
461 assert(!symbolName.empty() && "UndefinedAtoms must have a name");
462 Elf_Sym *symbol = new (this->_readerStorage) Elf_Sym;
464 symbol->st_value = 0;
465 symbol->st_shndx = llvm::ELF::SHN_UNDEF;
466 symbol->setBindingAndType(llvm::ELF::STB_GLOBAL, llvm::ELF::STT_NOTYPE);
467 symbol->setVisibility(llvm::ELF::STV_DEFAULT);
469 auto newAtom = this->handleUndefinedSymbol(symbolName, symbol);
470 this->_undefinedAtoms._atoms.push_back(*newAtom);
474 // cannot add atoms to Runtime file
475 virtual void addAtom(const Atom &) {
476 llvm_unreachable("cannot add atoms to Runtime files");
480 template <class ELFT>
481 ErrorOr<std::unique_ptr<ELFFile<ELFT>>>
482 ELFFile<ELFT>::create(std::unique_ptr<MemoryBuffer> mb,
483 ELFLinkingContext &ctx) {
484 std::unique_ptr<ELFFile<ELFT>> file(new ELFFile<ELFT>(std::move(mb), ctx));
485 return std::move(file);
488 template <class ELFT>
489 std::error_code ELFFile<ELFT>::doParse() {
491 _objFile.reset(new llvm::object::ELFFile<ELFT>(_mb->getBuffer(), ec));
495 if ((ec = createAtomsFromContext()))
498 // Read input sections from the input file that need to be converted to
500 if ((ec = createAtomizableSections()))
503 // For mergeable strings, we would need to split the section into various
505 if ((ec = createMergeableAtoms()))
508 // Create the necessary symbols that are part of the section that we
509 // created in createAtomizableSections function
510 if ((ec = createSymbolsFromAtomizableSections()))
513 // Create the appropriate atoms from the file
514 if ((ec = createAtoms()))
516 return std::error_code();
519 template <class ELFT> Reference::KindArch ELFFile<ELFT>::kindArch() {
520 switch (_objFile->getHeader()->e_machine) {
521 case llvm::ELF::EM_X86_64:
522 return Reference::KindArch::x86_64;
523 case llvm::ELF::EM_386:
524 return Reference::KindArch::x86;
525 case llvm::ELF::EM_ARM:
526 return Reference::KindArch::ARM;
527 case llvm::ELF::EM_HEXAGON:
528 return Reference::KindArch::Hexagon;
529 case llvm::ELF::EM_MIPS:
530 return Reference::KindArch::Mips;
531 case llvm::ELF::EM_AARCH64:
532 return Reference::KindArch::AArch64;
534 llvm_unreachable("unsupported e_machine value");
537 template <class ELFT>
538 std::error_code ELFFile<ELFT>::createAtomizableSections() {
539 // Handle: SHT_REL and SHT_RELA sections:
540 // Increment over the sections, when REL/RELA section types are found add
541 // the contents to the RelocationReferences map.
542 // Record the number of relocs to guess at preallocating the buffer.
543 uint64_t totalRelocs = 0;
544 for (const Elf_Shdr §ion : _objFile->sections()) {
545 if (isIgnoredSection(§ion))
548 if (isMergeableStringSection(§ion)) {
549 _mergeStringSections.push_back(§ion);
553 if (section.sh_type == llvm::ELF::SHT_RELA) {
554 auto sHdr = _objFile->getSection(section.sh_info);
556 auto sectionName = _objFile->getSectionName(sHdr);
557 if (std::error_code ec = sectionName.getError())
560 auto rai(_objFile->begin_rela(§ion));
561 auto rae(_objFile->end_rela(§ion));
563 _relocationAddendReferences[*sectionName] = make_range(rai, rae);
564 totalRelocs += std::distance(rai, rae);
565 } else if (section.sh_type == llvm::ELF::SHT_REL) {
566 auto sHdr = _objFile->getSection(section.sh_info);
568 auto sectionName = _objFile->getSectionName(sHdr);
569 if (std::error_code ec = sectionName.getError())
572 auto ri(_objFile->begin_rel(§ion));
573 auto re(_objFile->end_rel(§ion));
575 _relocationReferences[*sectionName] = make_range(ri, re);
576 totalRelocs += std::distance(ri, re);
578 _sectionSymbols[§ion];
581 _references.reserve(totalRelocs);
582 return std::error_code();
585 template <class ELFT> std::error_code ELFFile<ELFT>::createMergeableAtoms() {
586 // Divide the section that contains mergeable strings into tokens
588 // a) add resolver support to recognize multibyte chars
589 // b) Create a separate section chunk to write mergeable atoms
590 std::vector<MergeString *> tokens;
591 for (const Elf_Shdr *msi : _mergeStringSections) {
592 auto sectionName = getSectionName(msi);
593 if (std::error_code ec = sectionName.getError())
596 auto sectionContents = getSectionContents(msi);
597 if (std::error_code ec = sectionContents.getError())
600 StringRef secCont(reinterpret_cast<const char *>(sectionContents->begin()),
601 sectionContents->size());
603 unsigned int prev = 0;
604 for (std::size_t i = 0, e = sectionContents->size(); i != e; ++i) {
605 if ((*sectionContents)[i] == '\0') {
606 tokens.push_back(new (_readerStorage) MergeString(
607 prev, secCont.slice(prev, i + 1), msi, *sectionName));
613 // Create Mergeable atoms
614 for (const MergeString *tai : tokens) {
615 ArrayRef<uint8_t> content((const uint8_t *)tai->_string.data(),
616 tai->_string.size());
617 ErrorOr<ELFMergeAtom<ELFT> *> mergeAtom =
618 handleMergeString(tai->_sectionName, tai->_shdr, content, tai->_offset);
619 (*mergeAtom)->setOrdinal(++_ordinal);
620 _definedAtoms._atoms.push_back(*mergeAtom);
621 _mergeAtoms.push_back(*mergeAtom);
623 return std::error_code();
626 template <class ELFT>
627 std::error_code ELFFile<ELFT>::createSymbolsFromAtomizableSections() {
628 // Increment over all the symbols collecting atoms and symbol names for
630 auto SymI = _objFile->begin_symbols(), SymE = _objFile->end_symbols();
632 // Skip over dummy sym.
636 for (; SymI != SymE; ++SymI) {
637 const Elf_Shdr *section = _objFile->getSection(&*SymI);
639 auto symbolName = _objFile->getSymbolName(SymI);
640 if (std::error_code ec = symbolName.getError())
643 if (isAbsoluteSymbol(&*SymI)) {
644 ErrorOr<ELFAbsoluteAtom<ELFT> *> absAtom =
645 handleAbsoluteSymbol(*symbolName, &*SymI, (int64_t)getSymbolValue(&*SymI));
646 _absoluteAtoms._atoms.push_back(*absAtom);
647 _symbolToAtomMapping.insert(std::make_pair(&*SymI, *absAtom));
648 } else if (isUndefinedSymbol(&*SymI)) {
650 (_wrapSymbolMap.find(*symbolName) != _wrapSymbolMap.end())) {
651 auto wrapAtom = _wrapSymbolMap.find(*symbolName);
652 _symbolToAtomMapping.insert(
653 std::make_pair(&*SymI, wrapAtom->getValue()));
656 ErrorOr<ELFUndefinedAtom<ELFT> *> undefAtom =
657 handleUndefinedSymbol(*symbolName, &*SymI);
658 _undefinedAtoms._atoms.push_back(*undefAtom);
659 _symbolToAtomMapping.insert(std::make_pair(&*SymI, *undefAtom));
660 } else if (isCommonSymbol(&*SymI)) {
661 ErrorOr<ELFCommonAtom<ELFT> *> commonAtom =
662 handleCommonSymbol(*symbolName, &*SymI);
663 (*commonAtom)->setOrdinal(++_ordinal);
664 _definedAtoms._atoms.push_back(*commonAtom);
665 _symbolToAtomMapping.insert(std::make_pair(&*SymI, *commonAtom));
666 } else if (isDefinedSymbol(&*SymI)) {
667 _sectionSymbols[section].push_back(SymI);
669 llvm::errs() << "Unable to create atom for: " << *symbolName << "\n";
670 return llvm::object::object_error::parse_failed;
674 return std::error_code();
677 template <class ELFT> std::error_code ELFFile<ELFT>::createAtoms() {
678 // Holds all the atoms that are part of the section. They are the targets of
679 // the kindGroupChild reference.
680 llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> atomsForSection;
681 // group sections have a mapping of the section header to the
682 // signature/section.
683 llvm::DenseMap<const Elf_Shdr *, std::pair<StringRef, StringRef>>
685 // Contains a list of comdat sections for a group.
686 llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> comdatSections;
687 for (auto &i : _sectionSymbols) {
688 const Elf_Shdr *section = i.first;
689 std::vector<Elf_Sym_Iter> &symbols = i.second;
691 // Sort symbols by position.
692 std::stable_sort(symbols.begin(), symbols.end(),
693 [this](Elf_Sym_Iter a, Elf_Sym_Iter b) {
694 return getSymbolValue(&*a) < getSymbolValue(&*b);
697 ErrorOr<StringRef> sectionName = this->getSectionName(section);
698 if (std::error_code ec = sectionName.getError())
701 auto sectionContents = getSectionContents(section);
702 if (std::error_code ec = sectionContents.getError())
705 bool addAtoms = true;
707 // A section of type SHT_GROUP defines a grouping of sections. The name of a
708 // symbol from one of the containing object's symbol tables provides a
710 // for the section group. The section header of the SHT_GROUP section
712 // the identifying symbol entry, as described : the sh_link member contains
713 // the section header index of the symbol table section that contains the
715 // The sh_info member contains the symbol table index of the identifying
717 // The sh_flags member of the section header contains 0. The name of the
719 // (sh_name) is not specified.
720 if (isGroupSection(section)) {
721 const Elf_Word *groupMembers =
722 reinterpret_cast<const Elf_Word *>(sectionContents->data());
723 const long count = (section->sh_size) / sizeof(Elf_Word);
724 for (int i = 1; i < count; i++) {
725 const Elf_Shdr *sHdr = _objFile->getSection(groupMembers[i]);
726 ErrorOr<StringRef> sectionName = _objFile->getSectionName(sHdr);
727 if (std::error_code ec = sectionName.getError())
729 comdatSections[section].push_back(*sectionName);
731 const Elf_Sym *symbol = _objFile->getSymbol(section->sh_info);
732 const Elf_Shdr *symtab = _objFile->getSection(section->sh_link);
733 ErrorOr<StringRef> symbolName = _objFile->getSymbolName(symtab, symbol);
734 if (std::error_code ec = symbolName.getError())
736 groupSections.insert(
737 std::make_pair(section, std::make_pair(*symbolName, *sectionName)));
741 if (isGnuLinkOnceSection(*sectionName)) {
742 groupSections.insert(
743 std::make_pair(section, std::make_pair(*sectionName, *sectionName)));
747 if (isSectionMemberOfGroup(section))
750 if (handleSectionWithNoSymbols(section, symbols)) {
751 ELFDefinedAtom<ELFT> *newAtom =
752 createSectionAtom(section, *sectionName, *sectionContents);
753 newAtom->setOrdinal(++_ordinal);
755 _definedAtoms._atoms.push_back(newAtom);
757 atomsForSection[*sectionName].push_back(newAtom);
761 ELFDefinedAtom<ELFT> *previousAtom = nullptr;
762 ELFReference<ELFT> *anonFollowedBy = nullptr;
764 for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
766 StringRef symbolName = "";
767 if (symbol->getType() != llvm::ELF::STT_SECTION) {
768 auto symName = _objFile->getSymbolName(symbol);
769 if (std::error_code ec = symName.getError())
771 symbolName = *symName;
774 uint64_t contentSize = symbolContentSize(
775 section, &*symbol, (si + 1 == se) ? nullptr : &**(si + 1));
777 // Check to see if we need to add the FollowOn Reference
778 ELFReference<ELFT> *followOn = nullptr;
780 // Replace the followon atom with the anonymous atom that we created,
781 // so that the next symbol that we create is a followon from the
783 if (anonFollowedBy) {
784 followOn = anonFollowedBy;
786 followOn = new (_readerStorage)
787 ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
788 previousAtom->addReference(followOn);
792 ArrayRef<uint8_t> symbolData((const uint8_t *)sectionContents->data() +
793 getSymbolValue(&*symbol),
796 // If the linker finds that a section has global atoms that are in a
797 // mergeable section, treat them as defined atoms as they shouldn't be
798 // merged away as well as these symbols have to be part of symbol
800 if (isMergeableStringSection(section)) {
801 if (symbol->getBinding() == llvm::ELF::STB_GLOBAL) {
802 auto definedMergeAtom = handleDefinedSymbol(
803 symbolName, *sectionName, &**si, section, symbolData,
804 _references.size(), _references.size(), _references);
805 (*definedMergeAtom)->setOrdinal(++_ordinal);
807 _definedAtoms._atoms.push_back(*definedMergeAtom);
809 atomsForSection[*sectionName].push_back(*definedMergeAtom);
814 // Don't allocate content to a weak symbol, as they may be merged away.
815 // Create an anonymous atom to hold the data.
816 ELFDefinedAtom<ELFT> *anonAtom = nullptr;
817 anonFollowedBy = nullptr;
818 if (symbol->getBinding() == llvm::ELF::STB_WEAK) {
819 // Create anonymous new non-weak ELF symbol that holds the symbol
821 auto sym = new (_readerStorage) Elf_Sym(*symbol);
822 sym->setBinding(llvm::ELF::STB_GLOBAL);
823 anonAtom = createDefinedAtomAndAssignRelocations(
824 "", *sectionName, sym, section, symbolData, *sectionContents);
825 symbolData = ArrayRef<uint8_t>();
827 // If this is the last atom, let's not create a followon reference.
828 if (anonAtom && (si + 1) != se) {
829 anonFollowedBy = new (_readerStorage)
830 ELFReference<ELFT>(lld::Reference::kindLayoutAfter);
831 anonAtom->addReference(anonFollowedBy);
835 ELFDefinedAtom<ELFT> *newAtom = createDefinedAtomAndAssignRelocations(
836 symbolName, *sectionName, &*symbol, section, symbolData,
838 newAtom->setOrdinal(++_ordinal);
840 // If the atom was a weak symbol, let's create a followon reference to
841 // the anonymous atom that we created.
843 createEdge(newAtom, anonAtom, Reference::kindLayoutAfter);
846 // Set the followon atom to the weak atom that we have created, so
847 // that they would alias when the file gets written.
848 followOn->setTarget(anonAtom ? anonAtom : newAtom);
851 // The previous atom is always the atom created before unless the atom
853 previousAtom = anonAtom ? anonAtom : newAtom;
856 _definedAtoms._atoms.push_back(newAtom);
858 atomsForSection[*sectionName].push_back(newAtom);
860 _symbolToAtomMapping.insert(std::make_pair(&*symbol, newAtom));
862 anonAtom->setOrdinal(++_ordinal);
864 _definedAtoms._atoms.push_back(anonAtom);
866 atomsForSection[*sectionName].push_back(anonAtom);
871 // Iterate over all the group sections to create parent atoms pointing to
872 // group-child atoms.
873 for (auto § : groupSections) {
874 StringRef signature = sect.second.first;
875 StringRef groupSectionName = sect.second.second;
876 if (isGnuLinkOnceSection(signature))
877 handleGnuLinkOnceSection(signature, atomsForSection, sect.first);
878 else if (isGroupSection(sect.first))
879 handleSectionGroup(signature, groupSectionName, atomsForSection,
880 comdatSections, sect.first);
884 return std::error_code();
887 template <class ELFT>
888 std::error_code ELFFile<ELFT>::handleGnuLinkOnceSection(
890 llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
891 const Elf_Shdr *shdr) {
892 // TODO: Check for errors.
893 unsigned int referenceStart = _references.size();
894 std::vector<ELFReference<ELFT> *> refs;
895 for (auto ha : atomsForSection[signature]) {
896 _groupChild[ha->symbol()] = std::make_pair(signature, shdr);
897 ELFReference<ELFT> *ref =
898 new (_readerStorage) ELFReference<ELFT>(lld::Reference::kindGroupChild);
902 atomsForSection[signature].clear();
903 // Create a gnu linkonce atom.
904 auto gnuLinkOnceAtom = handleDefinedSymbol(
905 signature, signature, nullptr, shdr, ArrayRef<uint8_t>(), referenceStart,
906 _references.size(), _references);
907 (*gnuLinkOnceAtom)->setOrdinal(++_ordinal);
908 _definedAtoms._atoms.push_back(*gnuLinkOnceAtom);
909 for (auto reference : refs)
910 (*gnuLinkOnceAtom)->addReference(reference);
911 return std::error_code();
914 template <class ELFT>
915 std::error_code ELFFile<ELFT>::handleSectionGroup(
916 StringRef signature, StringRef groupSectionName,
917 llvm::StringMap<std::vector<ELFDefinedAtom<ELFT> *>> &atomsForSection,
918 llvm::DenseMap<const Elf_Shdr *, std::vector<StringRef>> &comdatSections,
919 const Elf_Shdr *shdr) {
920 // TODO: Check for errors.
921 unsigned int referenceStart = _references.size();
922 std::vector<ELFReference<ELFT> *> refs;
923 auto sectionNamesInGroup = comdatSections[shdr];
924 for (auto sectionName : sectionNamesInGroup) {
925 for (auto ha : atomsForSection[sectionName]) {
926 _groupChild[ha->symbol()] = std::make_pair(signature, shdr);
927 ELFReference<ELFT> *ref = new (_readerStorage)
928 ELFReference<ELFT>(lld::Reference::kindGroupChild);
932 atomsForSection[sectionName].clear();
934 // Create a gnu linkonce atom.
935 auto sectionGroupAtom = handleDefinedSymbol(
936 signature, groupSectionName, nullptr, shdr, ArrayRef<uint8_t>(),
937 referenceStart, _references.size(), _references);
938 (*sectionGroupAtom)->setOrdinal(++_ordinal);
939 _definedAtoms._atoms.push_back(*sectionGroupAtom);
940 for (auto reference : refs)
941 (*sectionGroupAtom)->addReference(reference);
942 return std::error_code();
945 template <class ELFT> std::error_code ELFFile<ELFT>::createAtomsFromContext() {
947 return std::error_code();
949 // a) Create an undefined atom for the symbol specified by the --wrap option,
951 // may be needed to be pulled from an archive.
952 // b) Create an undefined atom for __wrap_<symbolname>.
953 // c) All references to the symbol specified by wrap should point to
954 // __wrap_<symbolname>
955 // d) All references to __real_symbol should point to the <symbol>
956 for (auto &wrapsym : _ctx.wrapCalls()) {
957 StringRef wrapStr = wrapsym.getKey();
958 // Create a undefined symbol fror the wrap symbol.
959 UndefinedAtom *wrapSymAtom =
960 new (_readerStorage) SimpleUndefinedAtom(*this, wrapStr);
961 StringRef wrapCallSym =
962 _ctx.allocateString((llvm::Twine("__wrap_") + wrapStr).str());
963 StringRef realCallSym =
964 _ctx.allocateString((llvm::Twine("__real_") + wrapStr).str());
965 UndefinedAtom *wrapCallAtom =
966 new (_readerStorage) SimpleUndefinedAtom(*this, wrapCallSym);
967 // Create maps, when there is call to sym, it should point to wrapCallSym.
968 _wrapSymbolMap.insert(std::make_pair(wrapStr, wrapCallAtom));
969 // Whenever there is a reference to realCall it should point to the symbol
970 // created for each wrap usage.
971 _wrapSymbolMap.insert(std::make_pair(realCallSym, wrapSymAtom));
972 _undefinedAtoms._atoms.push_back(wrapSymAtom);
973 _undefinedAtoms._atoms.push_back(wrapCallAtom);
975 return std::error_code();
978 template <class ELFT>
979 ELFDefinedAtom<ELFT> *ELFFile<ELFT>::createDefinedAtomAndAssignRelocations(
980 StringRef symbolName, StringRef sectionName, const Elf_Sym *symbol,
981 const Elf_Shdr *section, ArrayRef<uint8_t> symContent,
982 ArrayRef<uint8_t> secContent) {
983 unsigned int referenceStart = _references.size();
985 // Add Rela (those with r_addend) references:
986 auto rari = _relocationAddendReferences.find(sectionName);
987 if (rari != _relocationAddendReferences.end())
988 createRelocationReferences(symbol, symContent, rari->second);
990 // Add Rel references.
991 auto rri = _relocationReferences.find(sectionName);
992 if (rri != _relocationReferences.end())
993 createRelocationReferences(symbol, symContent, secContent, rri->second);
995 // Create the DefinedAtom and add it to the list of DefinedAtoms.
996 return *handleDefinedSymbol(symbolName, sectionName, symbol, section,
997 symContent, referenceStart, _references.size(),
1001 template <class ELFT>
1002 void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
1003 ArrayRef<uint8_t> content,
1004 range<Elf_Rela_Iter> rels) {
1005 bool isMips64EL = _objFile->isMips64EL();
1006 const auto symValue = getSymbolValue(symbol);
1007 for (const auto &rel : rels) {
1008 if (rel.r_offset < symValue ||
1009 symValue + content.size() <= rel.r_offset)
1011 auto elfRelocation = new (_readerStorage)
1012 ELFReference<ELFT>(&rel, rel.r_offset - symValue, kindArch(),
1013 rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
1014 addReferenceToSymbol(elfRelocation, symbol);
1015 _references.push_back(elfRelocation);
1019 template <class ELFT>
1020 void ELFFile<ELFT>::createRelocationReferences(const Elf_Sym *symbol,
1021 ArrayRef<uint8_t> symContent,
1022 ArrayRef<uint8_t> secContent,
1023 range<Elf_Rel_Iter> rels) {
1024 bool isMips64EL = _objFile->isMips64EL();
1025 const auto symValue = getSymbolValue(symbol);
1026 for (const auto &rel : rels) {
1027 if (rel.r_offset < symValue ||
1028 symValue + symContent.size() <= rel.r_offset)
1030 auto elfRelocation = new (_readerStorage)
1031 ELFReference<ELFT>(rel.r_offset - symValue, kindArch(),
1032 rel.getType(isMips64EL), rel.getSymbol(isMips64EL));
1033 int32_t addend = *(symContent.data() + rel.r_offset - symValue);
1034 elfRelocation->setAddend(addend);
1035 addReferenceToSymbol(elfRelocation, symbol);
1036 _references.push_back(elfRelocation);
1040 template <class ELFT>
1041 void ELFFile<ELFT>::updateReferenceForMergeStringAccess(ELFReference<ELFT> *ref,
1042 const Elf_Sym *symbol,
1043 const Elf_Shdr *shdr) {
1044 // If the target atom is mergeable strefng atom, the atom might have been
1045 // merged with other atom having the same contents. Try to find the
1046 // merged one if that's the case.
1047 int64_t addend = ref->addend();
1051 const MergeSectionKey ms(shdr, addend);
1052 auto msec = _mergedSectionMap.find(ms);
1053 if (msec != _mergedSectionMap.end()) {
1054 ref->setTarget(msec->second);
1058 // The target atom was not merged. Mergeable atoms are not in
1059 // _symbolToAtomMapping, so we cannot find it by calling findAtom(). We
1060 // instead call findMergeAtom().
1061 if (symbol->getType() != llvm::ELF::STT_SECTION)
1062 addend = getSymbolValue(symbol) + addend;
1063 ELFMergeAtom<ELFT> *mergedAtom = findMergeAtom(shdr, addend);
1064 ref->setOffset(addend - mergedAtom->offset());
1066 ref->setTarget(mergedAtom);
1069 template <class ELFT> void ELFFile<ELFT>::updateReferences() {
1070 for (auto &ri : _references) {
1071 if (ri->kindNamespace() != lld::Reference::KindNamespace::ELF)
1073 const Elf_Sym *symbol = _objFile->getSymbol(ri->targetSymbolIndex());
1074 const Elf_Shdr *shdr = _objFile->getSection(symbol);
1076 // If the atom is not in mergeable string section, the target atom is
1077 // simply that atom.
1078 if (isMergeableStringSection(shdr))
1079 updateReferenceForMergeStringAccess(ri, symbol, shdr);
1081 ri->setTarget(findAtom(findSymbolForReference(ri), symbol));
1085 template <class ELFT>
1086 bool ELFFile<ELFT>::isIgnoredSection(const Elf_Shdr *section) {
1087 switch (section->sh_type) {
1088 case llvm::ELF::SHT_NULL:
1089 case llvm::ELF::SHT_STRTAB:
1090 case llvm::ELF::SHT_SYMTAB:
1091 case llvm::ELF::SHT_SYMTAB_SHNDX:
1099 template <class ELFT>
1100 bool ELFFile<ELFT>::isMergeableStringSection(const Elf_Shdr *section) {
1101 if (_doStringsMerge && section) {
1102 int64_t sectionFlags = section->sh_flags;
1103 sectionFlags &= ~llvm::ELF::SHF_ALLOC;
1104 // Mergeable string sections have both SHF_MERGE and SHF_STRINGS flags
1105 // set. sh_entsize is the size of each character which is normally 1.
1106 if ((section->sh_entsize < 2) &&
1107 (sectionFlags == (llvm::ELF::SHF_MERGE | llvm::ELF::SHF_STRINGS))) {
1114 template <class ELFT>
1115 ELFDefinedAtom<ELFT> *
1116 ELFFile<ELFT>::createSectionAtom(const Elf_Shdr *section, StringRef sectionName,
1117 ArrayRef<uint8_t> content) {
1118 Elf_Sym *sym = new (_readerStorage) Elf_Sym;
1120 sym->setBindingAndType(llvm::ELF::STB_LOCAL, llvm::ELF::STT_SECTION);
1125 auto *newAtom = createDefinedAtomAndAssignRelocations(
1126 "", sectionName, sym, section, content, content);
1127 newAtom->setOrdinal(++_ordinal);
1131 template <class ELFT>
1132 uint64_t ELFFile<ELFT>::symbolContentSize(const Elf_Shdr *section,
1133 const Elf_Sym *symbol,
1134 const Elf_Sym *nextSymbol) {
1135 const auto symValue = getSymbolValue(symbol);
1136 // if this is the last symbol, take up the remaining data.
1137 return nextSymbol ? getSymbolValue(nextSymbol) - symValue
1138 : section->sh_size - symValue;
1141 template <class ELFT>
1142 void ELFFile<ELFT>::createEdge(ELFDefinedAtom<ELFT> *from,
1143 ELFDefinedAtom<ELFT> *to, uint32_t edgeKind) {
1144 auto reference = new (_readerStorage) ELFReference<ELFT>(edgeKind);
1145 reference->setTarget(to);
1146 from->addReference(reference);
1149 /// Does the atom need to be redirected using a separate undefined atom?
1150 template <class ELFT>
1151 bool ELFFile<ELFT>::redirectReferenceUsingUndefAtom(
1152 const Elf_Sym *sourceSymbol, const Elf_Sym *targetSymbol) const {
1153 auto groupChildTarget = _groupChild.find(targetSymbol);
1155 // If the reference is not to a group child atom, there is no need to redirect
1156 // using a undefined atom. Its also not needed if the source and target are
1157 // from the same section.
1158 if ((groupChildTarget == _groupChild.end()) ||
1159 (sourceSymbol->st_shndx == targetSymbol->st_shndx))
1162 auto groupChildSource = _groupChild.find(sourceSymbol);
1164 // If the source symbol is not in a group, use a undefined symbol too.
1165 if (groupChildSource == _groupChild.end())
1168 // If the source and child are from the same group, we dont need the
1169 // relocation to go through a undefined symbol.
1170 if (groupChildSource->second.second == groupChildTarget->second.second)
1176 } // end namespace elf
1177 } // end namespace lld
1179 #endif // LLD_READER_WRITER_ELF_FILE_H