mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-17 05:24:49 +00:00
Do not use errs() or outs() directly. Instead use message(), log() or error()
LLD is a multi-threaded program. errs() or outs() are not guaranteed to be thread-safe (they are actually not). LLD's message(), log() or error() are thread-safe. We should use them. llvm-svn: 295787
This commit is contained in:
parent
9aa2bf209b
commit
e6e206d4b4
@ -227,7 +227,7 @@ void SectionChunk::printDiscardedMessage() const {
|
||||
// Removed by dead-stripping. If it's removed by ICF, ICF already
|
||||
// printed out the name, so don't repeat that here.
|
||||
if (Sym && this == Repl)
|
||||
outs() << "Discarded " << Sym->getName() << "\n";
|
||||
message("Discarded " + Sym->getName());
|
||||
}
|
||||
|
||||
StringRef SectionChunk::getDebugName() {
|
||||
|
@ -164,8 +164,7 @@ void LinkerDriver::addArchiveBuffer(MemoryBufferRef MB, StringRef SymName,
|
||||
|
||||
Obj->ParentName = ParentName;
|
||||
Symtab.addFile(Obj);
|
||||
if (Config->Verbose)
|
||||
outs() << "Loaded " << toString(Obj) << " for " << SymName << "\n";
|
||||
log("Loaded " + toString(Obj) + " for " + SymName);
|
||||
}
|
||||
|
||||
void LinkerDriver::enqueueArchiveMember(const Archive::Child &C,
|
||||
@ -472,8 +471,8 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
if (ErrOrWriter) {
|
||||
Tar = std::move(*ErrOrWriter);
|
||||
} else {
|
||||
errs() << "/linkrepro: failed to open " << Path << ": "
|
||||
<< toString(ErrOrWriter.takeError()) << '\n';
|
||||
error("/linkrepro: failed to open " + Path + ": " +
|
||||
toString(ErrOrWriter.takeError()));
|
||||
}
|
||||
}
|
||||
|
||||
@ -696,7 +695,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
// We should have inferred a machine type by now from the input files, but if
|
||||
// not we assume x64.
|
||||
if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) {
|
||||
errs() << "warning: /machine is not specified. x64 is assumed.\n";
|
||||
warn("/machine is not specified. x64 is assumed");
|
||||
Config->Machine = AMD64;
|
||||
}
|
||||
|
||||
@ -733,8 +732,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
|
||||
if (S.empty())
|
||||
fatal("entry point must be defined");
|
||||
Config->Entry = addUndefined(S);
|
||||
if (Config->Verbose)
|
||||
outs() << "Entry name inferred: " << S << "\n";
|
||||
log("Entry name inferred: " + S);
|
||||
}
|
||||
|
||||
// Handle /export
|
||||
|
@ -44,39 +44,35 @@ namespace {
|
||||
class Executor {
|
||||
public:
|
||||
explicit Executor(StringRef S) : Saver(Alloc), Prog(Saver.save(S)) {}
|
||||
void add(StringRef S) { Args.push_back(Saver.save(S).data()); }
|
||||
void add(std::string &S) { Args.push_back(Saver.save(S).data()); }
|
||||
void add(Twine S) { Args.push_back(Saver.save(S).data()); }
|
||||
void add(const char *S) { Args.push_back(Saver.save(S).data()); }
|
||||
void add(StringRef S) { Args.push_back(Saver.save(S)); }
|
||||
void add(std::string &S) { Args.push_back(Saver.save(S)); }
|
||||
void add(Twine S) { Args.push_back(Saver.save(S)); }
|
||||
void add(const char *S) { Args.push_back(Saver.save(S)); }
|
||||
|
||||
void run() {
|
||||
if (Config->Verbose) {
|
||||
outs() << Prog;
|
||||
for (const char *Arg : Args)
|
||||
outs() << " " << Arg;
|
||||
outs() << '\n';
|
||||
}
|
||||
log(Prog + " " + llvm::join(Args.begin(), Args.end(), " "));
|
||||
|
||||
ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog);
|
||||
if (auto EC = ExeOrErr.getError())
|
||||
fatal(EC, "unable to find " + Prog + " in PATH: ");
|
||||
const char *Exe = Saver.save(*ExeOrErr).data();
|
||||
|
||||
StringRef Exe = Saver.save(*ExeOrErr);
|
||||
Args.insert(Args.begin(), Exe);
|
||||
Args.push_back(nullptr);
|
||||
if (sys::ExecuteAndWait(Args[0], Args.data()) != 0) {
|
||||
for (const char *S : Args)
|
||||
if (S)
|
||||
errs() << S << " ";
|
||||
fatal("ExecuteAndWait failed");
|
||||
}
|
||||
|
||||
std::vector<const char *> Vec;
|
||||
for (StringRef S : Args)
|
||||
Vec.push_back(S.data());
|
||||
Vec.push_back(nullptr);
|
||||
|
||||
if (sys::ExecuteAndWait(Args[0], Vec.data()) != 0)
|
||||
fatal("ExecuteAndWait failed: " +
|
||||
llvm::join(Args.begin(), Args.end(), " "));
|
||||
}
|
||||
|
||||
private:
|
||||
BumpPtrAllocator Alloc;
|
||||
StringSaver Saver;
|
||||
StringRef Prog;
|
||||
std::vector<const char *> Args;
|
||||
std::vector<StringRef> Args;
|
||||
};
|
||||
|
||||
} // anonymous namespace
|
||||
@ -175,8 +171,7 @@ void parseMerge(StringRef S) {
|
||||
if (!Inserted) {
|
||||
StringRef Existing = Pair.first->second;
|
||||
if (Existing != To)
|
||||
errs() << "warning: " << S << ": already merged into " << Existing
|
||||
<< "\n";
|
||||
warn(S + ": already merged into " + Existing);
|
||||
}
|
||||
}
|
||||
|
||||
@ -558,7 +553,7 @@ void fixupExports() {
|
||||
Export *Existing = Pair.first->second;
|
||||
if (E == *Existing || E.Name != Existing->Name)
|
||||
continue;
|
||||
errs() << "warning: duplicate /export option: " << E.Name << "\n";
|
||||
warn("duplicate /export option: " + E.Name);
|
||||
}
|
||||
Config->Exports = std::move(V);
|
||||
|
||||
@ -677,8 +672,7 @@ void runMSVCLinker(opt::InputArgList &Args, ArrayRef<StringRef> Objects) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Config->Verbose)
|
||||
outs() << "link.exe " << Rsp << "\n";
|
||||
log("link.exe " + Rsp);
|
||||
|
||||
// Run MSVC link.exe.
|
||||
Temps.emplace_back("lto", "rsp", Rsp);
|
||||
@ -723,16 +717,16 @@ opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) {
|
||||
|
||||
// Print the real command line if response files are expanded.
|
||||
if (Args.hasArg(OPT_verbose) && ArgsArr.size() != Argv.size()) {
|
||||
outs() << "Command line:";
|
||||
std::string Msg = "Command line:";
|
||||
for (const char *S : Argv)
|
||||
outs() << " " << S;
|
||||
outs() << "\n";
|
||||
Msg += " " + std::string(S);
|
||||
message(Msg);
|
||||
}
|
||||
|
||||
if (MissingCount)
|
||||
fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
|
||||
for (auto *Arg : Args.filtered(OPT_UNKNOWN))
|
||||
errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n";
|
||||
warn("ignoring unknown argument: " + Arg->getSpelling());
|
||||
return Args;
|
||||
}
|
||||
|
||||
|
@ -55,6 +55,19 @@ static void print(StringRef S, raw_ostream::Colors C) {
|
||||
}
|
||||
}
|
||||
|
||||
void log(const Twine &Msg) {
|
||||
if (Config->Verbose) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
outs() << Argv0 << ": " << Msg << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void message(const Twine &Msg) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
outs() << Msg << "\n";
|
||||
outs().flush();
|
||||
}
|
||||
|
||||
void error(const Twine &Msg) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
|
||||
|
@ -20,6 +20,8 @@ extern uint64_t ErrorCount;
|
||||
extern llvm::raw_ostream *ErrorOS;
|
||||
extern llvm::StringRef Argv0;
|
||||
|
||||
void log(const Twine &Msg);
|
||||
void message(const Twine &Msg);
|
||||
void warn(const Twine &Msg);
|
||||
void error(const Twine &Msg);
|
||||
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
|
||||
|
@ -231,19 +231,16 @@ void ICF::run(const std::vector<Chunk *> &Vec) {
|
||||
++Cnt;
|
||||
} while (Repeat);
|
||||
|
||||
if (Config->Verbose)
|
||||
outs() << "\nICF needed " << Cnt << " iterations\n";
|
||||
log("ICF needed " + Twine(Cnt) + " iterations");
|
||||
|
||||
// Merge sections in the same colors.
|
||||
forEachColor([&](size_t Begin, size_t End) {
|
||||
if (End - Begin == 1)
|
||||
return;
|
||||
|
||||
if (Config->Verbose)
|
||||
outs() << "Selected " << Chunks[Begin]->getDebugName() << "\n";
|
||||
log("Selected " + Chunks[Begin]->getDebugName());
|
||||
for (size_t I = Begin + 1; I < End; ++I) {
|
||||
if (Config->Verbose)
|
||||
outs() << " Removed " << Chunks[I]->getDebugName() << "\n";
|
||||
log(" Removed " + Chunks[I]->getDebugName());
|
||||
Chunks[Begin]->replace(Chunks[I]);
|
||||
}
|
||||
});
|
||||
|
@ -57,8 +57,7 @@ static SymbolPreference compareDefined(Symbol *S, bool WasInserted,
|
||||
SymbolTable *Symtab;
|
||||
|
||||
void SymbolTable::addFile(InputFile *File) {
|
||||
if (Config->Verbose)
|
||||
outs() << "Reading " << toString(File) << "\n";
|
||||
log("Reading " + toString(File));
|
||||
File->parse();
|
||||
|
||||
MachineTypes MT = File->getMachineType();
|
||||
@ -81,8 +80,7 @@ void SymbolTable::addFile(InputFile *File) {
|
||||
if (S.empty())
|
||||
return;
|
||||
|
||||
if (Config->Verbose)
|
||||
outs() << "Directives: " << toString(File) << ": " << S << "\n";
|
||||
log("Directives: " + toString(File) + ": " + S);
|
||||
Driver->parseDirectives(S);
|
||||
}
|
||||
|
||||
@ -136,12 +134,11 @@ void SymbolTable::reportRemainingUndefines() {
|
||||
return;
|
||||
for (SymbolBody *B : Config->GCRoot)
|
||||
if (Undefs.count(B))
|
||||
errs() << "<root>: undefined symbol: " << B->getName() << "\n";
|
||||
warn("<root>: undefined symbol: " + B->getName());
|
||||
for (ObjectFile *File : ObjectFiles)
|
||||
for (SymbolBody *Sym : File->getSymbols())
|
||||
if (Undefs.count(Sym))
|
||||
errs() << toString(File) << ": undefined symbol: " << Sym->getName()
|
||||
<< "\n";
|
||||
warn(toString(File) + ": undefined symbol: " + Sym->getName());
|
||||
if (!Config->Force)
|
||||
fatal("link failed");
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ void LinkerDriver::main(ArrayRef<const char *> ArgsArr, bool CanExitEarly) {
|
||||
// in help to print the version information, GNU ld just normally exits,
|
||||
// while gold can continue linking. We are compatible with ld.bfd here.
|
||||
if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v))
|
||||
outs() << getLLDVersion() << "\n";
|
||||
message(getLLDVersion());
|
||||
if (Args.hasArg(OPT_version))
|
||||
return;
|
||||
|
||||
|
@ -45,9 +45,16 @@ static void print(StringRef S, raw_ostream::Colors C) {
|
||||
}
|
||||
|
||||
void elf::log(const Twine &Msg) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
if (Config->Verbose)
|
||||
if (Config->Verbose) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
outs() << Argv0 << ": " << Msg << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void elf::message(const Twine &Msg) {
|
||||
std::lock_guard<std::mutex> Lock(Mu);
|
||||
outs() << Msg << "\n";
|
||||
outs().flush();
|
||||
}
|
||||
|
||||
void elf::warn(const Twine &Msg) {
|
||||
|
@ -36,6 +36,7 @@ extern llvm::raw_ostream *ErrorOS;
|
||||
extern llvm::StringRef Argv0;
|
||||
|
||||
void log(const Twine &Msg);
|
||||
void message(const Twine &Msg);
|
||||
void warn(const Twine &Msg);
|
||||
void error(const Twine &Msg);
|
||||
LLVM_ATTRIBUTE_NORETURN void fatal(const Twine &Msg);
|
||||
|
@ -56,14 +56,13 @@ public:
|
||||
}
|
||||
|
||||
Optional<MemoryBufferRef> elf::readFile(StringRef Path) {
|
||||
if (Config->Verbose)
|
||||
outs() << Path << "\n";
|
||||
|
||||
log(Path);
|
||||
auto MBOrErr = MemoryBuffer::getFile(Path);
|
||||
if (auto EC = MBOrErr.getError()) {
|
||||
error("cannot open " + Path + ": " + EC.message());
|
||||
return None;
|
||||
}
|
||||
|
||||
std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
|
||||
MemoryBufferRef MBRef = MB->getMemBufferRef();
|
||||
make<std::unique_ptr<MemoryBuffer>>(std::move(MB)); // take MB ownership
|
||||
|
@ -568,8 +568,8 @@ static bool canMergeToProgbits(unsigned Type) {
|
||||
template <class ELFT> static void reportDiscarded(InputSectionBase<ELFT> *IS) {
|
||||
if (!Config->PrintGcSections)
|
||||
return;
|
||||
errs() << "removing unused section from '" << IS->Name << "' in file '"
|
||||
<< IS->getFile()->getName() << "'\n";
|
||||
message("removing unused section from '" + IS->Name + "' in file '" +
|
||||
IS->getFile()->getName());
|
||||
}
|
||||
|
||||
template <class ELFT>
|
||||
|
@ -75,7 +75,7 @@ template <class ELFT> void SymbolTable<ELFT>::addFile(InputFile *File) {
|
||||
}
|
||||
|
||||
if (Config->Trace)
|
||||
outs() << toString(File) << "\n";
|
||||
message(toString(File));
|
||||
|
||||
// .so file
|
||||
if (auto *F = dyn_cast<SharedFile<ELFT>>(File)) {
|
||||
|
@ -293,15 +293,15 @@ bool Symbol::includeInDynsym() const {
|
||||
// Print out a log message for --trace-symbol.
|
||||
void elf::printTraceSymbol(Symbol *Sym) {
|
||||
SymbolBody *B = Sym->body();
|
||||
outs() << toString(B->File);
|
||||
|
||||
std::string S;
|
||||
if (B->isUndefined())
|
||||
outs() << ": reference to ";
|
||||
S = ": reference to ";
|
||||
else if (B->isCommon())
|
||||
outs() << ": common definition of ";
|
||||
S = ": common definition of ";
|
||||
else
|
||||
outs() << ": definition of ";
|
||||
outs() << B->getName() << "\n";
|
||||
S = ": definition of ";
|
||||
|
||||
message(toString(B->File) + S + B->getName());
|
||||
}
|
||||
|
||||
// Returns a symbol for an error message.
|
||||
|
Loading…
x
Reference in New Issue
Block a user