[llvm] Object: Don't error out on malformed bitcode files. (PR #96848)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Jul 4 14:48:48 PDT 2024
================
@@ -482,16 +482,47 @@ static uint64_t computeHeadersSize(object::Archive::Kind Kind,
}
static Expected<std::unique_ptr<SymbolicFile>>
-getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context) {
+getSymbolicFile(MemoryBufferRef Buf, LLVMContext &Context,
+ object::Archive::Kind Kind) {
const file_magic Type = identify_magic(Buf.getBuffer());
// Don't attempt to read non-symbolic file types.
if (!object::SymbolicFile::isSymbolicFile(Type, &Context))
return nullptr;
if (Type == file_magic::bitcode) {
auto ObjOrErr = object::SymbolicFile::createSymbolicFile(
Buf, file_magic::bitcode, &Context);
- if (!ObjOrErr)
- return ObjOrErr.takeError();
+ // An error reading a bitcode file most likely indicates that the file
+ // was created by a compiler from the future. Normally we don't try to
+ // implement forwards compatibility for bitcode files, but when creating an
+ // archive we can implement best-effort forwards compatibility by treating
+ // the file as a blob and not creating symbol index entries for it. lld and
+ // mold ignore the archive symbol index, so provided that you use one of
+ // these linkers, LTO will work as long as lld or the gold plugin is newer
+ // than the compiler. We only ignore errors if the archive format is one
+ // that is supported by a linker that is known to ignore the index,
+ // otherwise there's no chance of this working so we may as well error out.
+ // We print a warning on read failure so that users of linkers that rely on
+ // the symbol index can diagnose the issue.
+ //
+ // This is the same behavior as GNU ar when the linker plugin returns an
+ // error when reading the input file. If the bitcode file is actually
+ // malformed, it will be diagnosed at link time.
+ if (!ObjOrErr) {
+ switch (Kind) {
+ case object::Archive::K_BSD:
+ case object::Archive::K_GNU:
+ case object::Archive::K_GNU64:
+ llvm::logAllUnhandledErrors(ObjOrErr.takeError(), llvm::errs(),
----------------
pcc wrote:
My earlier message highlighted a problem with the `llvm::Error` API: it doesn't really handle "contexts" very well, such as the file name. If we really wanted to handle this "properly", I think we would need to fundamentally redesign `llvm::Error` to handle contexts for all diagnostics, not just errors. For example, we could make it so that `llvm::Expected` holds a list of warnings on the side and those get propagated through callers when adding contexts. And then we wouldn't want the callback at all, we could just handle it in the caller. An alternative approach would involve a completely different way of denoting contexts, such as by using RAII objects.
In your use case, I think the `raw_ostream &Warn` argument that I described before is sufficient. You can redirect the output stream to a buffer and use it to detect whether a warning was printed, and then print the warnings to stderr followed by e.g. "error: warnings treated as errors". LLD's warning API just prints to stderr so it'll be more or less the same except that it won't be colored. That's a minor aesthetic detail which I think we can put up with for now until the `llvm::Error` API is redesigned.
https://github.com/llvm/llvm-project/pull/96848
More information about the llvm-commits
mailing list