Mercurial > hg > CbC > CbC_llvm
diff lld/ELF/OutputSections.cpp @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
line wrap: on
line diff
--- a/lld/ELF/OutputSections.cpp Mon May 25 11:55:54 2020 +0900 +++ b/lld/ELF/OutputSections.cpp Tue Jun 08 06:07:14 2021 +0900 @@ -20,7 +20,9 @@ #include "llvm/Support/MathExtras.h" #include "llvm/Support/Parallel.h" #include "llvm/Support/SHA1.h" +#include "llvm/Support/TimeProfiler.h" #include <regex> +#include <unordered_set> using namespace llvm; using namespace llvm::dwarf; @@ -77,10 +79,14 @@ // to be allocated for nobits sections. Other ones don't require // any special treatment on top of progbits, so there doesn't // seem to be a harm in merging them. +// +// NOTE: clang since rL252300 emits SHT_X86_64_UNWIND .eh_frame sections. Allow +// them to be merged into SHT_PROGBITS .eh_frame (GNU as .cfi_*). static bool canMergeToProgbits(unsigned type) { return type == SHT_NOBITS || type == SHT_PROGBITS || type == SHT_INIT_ARRAY || type == SHT_PREINIT_ARRAY || type == SHT_FINI_ARRAY || - type == SHT_NOTE; + type == SHT_NOTE || + (type == SHT_X86_64_UNWIND && config->emachine == EM_X86_64); } // Record that isec will be placed in the OutputSection. isec does not become @@ -280,6 +286,8 @@ !name.startswith(".debug_")) return; + llvm::TimeTraceScope timeScope("Compress debug sections"); + // Create a section header. zDebugHeader.resize(sizeof(Elf_Chdr)); auto *hdr = reinterpret_cast<Elf_Chdr *>(zDebugHeader.data()); @@ -376,6 +384,15 @@ // provides signature of the section group. ArrayRef<Symbol *> symbols = section->file->getSymbols(); os->info = in.symTab->getSymbolIndex(symbols[section->info]); + + // Some group members may be combined or discarded, so we need to compute the + // new size. The content will be rewritten in InputSection::copyShtGroup. + std::unordered_set<uint32_t> seen; + ArrayRef<InputSectionBase *> sections = section->file->getSections(); + for (const uint32_t &idx : section->getDataAs<uint32_t>().slice(1)) + if (OutputSection *osec = sections[read32(&idx)]->getOutputSection()) + seen.insert(osec->sectionIndex); + os->size = (1 + seen.size()) * sizeof(uint32_t); } void OutputSection::finalize() { @@ -401,7 +418,11 @@ if (!config->copyRelocs || (type != SHT_RELA && type != SHT_REL)) return; - if (isa<SyntheticSection>(first)) + // Skip if 'first' is synthetic, i.e. not a section created by --emit-relocs. + // Normally 'type' was changed by 'first' so 'first' should be non-null. + // However, if the output section is .rela.dyn, 'type' can be set by the empty + // synthetic .rela.plt and first can be null. + if (!first || isa<SyntheticSection>(first)) return; link = in.symTab->getParent()->sectionIndex; @@ -430,19 +451,19 @@ return std::regex_match(s.begin(), s.end(), re); } -// .ctors and .dtors are sorted by this priority from highest to lowest. -// -// 1. The section was contained in crtbegin (crtbegin contains -// some sentinel value in its .ctors and .dtors so that the runtime -// can find the beginning of the sections.) +// .ctors and .dtors are sorted by this order: // -// 2. The section has an optional priority value in the form of ".ctors.N" -// or ".dtors.N" where N is a number. Unlike .{init,fini}_array, -// they are compared as string rather than number. +// 1. .ctors/.dtors in crtbegin (which contains a sentinel value -1). +// 2. The section is named ".ctors" or ".dtors" (priority: 65536). +// 3. The section has an optional priority value in the form of ".ctors.N" or +// ".dtors.N" where N is a number in the form of %05u (priority: 65535-N). +// 4. .ctors/.dtors in crtend (which contains a sentinel value 0). // -// 3. The section is just ".ctors" or ".dtors". -// -// 4. The section was contained in crtend, which contains an end marker. +// For 2 and 3, the sections are sorted by priority from high to low, e.g. +// .ctors (65536), .ctors.00100 (65436), .ctors.00200 (65336). In GNU ld's +// internal linker scripts, the sorting is by string comparison which can +// achieve the same goal given the optional priority values are of the same +// length. // // In an ideal world, we don't need this function because .init_array and // .ctors are duplicate features (and .init_array is newer.) However, there @@ -457,13 +478,7 @@ bool endB = isCrtend(b->file->getName()); if (endA != endB) return endB; - StringRef x = a->name; - StringRef y = b->name; - assert(x.startswith(".ctors") || x.startswith(".dtors")); - assert(y.startswith(".ctors") || y.startswith(".dtors")); - x = x.substr(6); - y = y.substr(6); - return x < y; + return getPriority(a->name) > getPriority(b->name); } // Sorts input sections by the special rules for .ctors and .dtors. @@ -475,16 +490,17 @@ llvm::stable_sort(isd->sections, compCtors); } -// If an input string is in the form of "foo.N" where N is a number, -// return N. Otherwise, returns 65536, which is one greater than the -// lowest priority. +// If an input string is in the form of "foo.N" where N is a number, return N +// (65535-N if .ctors.N or .dtors.N). Otherwise, returns 65536, which is one +// greater than the lowest priority. int elf::getPriority(StringRef s) { size_t pos = s.rfind('.'); if (pos == StringRef::npos) return 65536; - int v; - if (!to_integer(s.substr(pos + 1), v, 10)) - return 65536; + int v = 65536; + if (to_integer(s.substr(pos + 1), v, 10) && + (pos == 6 && (s.startswith(".ctors") || s.startswith(".dtors")))) + v = 65535 - v; return v; }