[lld] 439341b - [lld][ELF] Add additional time trace categories
James Henderson via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 10 02:29:39 PST 2020
Author: James Henderson
Date: 2020-11-10T10:28:46Z
New Revision: 439341b9bf0d9c91d1fc7a896cb85dbbb958f924
URL: https://github.com/llvm/llvm-project/commit/439341b9bf0d9c91d1fc7a896cb85dbbb958f924
DIFF: https://github.com/llvm/llvm-project/commit/439341b9bf0d9c91d1fc7a896cb85dbbb958f924.diff
LOG: [lld][ELF] Add additional time trace categories
I noticed when running a large link with the --time-trace option that
there were several areas which were missing any specific time trace
categories (aside from the generic link/ExecuteLinker categories). This
patch adds new categories to fill most of the "gaps", or to provide more
detail than was previously provided.
Reviewed by: MaskRay, grimar, russell.gallop
Differential Revision: https://reviews.llvm.org/D90686
Added:
Modified:
lld/ELF/Driver.cpp
lld/ELF/DriverUtils.cpp
lld/ELF/InputFiles.cpp
lld/ELF/LinkerScript.cpp
lld/ELF/MapFile.cpp
lld/ELF/OutputSections.cpp
lld/ELF/ScriptParser.cpp
lld/ELF/Writer.cpp
Removed:
################################################################################
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index fbc5e44baa05..318c231088a0 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1321,6 +1321,7 @@ static bool isFormatBinary(StringRef s) {
}
void LinkerDriver::createFiles(opt::InputArgList &args) {
+ llvm::TimeTraceScope timeScope("Load input files");
// For --{push,pop}-state.
std::vector<std::tuple<bool, bool, bool>> stack;
@@ -1659,6 +1660,7 @@ static void writeDependencyFile() {
// result, the passes after the symbol resolution won't see any
// symbols of type CommonSymbol.
static void replaceCommonSymbols() {
+ llvm::TimeTraceScope timeScope("Replace common symbols");
for (Symbol *sym : symtab->symbols()) {
auto *s = dyn_cast<CommonSymbol>(sym);
if (!s)
@@ -1678,6 +1680,7 @@ static void replaceCommonSymbols() {
// created from the DSO. Otherwise, they become dangling references
// that point to a non-existent DSO.
static void demoteSharedSymbols() {
+ llvm::TimeTraceScope timeScope("Demote shared symbols");
for (Symbol *sym : symtab->symbols()) {
auto *s = dyn_cast<SharedSymbol>(sym);
if (!s || s->getFile().isNeeded)
@@ -1974,10 +1977,14 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// Fail early if the output file or map file is not writable. If a user has a
// long link, e.g. due to a large LTO link, they do not wish to run it and
// find that it failed because there was a mistake in their command-line.
- if (auto e = tryCreateFile(config->outputFile))
- error("cannot open output file " + config->outputFile + ": " + e.message());
- if (auto e = tryCreateFile(config->mapFile))
- error("cannot open map file " + config->mapFile + ": " + e.message());
+ {
+ llvm::TimeTraceScope timeScope("Create output files");
+ if (auto e = tryCreateFile(config->outputFile))
+ error("cannot open output file " + config->outputFile + ": " +
+ e.message());
+ if (auto e = tryCreateFile(config->mapFile))
+ error("cannot open map file " + config->mapFile + ": " + e.message());
+ }
if (errorCount())
return;
@@ -2004,8 +2011,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// appended to the Files vector.
{
llvm::TimeTraceScope timeScope("Parse input files");
- for (size_t i = 0; i < files.size(); ++i)
+ for (size_t i = 0; i < files.size(); ++i) {
+ llvm::TimeTraceScope timeScope("Parse input files", files[i]->getName());
parseFile(files[i]);
+ }
}
// Now that we have every file, we can decide if we will need a
@@ -2092,8 +2101,10 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
// For a relocatable output, version scripts don't make sense, and
// parsing a symbol version string (e.g. dropping "@ver1" from a symbol
// name "foo at ver1") rather do harm, so we don't call this if -r is given.
- if (!config->relocatable)
+ if (!config->relocatable) {
+ llvm::TimeTraceScope timeScope("Process symbol versions");
symtab->scanVersionScript();
+ }
// Do link-time optimization if given files are LLVM bitcode files.
// This compiles bitcode files into real object files.
@@ -2123,37 +2134,43 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
if (!wrapped.empty())
wrapSymbols(wrapped);
- // Now that we have a complete list of input files.
- // Beyond this point, no new files are added.
- // Aggregate all input sections into one place.
- for (InputFile *f : objectFiles)
- for (InputSectionBase *s : f->getSections())
- if (s && s != &InputSection::discarded)
- inputSections.push_back(s);
- for (BinaryFile *f : binaryFiles)
- for (InputSectionBase *s : f->getSections())
- inputSections.push_back(cast<InputSection>(s));
-
- llvm::erase_if(inputSections, [](InputSectionBase *s) {
- if (s->type == SHT_LLVM_SYMPART) {
- readSymbolPartitionSection<ELFT>(s);
- return true;
- }
+ {
+ llvm::TimeTraceScope timeScope("Aggregate sections");
+ // Now that we have a complete list of input files.
+ // Beyond this point, no new files are added.
+ // Aggregate all input sections into one place.
+ for (InputFile *f : objectFiles)
+ for (InputSectionBase *s : f->getSections())
+ if (s && s != &InputSection::discarded)
+ inputSections.push_back(s);
+ for (BinaryFile *f : binaryFiles)
+ for (InputSectionBase *s : f->getSections())
+ inputSections.push_back(cast<InputSection>(s));
+ }
- // We do not want to emit debug sections if --strip-all
- // or -strip-debug are given.
- if (config->strip == StripPolicy::None)
- return false;
+ {
+ llvm::TimeTraceScope timeScope("Strip sections");
+ llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ if (s->type == SHT_LLVM_SYMPART) {
+ readSymbolPartitionSection<ELFT>(s);
+ return true;
+ }
- if (isDebugSection(*s))
- return true;
- if (auto *isec = dyn_cast<InputSection>(s))
- if (InputSectionBase *rel = isec->getRelocatedSection())
- if (isDebugSection(*rel))
- return true;
+ // We do not want to emit debug sections if --strip-all
+ // or -strip-debug are given.
+ if (config->strip == StripPolicy::None)
+ return false;
- return false;
- });
+ if (isDebugSection(*s))
+ return true;
+ if (auto *isec = dyn_cast<InputSection>(s))
+ if (InputSectionBase *rel = isec->getRelocatedSection())
+ if (isDebugSection(*rel))
+ return true;
+
+ return false;
+ });
+ }
// Since we now have a complete set of input files, we can create
// a .d file to record build dependencies.
@@ -2225,23 +2242,33 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &args) {
if (!config->relocatable)
combineEhSections();
- // Create output sections described by SECTIONS commands.
- script->processSectionCommands();
-
- // Linker scripts control how input sections are assigned to output sections.
- // Input sections that were not handled by scripts are called "orphans", and
- // they are assigned to output sections by the default rule. Process that.
- script->addOrphanSections();
-
- // Migrate InputSectionDescription::sectionBases to sections. This includes
- // merging MergeInputSections into a single MergeSyntheticSection. From this
- // point onwards InputSectionDescription::sections should be used instead of
- // sectionBases.
- for (BaseCommand *base : script->sectionCommands)
- if (auto *sec = dyn_cast<OutputSection>(base))
- sec->finalizeInputSections();
- llvm::erase_if(inputSections,
- [](InputSectionBase *s) { return isa<MergeInputSection>(s); });
+ {
+ llvm::TimeTraceScope timeScope("Assign sections");
+
+ // Create output sections described by SECTIONS commands.
+ script->processSectionCommands();
+
+ // Linker scripts control how input sections are assigned to output
+ // sections. Input sections that were not handled by scripts are called
+ // "orphans", and they are assigned to output sections by the default rule.
+ // Process that.
+ script->addOrphanSections();
+ }
+
+ {
+ llvm::TimeTraceScope timeScope("Merge/finalize input sections");
+
+ // Migrate InputSectionDescription::sectionBases to sections. This includes
+ // merging MergeInputSections into a single MergeSyntheticSection. From this
+ // point onwards InputSectionDescription::sections should be used instead of
+ // sectionBases.
+ for (BaseCommand *base : script->sectionCommands)
+ if (auto *sec = dyn_cast<OutputSection>(base))
+ sec->finalizeInputSections();
+ llvm::erase_if(inputSections, [](InputSectionBase *s) {
+ return isa<MergeInputSection>(s);
+ });
+ }
// Two input sections with
diff erent output sections should not be folded.
// ICF runs after processSectionCommands() so that we know the output sections.
diff --git a/lld/ELF/DriverUtils.cpp b/lld/ELF/DriverUtils.cpp
index e33b07c0c9c9..03173565e578 100644
--- a/lld/ELF/DriverUtils.cpp
+++ b/lld/ELF/DriverUtils.cpp
@@ -26,6 +26,7 @@
#include "llvm/Support/Host.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
+#include "llvm/Support/TimeProfiler.h"
using namespace llvm;
using namespace llvm::sys;
@@ -238,6 +239,7 @@ Optional<std::string> elf::searchLibraryBaseName(StringRef name) {
// This is for -l<namespec>.
Optional<std::string> elf::searchLibrary(StringRef name) {
+ llvm::TimeTraceScope timeScope("Locate library", name);
if (name.startswith(":"))
return findFromSearchPaths(name.substr(1));
return searchLibraryBaseName(name);
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp
index 70134d5ca0ef..f44260959d27 100644
--- a/lld/ELF/InputFiles.cpp
+++ b/lld/ELF/InputFiles.cpp
@@ -105,6 +105,8 @@ InputFile::InputFile(Kind k, MemoryBufferRef m)
}
Optional<MemoryBufferRef> elf::readFile(StringRef path) {
+ llvm::TimeTraceScope timeScope("Load input files", path);
+
// The --chroot option changes our virtual root directory.
// This is useful when you are dealing with files created by --reproduce.
if (!config->chroot.empty() && path.startswith("/"))
diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index 9d612ae4aba0..8ae95fbe1e94 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -30,6 +30,7 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Support/Parallel.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/TimeProfiler.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
@@ -765,6 +766,7 @@ void LinkerScript::addOrphanSections() {
}
void LinkerScript::diagnoseOrphanHandling() const {
+ llvm::TimeTraceScope timeScope("Diagnose orphan sections");
for (const InputSectionBase *sec : orphanSections) {
// Input SHT_REL[A] retained by --emit-relocs are ignored by
// computeInputSections(). Don't warn/error.
diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp
index 12cffead1f80..239c6c394840 100644
--- a/lld/ELF/MapFile.cpp
+++ b/lld/ELF/MapFile.cpp
@@ -29,6 +29,7 @@
#include "llvm/ADT/MapVector.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/Parallel.h"
+#include "llvm/Support/TimeProfiler.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;
@@ -142,6 +143,8 @@ void elf::writeMapFile() {
if (config->mapFile.empty())
return;
+ llvm::TimeTraceScope timeScope("Write map file");
+
// Open a map file for writing.
std::error_code ec;
raw_fd_ostream os(config->mapFile, ec, sys::fs::OF_None);
diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp
index 1b7f26a7d79f..518af1ee0548 100644
--- a/lld/ELF/OutputSections.cpp
+++ b/lld/ELF/OutputSections.cpp
@@ -20,6 +20,7 @@
#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>
@@ -285,6 +286,8 @@ template <class ELFT> void OutputSection::maybeCompress() {
!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());
diff --git a/lld/ELF/ScriptParser.cpp b/lld/ELF/ScriptParser.cpp
index eae1d17b2f43..5a8131166b14 100644
--- a/lld/ELF/ScriptParser.cpp
+++ b/lld/ELF/ScriptParser.cpp
@@ -32,6 +32,7 @@
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/ScopedPrinter.h"
+#include "llvm/Support/TimeProfiler.h"
#include <cassert>
#include <limits>
#include <vector>
@@ -1620,17 +1621,23 @@ std::pair<uint32_t, uint32_t> ScriptParser::readMemoryAttributes() {
}
void elf::readLinkerScript(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read linker script",
+ mb.getBufferIdentifier());
ScriptParser(mb).readLinkerScript();
}
void elf::readVersionScript(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read version script",
+ mb.getBufferIdentifier());
ScriptParser(mb).readVersionScript();
}
void elf::readDynamicList(MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read dynamic list", mb.getBufferIdentifier());
ScriptParser(mb).readDynamicList();
}
void elf::readDefsym(StringRef name, MemoryBufferRef mb) {
+ llvm::TimeTraceScope timeScope("Read defsym input", name);
ScriptParser(mb).readDefsym(name);
}
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a02b08204d80..1bb88a25351c 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -158,7 +158,6 @@ static bool needsInterpSection() {
}
template <class ELFT> void elf::writeResult() {
- llvm::TimeTraceScope timeScope("Write output file");
Writer<ELFT>().run();
}
@@ -205,6 +204,7 @@ void elf::copySectionsIntoPartitions() {
}
void elf::combineEhSections() {
+ llvm::TimeTraceScope timeScope("Combine EH sections");
for (InputSectionBase *&s : inputSections) {
// Ignore dead sections and the partition end marker (.part.end),
// whose partition number is out of bounds.
@@ -634,30 +634,34 @@ template <class ELFT> void Writer<ELFT>::run() {
checkSections();
// It does not make sense try to open the file if we have error already.
- if (errorCount())
- return;
- // Write the result down to a file.
- openFile();
if (errorCount())
return;
- if (!config->oFormatBinary) {
- if (config->zSeparate != SeparateSegmentKind::None)
- writeTrapInstr();
- writeHeader();
- writeSections();
- } else {
- writeSectionsBinary();
- }
+ {
+ llvm::TimeTraceScope timeScope("Write output file");
+ // Write the result down to a file.
+ openFile();
+ if (errorCount())
+ return;
- // Backfill .note.gnu.build-id section content. This is done at last
- // because the content is usually a hash value of the entire output file.
- writeBuildId();
- if (errorCount())
- return;
+ if (!config->oFormatBinary) {
+ if (config->zSeparate != SeparateSegmentKind::None)
+ writeTrapInstr();
+ writeHeader();
+ writeSections();
+ } else {
+ writeSectionsBinary();
+ }
+
+ // Backfill .note.gnu.build-id section content. This is done at last
+ // because the content is usually a hash value of the entire output file.
+ writeBuildId();
+ if (errorCount())
+ return;
- if (auto e = buffer->commit())
- error("failed to write to the output file: " + toString(std::move(e)));
+ if (auto e = buffer->commit())
+ error("failed to write to the output file: " + toString(std::move(e)));
+ }
}
template <class ELFT, class RelTy>
@@ -763,6 +767,7 @@ static bool includeInSymtab(const Symbol &b) {
template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
if (!in.symTab)
return;
+ llvm::TimeTraceScope timeScope("Add local symbols");
if (config->copyRelocs && config->discard != DiscardPolicy::None)
markUsedLocalSymbols<ELFT>();
for (InputFile *file : objectFiles) {
@@ -1504,6 +1509,7 @@ template <class ELFT> void Writer<ELFT>::sortInputSections() {
}
template <class ELFT> void Writer<ELFT>::sortSections() {
+ llvm::TimeTraceScope timeScope("Sort sections");
script->adjustSectionsBeforeSorting();
// Don't sort if using -r. It is not necessary and we want to preserve the
@@ -1637,6 +1643,7 @@ static bool compareByFilePosition(InputSection *a, InputSection *b) {
}
template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
+ llvm::TimeTraceScope timeScope("Resolve SHF_LINK_ORDER");
for (OutputSection *sec : outputSections) {
if (!(sec->flags & SHF_LINK_ORDER))
continue;
@@ -1679,8 +1686,10 @@ template <class ELFT> void Writer<ELFT>::resolveShfLinkOrder() {
}
static void finalizeSynthetic(SyntheticSection *sec) {
- if (sec && sec->isNeeded() && sec->getParent())
+ if (sec && sec->isNeeded() && sec->getParent()) {
+ llvm::TimeTraceScope timeScope("Finalize synthetic sections", sec->name);
sec->finalizeContents();
+ }
}
// We need to generate and finalize the content that depends on the address of
@@ -1688,6 +1697,7 @@ static void finalizeSynthetic(SyntheticSection *sec) {
// addresses we must converge to a fixed point. We do that here. See the comment
// in Writer<ELFT>::finalizeSections().
template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
+ llvm::TimeTraceScope timeScope("Finalize address dependent content");
ThunkCreator tc;
AArch64Err843419Patcher a64p;
ARMErr657417Patcher a32p;
@@ -1944,11 +1954,14 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
}
}
- // This responsible for splitting up .eh_frame section into
- // pieces. The relocation scan uses those pieces, so this has to be
- // earlier.
- for (Partition &part : partitions)
- finalizeSynthetic(part.ehFrame);
+ {
+ llvm::TimeTraceScope timeScope("Finalize .eh_frame");
+ // This responsible for splitting up .eh_frame section into
+ // pieces. The relocation scan uses those pieces, so this has to be
+ // earlier.
+ for (Partition &part : partitions)
+ finalizeSynthetic(part.ehFrame);
+ }
for (Symbol *sym : symtab->symbols())
sym->isPreemptible = computeIsPreemptible(*sym);
@@ -1957,14 +1970,17 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// by declareSymbols) to actual definitions.
script->processSymbolAssignments();
- // Scan relocations. This must be done after every symbol is declared so that
- // we can correctly decide if a dynamic relocation is needed. This is called
- // after processSymbolAssignments() because it needs to know whether a
- // linker-script-defined symbol is absolute.
- ppc64noTocRelax.clear();
- if (!config->relocatable) {
- forEachRelSec(scanRelocations<ELFT>);
- reportUndefinedSymbols<ELFT>();
+ {
+ llvm::TimeTraceScope timeScope("Scan relocations");
+ // Scan relocations. This must be done after every symbol is declared so
+ // that we can correctly decide if a dynamic relocation is needed. This is
+ // called after processSymbolAssignments() because it needs to know whether
+ // a linker-script-defined symbol is absolute.
+ ppc64noTocRelax.clear();
+ if (!config->relocatable) {
+ forEachRelSec(scanRelocations<ELFT>);
+ reportUndefinedSymbols<ELFT>();
+ }
}
if (in.plt && in.plt->isNeeded())
@@ -1994,31 +2010,34 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
toString(*sym) + " [--no-allow-shlib-undefined]");
}
- // Now that we have defined all possible global symbols including linker-
- // synthesized ones. Visit all symbols to give the finishing touches.
- for (Symbol *sym : symtab->symbols()) {
- if (!includeInSymtab(*sym))
- continue;
- if (in.symTab)
- in.symTab->addSymbol(sym);
-
- if (sym->includeInDynsym()) {
- partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
- if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
- if (file->isNeeded && !sym->isUndefined())
- addVerneed(sym);
+ {
+ llvm::TimeTraceScope timeScope("Add symbols to symtabs");
+ // Now that we have defined all possible global symbols including linker-
+ // synthesized ones. Visit all symbols to give the finishing touches.
+ for (Symbol *sym : symtab->symbols()) {
+ if (!includeInSymtab(*sym))
+ continue;
+ if (in.symTab)
+ in.symTab->addSymbol(sym);
+
+ if (sym->includeInDynsym()) {
+ partitions[sym->partition - 1].dynSymTab->addSymbol(sym);
+ if (auto *file = dyn_cast_or_null<SharedFile>(sym->file))
+ if (file->isNeeded && !sym->isUndefined())
+ addVerneed(sym);
+ }
}
- }
- // We also need to scan the dynamic relocation tables of the other partitions
- // and add any referenced symbols to the partition's dynsym.
- for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
- DenseSet<Symbol *> syms;
- for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
- syms.insert(e.sym);
- for (DynamicReloc &reloc : part.relaDyn->relocs)
- if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
- part.dynSymTab->addSymbol(reloc.sym);
+ // We also need to scan the dynamic relocation tables of the other
+ // partitions and add any referenced symbols to the partition's dynsym.
+ for (Partition &part : MutableArrayRef<Partition>(partitions).slice(1)) {
+ DenseSet<Symbol *> syms;
+ for (const SymbolTableEntry &e : part.dynSymTab->getSymbols())
+ syms.insert(e.sym);
+ for (DynamicReloc &reloc : part.relaDyn->relocs)
+ if (reloc.sym && !reloc.useSymVA && syms.insert(reloc.sym).second)
+ part.dynSymTab->addSymbol(reloc.sym);
+ }
}
// Do not proceed if there was an undefined symbol.
@@ -2099,35 +2118,39 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
// have the headers, we can find out which sections they point to.
setReservedSymbolSections();
- finalizeSynthetic(in.bss);
- finalizeSynthetic(in.bssRelRo);
- finalizeSynthetic(in.symTabShndx);
- finalizeSynthetic(in.shStrTab);
- finalizeSynthetic(in.strTab);
- finalizeSynthetic(in.got);
- finalizeSynthetic(in.mipsGot);
- finalizeSynthetic(in.igotPlt);
- finalizeSynthetic(in.gotPlt);
- finalizeSynthetic(in.relaIplt);
- finalizeSynthetic(in.relaPlt);
- finalizeSynthetic(in.plt);
- finalizeSynthetic(in.iplt);
- finalizeSynthetic(in.ppc32Got2);
- finalizeSynthetic(in.partIndex);
-
- // Dynamic section must be the last one in this list and dynamic
- // symbol table section (dynSymTab) must be the first one.
- for (Partition &part : partitions) {
- finalizeSynthetic(part.dynSymTab);
- finalizeSynthetic(part.gnuHashTab);
- finalizeSynthetic(part.hashTab);
- finalizeSynthetic(part.verDef);
- finalizeSynthetic(part.relaDyn);
- finalizeSynthetic(part.relrDyn);
- finalizeSynthetic(part.ehFrameHdr);
- finalizeSynthetic(part.verSym);
- finalizeSynthetic(part.verNeed);
- finalizeSynthetic(part.dynamic);
+ {
+ llvm::TimeTraceScope timeScope("Finalize synthetic sections");
+
+ finalizeSynthetic(in.bss);
+ finalizeSynthetic(in.bssRelRo);
+ finalizeSynthetic(in.symTabShndx);
+ finalizeSynthetic(in.shStrTab);
+ finalizeSynthetic(in.strTab);
+ finalizeSynthetic(in.got);
+ finalizeSynthetic(in.mipsGot);
+ finalizeSynthetic(in.igotPlt);
+ finalizeSynthetic(in.gotPlt);
+ finalizeSynthetic(in.relaIplt);
+ finalizeSynthetic(in.relaPlt);
+ finalizeSynthetic(in.plt);
+ finalizeSynthetic(in.iplt);
+ finalizeSynthetic(in.ppc32Got2);
+ finalizeSynthetic(in.partIndex);
+
+ // Dynamic section must be the last one in this list and dynamic
+ // symbol table section (dynSymTab) must be the first one.
+ for (Partition &part : partitions) {
+ finalizeSynthetic(part.dynSymTab);
+ finalizeSynthetic(part.gnuHashTab);
+ finalizeSynthetic(part.hashTab);
+ finalizeSynthetic(part.verDef);
+ finalizeSynthetic(part.relaDyn);
+ finalizeSynthetic(part.relrDyn);
+ finalizeSynthetic(part.ehFrameHdr);
+ finalizeSynthetic(part.verSym);
+ finalizeSynthetic(part.verNeed);
+ finalizeSynthetic(part.dynamic);
+ }
}
if (!script->hasSectionsCommand && !config->relocatable)
@@ -2158,9 +2181,13 @@ template <class ELFT> void Writer<ELFT>::finalizeSections() {
if (errorCount())
return;
- // finalizeAddressDependentContent may have added local symbols to the static symbol table.
- finalizeSynthetic(in.symTab);
- finalizeSynthetic(in.ppc64LongBranchTarget);
+ {
+ llvm::TimeTraceScope timeScope("Finalize synthetic sections");
+ // finalizeAddressDependentContent may have added local symbols to the
+ // static symbol table.
+ finalizeSynthetic(in.symTab);
+ finalizeSynthetic(in.ppc64LongBranchTarget);
+ }
// Relaxation to delete inter-basic block jumps created by basic block
// sections. Run after in.symTab is finalized as optimizeBasicBlockJumps
More information about the llvm-commits
mailing list