From 708ad63474e38a61ed1d6784636b71e84bd4ae00 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Fri, 29 Apr 2022 11:27:11 +0800 Subject: [PATCH] [ELF][LTO] Fix non-v2 LTO build If a given linker LTO plugin does not support the v3 API, we resolve all symbol names to identify the set of object files that are actually needed for linking and then restart the linker to do the same thing again from scratch, excluding the unneeded files from the beginning. We do this because the v2 API does not provide a way to "unload" an object file once it is read. To identify an unneeded object file on the second run, we serialize its name in the form of `:` or just a filename. If an object file is in a thin archive, we simply used its filename. But if the same file is directly given to a linker as well as as a thin archive member, the file would accidentally be excluded on the second run. This change fixes that issue. With this change, it looks like we can build GCC 12 with LTO using mold. Fixes https://github.com/rui314/mold/issues/454 --- archive-file.h | 1 + elf/main.cc | 1 + mold.h | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/archive-file.h b/archive-file.h index 7108c7262a..496aa81ed6 100644 --- a/archive-file.h +++ b/archive-file.h @@ -93,6 +93,7 @@ read_thin_archive_members(C &ctx, MappedFile *mf) { std::string path = name.starts_with('/') ? name : (filepath(mf->name).parent_path() / name).string(); vec.push_back(MappedFile::must_open(ctx, path)); + vec.back()->thin_parent = mf; data = body; } return vec; diff --git a/elf/main.cc b/elf/main.cc index 27b5dc95bb..c910b5c02c 100644 --- a/elf/main.cc +++ b/elf/main.cc @@ -45,6 +45,7 @@ static ObjectFile *new_lto_obj(Context &ctx, MappedFile> *mf, ObjectFile *file = read_lto_object(ctx, mf); file->priority = ctx.file_priority++; + file->archive_name = archive_name; file->is_in_lib = ctx.in_lib || (!archive_name.empty() && !ctx.whole_archive); file->is_alive = !file->is_in_lib; ctx.has_lto_object = true; diff --git a/mold.h b/mold.h index 7c6f9feba7..a0e8166e62 100644 --- a/mold.h +++ b/mold.h @@ -590,6 +590,12 @@ class MappedFile { // because archive members may have the same name. return parent->name + ":" + std::to_string(get_offset()); } + + if (thin_parent) { + // If this is a thin archive member, the filename part is + // guaranteed to be unique. + return thin_parent->name + ":" + name; + } return name; } @@ -599,6 +605,7 @@ class MappedFile { i64 mtime = 0; bool given_fullpath = true; MappedFile *parent = nullptr; + MappedFile *thin_parent = nullptr; int fd = -1; };