diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -57,10 +57,15 @@ namespace lld { namespace coff { +static void initGlobals(); static Timer inputFileTimer("Input File Reading", Timer::root()); +// If you add a new global variable, make sure that you add initialization code +// to initGlobals() too. Configuration *config; LinkerDriver *driver; +SymbolTable *symtab; +std::vector outputSections; bool link(ArrayRef args, bool canExitEarly, raw_ostream &stdoutOS, raw_ostream &stderrOS) { @@ -74,6 +79,8 @@ errorHandler().exitEarly = canExitEarly; stderrOS.enable_colors(stderrOS.has_colors()); + initGlobals(); + config = make(); symtab = make(); driver = make(); @@ -92,6 +99,16 @@ return !errorCount(); } +// Reset globals. We want to make sure that on every linker invocation, we start +// with fresh global variables, so that users who link lld as a library can call +// link() multiple times from the same process. +static void initGlobals() { + config = nullptr; + driver = nullptr; + symtab = nullptr; + outputSections.clear(); +} + // Parse options of the form "old;new". static std::pair getOldNewOptions(opt::InputArgList &args, unsigned id) { diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -30,8 +30,6 @@ static Timer ltoTimer("LTO", Timer::root()); -SymbolTable *symtab; - void SymbolTable::addFile(InputFile *file) { log("Reading " + toString(file)); file->parse(); diff --git a/lld/COFF/Writer.h b/lld/COFF/Writer.h --- a/lld/COFF/Writer.h +++ b/lld/COFF/Writer.h @@ -18,6 +18,11 @@ namespace lld { namespace coff { + +class OutputSection; + +extern std::vector outputSections; + static const int pageSize = 4096; void writeResult(); diff --git a/lld/COFF/Writer.cpp b/lld/COFF/Writer.cpp --- a/lld/COFF/Writer.cpp +++ b/lld/COFF/Writer.cpp @@ -80,10 +80,6 @@ static const int numberOfDataDirectory = 16; -// Global vector of all output sections. After output sections are finalized, -// this can be indexed by Chunk::getOutputSection. -static std::vector outputSections; - OutputSection *Chunk::getOutputSection() const { return osidx == 0 ? nullptr : outputSections[osidx - 1]; } diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -69,9 +69,26 @@ namespace lld { namespace elf { +// If you add a new global variable, make sure that you add initialization code +// to initGlobals() too. Configuration *config; +InStruct in; LinkerDriver *driver; - +LinkerScript *script; +Partition *mainPart; +SymbolTable *symtab; +const TargetInfo *target; +std::unique_ptr tar; +std::vector binaryFiles; +std::vector bitcodeFiles; +std::vector objectFiles; +std::vector inputSections; +std::vector lazyObjFiles; +std::vector outputSections; +std::vector partitions; +std::vector sharedFiles; + +static void initGlobals(); static void setConfigs(opt::InputArgList &args); static void readConfigs(opt::InputArgList &args); @@ -87,12 +104,7 @@ errorHandler().exitEarly = canExitEarly; stderrOS.enable_colors(stderrOS.has_colors()); - inputSections.clear(); - outputSections.clear(); - binaryFiles.clear(); - bitcodeFiles.clear(); - objectFiles.clear(); - sharedFiles.clear(); + initGlobals(); config = make(); driver = make(); @@ -120,6 +132,28 @@ return !errorCount(); } +// Reset globals. We want to make sure that on every linker invocation, we start +// with fresh global variables, so that users who link lld as a library can call +// link() multiple times from the same process. +static void initGlobals() { + config = nullptr; + memset(&in, 0, sizeof(in)); + driver = nullptr; + script = nullptr; + mainPart = nullptr; + symtab = nullptr; + target = nullptr; + tar.reset(); + binaryFiles.clear(); + bitcodeFiles.clear(); + objectFiles.clear(); + inputSections.clear(); + lazyObjFiles.clear(); + outputSections.clear(); + partitions.clear(); + sharedFiles.clear(); +} + // Parses a linker -m option. static std::tuple parseEmulation(StringRef emul) { uint8_t osabi = 0; diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -55,13 +55,6 @@ namespace elf { bool InputFile::isInGroup; uint32_t InputFile::nextGroupId; -std::vector binaryFiles; -std::vector bitcodeFiles; -std::vector lazyObjFiles; -std::vector objectFiles; -std::vector sharedFiles; - -std::unique_ptr tar; static ELFKind getELFKind(MemoryBufferRef mb, StringRef archiveName) { unsigned char size; diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -44,7 +44,6 @@ } namespace elf { -std::vector inputSections; template static ArrayRef getSectionContents(ObjFile &file, diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -46,7 +46,6 @@ namespace lld { namespace elf { -LinkerScript *script; static uint64_t getOutputSectionVA(SectionBase *sec) { OutputSection *os = sec->getOutputSection(); diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -39,8 +39,6 @@ OutputSection *Out::initArray; OutputSection *Out::finiArray; -std::vector outputSections; - uint32_t OutputSection::getPhdrFlags() const { uint32_t ret = 0; if (config->emachine != EM_ARM || !(flags & SHF_ARM_PURECODE)) diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -29,7 +29,6 @@ namespace lld { namespace elf { -SymbolTable *symtab; void SymbolTable::wrap(Symbol *sym, Symbol *real, Symbol *wrap) { // Swap symbols as instructed by -wrap. diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -3584,11 +3584,6 @@ } } -InStruct in; - -std::vector partitions; -Partition *mainPart; - template GdbIndexSection *GdbIndexSection::create(); template GdbIndexSection *GdbIndexSection::create(); template GdbIndexSection *GdbIndexSection::create(); diff --git a/lld/ELF/Target.cpp b/lld/ELF/Target.cpp --- a/lld/ELF/Target.cpp +++ b/lld/ELF/Target.cpp @@ -44,7 +44,6 @@ } namespace elf { -const TargetInfo *target; TargetInfo *getTarget() { switch (config->emachine) {