[MachO] Properly reset global state
We need to reset global state between runs, similar to the other ports. There's some file-static state which needs to be reset as well and we need to add some new helpers for that. With this change, most LLD Mach-O tests pass with `LLD_IN_TEST=2` (which runs the linker twice on each test). Some tests will be fixed by the remainder of this stack, and the rest are fundamentally incompatible with that mode (e.g. they intentionally throw fatal errors). Fixes PR52070. Reviewed By: #lld-macho, int3 Differential Revision: https://reviews.llvm.org/D112878
This commit is contained in:
parent
f964ca896f
commit
0f6d720f1f
|
@ -1068,7 +1068,25 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
lld::stdoutOS = &stdoutOS;
|
||||
lld::stderrOS = &stderrOS;
|
||||
|
||||
errorHandler().cleanupCallback = []() { freeArena(); };
|
||||
errorHandler().cleanupCallback = []() {
|
||||
freeArena();
|
||||
|
||||
concatOutputSections.clear();
|
||||
inputFiles.clear();
|
||||
inputSections.clear();
|
||||
loadedArchives.clear();
|
||||
syntheticSections.clear();
|
||||
thunkMap.clear();
|
||||
|
||||
firstTLVDataSection = nullptr;
|
||||
tar = nullptr;
|
||||
memset(&in, 0, sizeof(in));
|
||||
|
||||
resetLoadedDylibs();
|
||||
resetOutputSegments();
|
||||
resetWriter();
|
||||
InputFile::resetIdCount();
|
||||
};
|
||||
|
||||
errorHandler().logName = args::getFilenameWithoutExe(argsArr[0]);
|
||||
stderrOS.enable_colors(stderrOS.has_colors());
|
||||
|
@ -1392,6 +1410,8 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
reexportHandler(arg, extensions);
|
||||
}
|
||||
|
||||
cl::ResetAllOptionOccurrences();
|
||||
|
||||
// Parse LTO options.
|
||||
if (const Arg *arg = args.getLastArg(OPT_mcpu))
|
||||
parseClangOption(saver.save("-mcpu=" + StringRef(arg->getValue())),
|
||||
|
@ -1476,5 +1496,7 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
if (canExitEarly)
|
||||
exitLld(errorCount() ? 1 : 0);
|
||||
|
||||
return !errorCount();
|
||||
bool ret = errorCount() == 0;
|
||||
errorHandler().reset();
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -56,6 +56,7 @@ llvm::Optional<StringRef> resolveDylibPath(llvm::StringRef path);
|
|||
|
||||
DylibFile *loadDylib(llvm::MemoryBufferRef mbref, DylibFile *umbrella = nullptr,
|
||||
bool isBundleLoader = false);
|
||||
void resetLoadedDylibs();
|
||||
|
||||
// Search for all possible combinations of `{root}/{name}.{extension}`.
|
||||
// If \p extensions are not specified, then just search for `{root}/{name}`.
|
||||
|
|
|
@ -246,6 +246,8 @@ DylibFile *macho::loadDylib(MemoryBufferRef mbref, DylibFile *umbrella,
|
|||
return newFile;
|
||||
}
|
||||
|
||||
void macho::resetLoadedDylibs() { loadedDylibs.clear(); }
|
||||
|
||||
Optional<StringRef>
|
||||
macho::findPathCombination(const Twine &name,
|
||||
const std::vector<StringRef> &roots,
|
||||
|
|
|
@ -69,6 +69,7 @@ public:
|
|||
virtual ~InputFile() = default;
|
||||
Kind kind() const { return fileKind; }
|
||||
StringRef getName() const { return name; }
|
||||
static void resetIdCount() { idCount = 0; }
|
||||
|
||||
MemoryBufferRef mb;
|
||||
|
||||
|
|
|
@ -161,6 +161,11 @@ void macho::sortOutputSegments() {
|
|||
static DenseMap<StringRef, OutputSegment *> nameToOutputSegment;
|
||||
std::vector<OutputSegment *> macho::outputSegments;
|
||||
|
||||
void macho::resetOutputSegments() {
|
||||
outputSegments.clear();
|
||||
nameToOutputSegment.clear();
|
||||
}
|
||||
|
||||
static StringRef maybeRenameSegment(StringRef name) {
|
||||
auto newName = config->segmentRenameMap.find(name);
|
||||
if (newName != config->segmentRenameMap.end())
|
||||
|
|
|
@ -68,6 +68,7 @@ private:
|
|||
extern std::vector<OutputSegment *> outputSegments;
|
||||
|
||||
void sortOutputSegments();
|
||||
void resetOutputSegments();
|
||||
|
||||
OutputSegment *getOrCreateOutputSegment(StringRef name);
|
||||
|
||||
|
|
|
@ -343,6 +343,7 @@ public:
|
|||
}
|
||||
|
||||
static uint32_t getInstanceCount() { return instanceCount; }
|
||||
static void resetInstanceCount() { instanceCount = 0; }
|
||||
|
||||
private:
|
||||
LoadCommandType type;
|
||||
|
@ -1153,6 +1154,8 @@ template <class LP> void Writer::run() {
|
|||
|
||||
template <class LP> void macho::writeResult() { Writer().run<LP>(); }
|
||||
|
||||
void macho::resetWriter() { LCDylib::resetInstanceCount(); }
|
||||
|
||||
void macho::createSyntheticSections() {
|
||||
in.header = make<MachHeaderSection>();
|
||||
if (config->dedupLiterals) {
|
||||
|
|
|
@ -26,6 +26,7 @@ public:
|
|||
};
|
||||
|
||||
template <class LP> void writeResult();
|
||||
void resetWriter();
|
||||
|
||||
void createSyntheticSections();
|
||||
|
||||
|
|
Loading…
Reference in a new issue