Skip to content

Commit 4c18681

Browse files
authored
[InstallAPI] Add support for aliased exports (#88750)
Apple's ld supports alias_lists, described as ``` -alias_list filename The specified filename contains a list of aliases. The symbol name and its alias are on one line, separated by whitespace. Lines starting with # are ignored. ``` To handle this for installapi-produced TBD files, pass along the same input and account for it in verification.
1 parent 353322f commit 4c18681

File tree

12 files changed

+572
-8
lines changed

12 files changed

+572
-8
lines changed

clang/include/clang/Basic/DiagnosticInstallAPIKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ def err_no_matching_target : Error<"no matching target found for target variant
2424
def err_unsupported_vendor : Error<"vendor '%0' is not supported: '%1'">;
2525
def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'">;
2626
def err_unsupported_os : Error<"os '%0' is not supported: '%1'">;
27+
def err_cannot_read_alias_list : Error<"could not read alias list '%0': %1">;
2728
} // end of command line category.
2829

2930
let CategoryName = "Verification" in {

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,7 @@ def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">,
15051505
def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">,
15061506
Visibility<[ClangOption, CC1Option]>;
15071507
def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
1508+
def alias_list : Separate<["-"], "alias_list">, Flags<[LinkerInput]>;
15081509
def extract_api : Flag<["-"], "extract-api">,
15091510
Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
15101511
HelpText<"Extract API information">;

clang/include/clang/InstallAPI/DylibVerifier.h

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -78,10 +78,12 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
7878
DylibVerifier() = default;
7979

8080
DylibVerifier(llvm::MachO::Records &&Dylib, ReexportedInterfaces &&Reexports,
81-
DiagnosticsEngine *Diag, VerificationMode Mode, bool Zippered,
82-
bool Demangle, StringRef DSYMPath)
83-
: Dylib(std::move(Dylib)), Reexports(std::move(Reexports)), Mode(Mode),
84-
Zippered(Zippered), Demangle(Demangle), DSYMPath(DSYMPath),
81+
AliasMap Aliases, DiagnosticsEngine *Diag,
82+
VerificationMode Mode, bool Zippered, bool Demangle,
83+
StringRef DSYMPath)
84+
: Dylib(std::move(Dylib)), Reexports(std::move(Reexports)),
85+
Aliases(std::move(Aliases)), Mode(Mode), Zippered(Zippered),
86+
Demangle(Demangle), DSYMPath(DSYMPath),
8587
Exports(std::make_unique<SymbolSet>()), Ctx(VerifierContext{Diag}) {}
8688

8789
Result verify(GlobalRecord *R, const FrontendAttrs *FA);
@@ -104,7 +106,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
104106
void setTarget(const Target &T);
105107

106108
/// Release ownership over exports.
107-
std::unique_ptr<SymbolSet> getExports() { return std::move(Exports); }
109+
std::unique_ptr<SymbolSet> takeExports();
108110

109111
/// Get result of verification.
110112
Result getState() const { return Ctx.FrontendState; }
@@ -189,6 +191,9 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
189191
// Reexported interfaces apart of the library.
190192
ReexportedInterfaces Reexports;
191193

194+
// Symbol aliases.
195+
AliasMap Aliases;
196+
192197
// Controls what class of violations to report.
193198
VerificationMode Mode = VerificationMode::Invalid;
194199

clang/include/clang/InstallAPI/MachO.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "llvm/TextAPI/TextAPIWriter.h"
2424
#include "llvm/TextAPI/Utils.h"
2525

26+
using AliasMap = llvm::MachO::AliasMap;
2627
using Architecture = llvm::MachO::Architecture;
2728
using ArchitectureSet = llvm::MachO::ArchitectureSet;
2829
using SymbolFlags = llvm::MachO::SymbolFlags;

clang/lib/InstallAPI/DylibVerifier.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -674,6 +674,11 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
674674
return;
675675
}
676676

677+
if (Aliases.count({SymbolName.str(), SymCtx.Kind})) {
678+
updateState(Result::Valid);
679+
return;
680+
}
681+
677682
// All checks at this point classify as some kind of violation.
678683
// The different verification modes dictate whether they are reported to the
679684
// user.
@@ -973,5 +978,24 @@ bool DylibVerifier::verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
973978
return true;
974979
}
975980

981+
std::unique_ptr<SymbolSet> DylibVerifier::takeExports() {
982+
for (const auto &[Alias, Base] : Aliases) {
983+
TargetList Targets;
984+
SymbolFlags Flags = SymbolFlags::None;
985+
if (const Symbol *Sym = Exports->findSymbol(Base.second, Base.first)) {
986+
Flags = Sym->getFlags();
987+
Targets = {Sym->targets().begin(), Sym->targets().end()};
988+
}
989+
990+
Record R(Alias.first, RecordLinkage::Exported, Flags);
991+
SymbolContext SymCtx;
992+
SymCtx.SymbolName = Alias.first;
993+
SymCtx.Kind = Alias.second;
994+
addSymbol(&R, SymCtx, std::move(Targets));
995+
}
996+
997+
return std::move(Exports);
998+
}
999+
9761000
} // namespace installapi
9771001
} // namespace clang

0 commit comments

Comments
 (0)