1
1
mirror of https://github.com/rui314/mold.git synced 2024-11-10 10:57:55 +03:00
This commit is contained in:
Rui Ueyama 2022-06-27 17:20:48 +08:00
parent 8aa05de5e3
commit a6a03b5851
2 changed files with 46 additions and 37 deletions

View File

@ -733,6 +733,35 @@ void ObjectFile<E>::parse_lto_symbols(Context<E> &ctx) {
mach_syms = mach_syms2;
}
template <typename E>
static MappedFile<Context<E>> *
find_external_lib(Context<E> &ctx, std::string_view parent, std::string path) {
if (!path.starts_with('/'))
return nullptr;
for (const std::string &root : ctx.arg.syslibroot) {
if (path.ends_with(".tbd")) {
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path))
return file;
continue;
}
if (path.ends_with(".dylib")) {
std::string stem(path.substr(0, path.size() - 6));
if (auto *file = MappedFile<Context<E>>::open(ctx, root + stem + ".tbd"))
return file;
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path))
return file;
}
for (std::string extn : {".tbd", ".dylib"})
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path + extn))
return file;
}
return nullptr;
}
template <typename E>
DylibFile<E> *DylibFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf) {
DylibFile<E> *dylib = new DylibFile<E>(mf);
@ -752,6 +781,18 @@ DylibFile<E> *DylibFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf)
Fatal(ctx) << mf->name << ": is not a dylib";
}
for (std::string_view path : dylib->reexported_libs) {
MappedFile<Context<E>> *mf =
find_external_lib(ctx, dylib->install_name, std::string(path));
if (!mf)
Fatal(ctx) << dylib->install_name << ": cannot open reexported library "
<< path;
DylibFile<E> *child = DylibFile<E>::create(ctx, mf);
dylib->exports.merge(child->exports);
dylib->weak_exports.merge(child->weak_exports);
}
for (std::string_view s : dylib->exports) {
dylib->syms.push_back(get_symbol(ctx, s));
dylib->is_weak_symbol.push_back(false);
@ -765,7 +806,7 @@ DylibFile<E> *DylibFile<E>::create(Context<E> &ctx, MappedFile<Context<E>> *mf)
}
return dylib;
};
}
template <typename E>
void DylibFile<E>::read_trie(Context<E> &ctx, u8 *start, i64 offset,
@ -800,6 +841,7 @@ void DylibFile<E>::parse_tapi(Context<E> &ctx) {
TextDylib tbd = parse_tbd(ctx, this->mf);
install_name = tbd.install_name;
reexported_libs = std::move(tbd.reexported_libs);
exports = std::move(tbd.exports);
weak_exports = std::move(tbd.weak_exports);
}

View File

@ -204,35 +204,6 @@ template <typename E>
static TextDylib parse(Context<E> &ctx, MappedFile<Context<E>> *mf,
std::string_view arch);
template <typename E>
static MappedFile<Context<E>> *
find_external_lib(Context<E> &ctx, std::string_view parent, std::string path) {
if (!path.starts_with('/'))
Fatal(ctx) << parent << ": contains an invalid reexported path: " << path;
for (const std::string &root : ctx.arg.syslibroot) {
if (path.ends_with(".tbd")) {
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path))
return file;
continue;
}
if (path.ends_with(".dylib")) {
std::string stem(path.substr(0, path.size() - 6));
if (auto *file = MappedFile<Context<E>>::open(ctx, root + stem + ".tbd"))
return file;
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path))
return file;
}
for (std::string extn : {".tbd", ".dylib"})
if (auto *file = MappedFile<Context<E>>::open(ctx, root + path + extn))
return file;
}
Fatal(ctx) << parent << ": cannot open reexported library " << path;
}
// A single YAML file may contain multiple text dylibs. The first text
// dylib is the main file followed by optional other text dylibs for
// re-exported libraries.
@ -243,6 +214,7 @@ template <typename E>
static TextDylib
squash(Context<E> &ctx, std::span<TextDylib> tbds, std::string_view arch) {
std::unordered_map<std::string_view, TextDylib> map;
std::vector<std::string_view> remainings;
TextDylib main = std::move(tbds[0]);
for (TextDylib &tbd : tbds.subspan(1))
@ -253,23 +225,18 @@ squash(Context<E> &ctx, std::span<TextDylib> tbds, std::string_view arch) {
auto it = map.find(lib);
if (it != map.end()) {
// The referenced reexported library is in the same .tbd file.
TextDylib &child = it->second;
merge(main.exports, child.exports);
merge(main.weak_exports, child.weak_exports);
visit(child);
} else {
// The referenced reexported library is a separate file.
MappedFile<Context<E>> *mf =
find_external_lib(ctx, tbd.install_name, std::string(lib));
TextDylib child = parse(ctx, mf, arch);
merge(main.exports, child.exports);
merge(main.weak_exports, child.weak_exports);
remainings.push_back(lib);
}
}
};
visit(main);
main.reexported_libs = remainings;
return main;
}