[clang] [llvm] [InstallAPI] Add support for aliased exports (PR #88750)
Cyndy Ishida via cfe-commits
cfe-commits at lists.llvm.org
Mon Apr 15 10:24:42 PDT 2024
https://github.com/cyndyishida updated https://github.com/llvm/llvm-project/pull/88750
>From b2b54ad8ccf930a19327563a64c52c9f4013103f Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Thu, 11 Apr 2024 13:13:45 -0700
Subject: [PATCH 1/3] [InstallAPI] Add support for aliased exports
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.
---
.../clang/Basic/DiagnosticInstallAPIKinds.td | 1 +
clang/include/clang/Driver/Options.td | 1 +
.../include/clang/InstallAPI/DylibVerifier.h | 15 +-
clang/include/clang/InstallAPI/MachO.h | 1 +
clang/lib/InstallAPI/DylibVerifier.cpp | 24 +
clang/test/InstallAPI/alias_list.test | 461 ++++++++++++++++++
clang/tools/clang-installapi/Options.cpp | 24 +-
clang/tools/clang-installapi/Options.h | 3 +
llvm/include/llvm/TextAPI/Utils.h | 12 +
llvm/lib/TextAPI/Utils.cpp | 34 ++
10 files changed, 569 insertions(+), 7 deletions(-)
create mode 100644 clang/test/InstallAPI/alias_list.test
diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
index 396bff0146a373..91a40cd589b385 100644
--- a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
+++ b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td
@@ -24,6 +24,7 @@ def err_no_matching_target : Error<"no matching target found for target variant
def err_unsupported_vendor : Error<"vendor '%0' is not supported: '%1'">;
def err_unsupported_environment : Error<"environment '%0' is not supported: '%1'">;
def err_unsupported_os : Error<"os '%0' is not supported: '%1'">;
+def err_cannot_read_alias_list : Error<"could not read alias list '%0': %1">;
} // end of command line category.
let CategoryName = "Verification" in {
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index e24626913add76..8c38acb72362c7 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1505,6 +1505,7 @@ def end_no_unused_arguments : Flag<["--"], "end-no-unused-arguments">,
def interface_stub_version_EQ : JoinedOrSeparate<["-"], "interface-stub-version=">,
Visibility<[ClangOption, CC1Option]>;
def exported__symbols__list : Separate<["-"], "exported_symbols_list">;
+def alias_list : Separate<["-"], "alias_list">, Flags<[LinkerInput]>;
def extract_api : Flag<["-"], "extract-api">,
Visibility<[ClangOption, CC1Option]>, Group<Action_Group>,
HelpText<"Extract API information">;
diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h
index 31de212fc423a5..f1a949d8f99394 100644
--- a/clang/include/clang/InstallAPI/DylibVerifier.h
+++ b/clang/include/clang/InstallAPI/DylibVerifier.h
@@ -78,10 +78,12 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
DylibVerifier() = default;
DylibVerifier(llvm::MachO::Records &&Dylib, ReexportedInterfaces &&Reexports,
- DiagnosticsEngine *Diag, VerificationMode Mode, bool Zippered,
- bool Demangle, StringRef DSYMPath)
- : Dylib(std::move(Dylib)), Reexports(std::move(Reexports)), Mode(Mode),
- Zippered(Zippered), Demangle(Demangle), DSYMPath(DSYMPath),
+ AliasMap Aliases, DiagnosticsEngine *Diag,
+ VerificationMode Mode, bool Zippered, bool Demangle,
+ StringRef DSYMPath)
+ : Dylib(std::move(Dylib)), Reexports(std::move(Reexports)),
+ Aliases(std::move(Aliases)), Mode(Mode), Zippered(Zippered),
+ Demangle(Demangle), DSYMPath(DSYMPath),
Exports(std::make_unique<SymbolSet>()), Ctx(VerifierContext{Diag}) {}
Result verify(GlobalRecord *R, const FrontendAttrs *FA);
@@ -104,7 +106,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
void setTarget(const Target &T);
/// Release ownership over exports.
- std::unique_ptr<SymbolSet> getExports() { return std::move(Exports); }
+ std::unique_ptr<SymbolSet> getExports();
/// Get result of verification.
Result getState() const { return Ctx.FrontendState; }
@@ -189,6 +191,9 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
// Reexported interfaces apart of the library.
ReexportedInterfaces Reexports;
+ // Symbol aliases.
+ AliasMap Aliases;
+
// Controls what class of violations to report.
VerificationMode Mode = VerificationMode::Invalid;
diff --git a/clang/include/clang/InstallAPI/MachO.h b/clang/include/clang/InstallAPI/MachO.h
index 854399f54ba6c8..9da91a62e23311 100644
--- a/clang/include/clang/InstallAPI/MachO.h
+++ b/clang/include/clang/InstallAPI/MachO.h
@@ -23,6 +23,7 @@
#include "llvm/TextAPI/TextAPIWriter.h"
#include "llvm/TextAPI/Utils.h"
+using AliasMap = llvm::MachO::AliasMap;
using Architecture = llvm::MachO::Architecture;
using ArchitectureSet = llvm::MachO::ArchitectureSet;
using SymbolFlags = llvm::MachO::SymbolFlags;
diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp
index 84d9b5892e88da..27b28e59105983 100644
--- a/clang/lib/InstallAPI/DylibVerifier.cpp
+++ b/clang/lib/InstallAPI/DylibVerifier.cpp
@@ -674,6 +674,11 @@ void DylibVerifier::visitSymbolInDylib(const Record &R, SymbolContext &SymCtx) {
return;
}
+ if (Aliases.count({SymbolName.str(), SymCtx.Kind})) {
+ updateState(Result::Valid);
+ return;
+ }
+
// All checks at this point classify as some kind of violation.
// The different verification modes dictate whether they are reported to the
// user.
@@ -973,5 +978,24 @@ bool DylibVerifier::verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
return true;
}
+std::unique_ptr<SymbolSet> DylibVerifier::getExports() {
+ for (const auto &[Alias, Base] : Aliases) {
+ TargetList Targets;
+ SymbolFlags Flags = SymbolFlags::None;
+ if (const Symbol *Sym = Exports->findSymbol(Base.second, Base.first)) {
+ Flags = Sym->getFlags();
+ Targets = {Sym->targets().begin(), Sym->targets().end()};
+ }
+
+ Record R(Alias.first, RecordLinkage::Exported, Flags);
+ SymbolContext SymCtx;
+ SymCtx.SymbolName = Alias.first;
+ SymCtx.Kind = Alias.second;
+ addSymbol(&R, SymCtx, std::move(Targets));
+ }
+
+ return std::move(Exports);
+}
+
} // namespace installapi
} // namespace clang
diff --git a/clang/test/InstallAPI/alias_list.test b/clang/test/InstallAPI/alias_list.test
new file mode 100644
index 00000000000000..3e12221e088c4b
--- /dev/null
+++ b/clang/test/InstallAPI/alias_list.test
@@ -0,0 +1,461 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: sed -e "s|DSTROOT|%/t|g" %t/inputs.json.in > %t/inputs.json
+; RUN: yaml2obj %t/AliasList.yaml -o %t/Frameworks/AliasList.framework/AliasList
+
+; RUN: clang-installapi --target=x86_64-apple-macos13 \
+; RUN: -alias_list %t/aliases.txt \
+; RUN: -install_name /System/Library/Frameworks/AliasList.framework/Versions/A/AliasList \
+; RUN: -current_version 1 -compatibility_version 1 \
+; RUN: -F%t/Frameworks -ObjC %t/inputs.json --verify-mode=Pedantic \
+; RUN: --verify-against=%t/Frameworks/AliasList.framework/AliasList \
+; RUN: -o %t/AliasList.tbd 2>&1 | FileCheck -allow-empty %s \
+; RUN: --implicit-check-not=error --implicit-check-not=warning
+; RUN: llvm-readtapi -compare %t/expected.tbd %t/AliasList.tbd
+
+// Check error handling.
+; RUN: not clang-installapi --target=x86_64-apple-macos13 \
+; RUN: -alias_list %t/invalid.txt \
+; RUN: -install_name /System/Library/Frameworks/AliasList.framework/Versions/A/AliasList \
+; RUN: -current_version 1 -compatibility_version 1 \
+; RUN: -F%t/Frameworks -ObjC %t/inputs.json --verify-mode=Pedantic \
+; RUN: --verify-against=%t/Frameworks/AliasList.framework/AliasList \
+; RUN: -o %t/AliasList.tbd 2>&1 | FileCheck -allow-empty %s \
+; RUN: --check-prefix=INVALID
+
+; INVALID: error: could not read alias list {{.*}} missing alias for: _hidden
+
+;--- Frameworks/AliasList.framework/Headers/AliasList.h
+// simple alias from one symbol to another.
+extern int simple_symbol;
+extern int alias_symbol;
+
+// This symbol comes from the alias file.
+extern int exported_symbol;
+
+// This symbol was moved here and has several special hide symbols in the alias
+// file.
+extern int moved_here_symbol;
+
+// This alias is public, whereas the source is private.
+extern int public_symbol;
+
+;--- Frameworks/AliasList.framework/PrivateHeaders/AliasList_Private.h
+// This is a private symbol that has a public alias.
+extern int private_symbol;
+
+;--- aliases.txt
+# comment
+_simple_symbol _alias_symbol
+# test multiple space characters separated symbol and alias
+_hidden_symbol _exported_symbol # test inline comment with spaces
+# test tab character separated symbol and alias
+_moved_here_symbol $ld$hide$os10.4$_moved_here_symbol# test inline comment without spaces
+# test trailing space character
+_moved_here_symbol $ld$hide$os10.5$_moved_here_symbol
+# test trailing tab character
+_moved_here_symbol $ld$hide$os10.6$_moved_here_symbol
+_private_symbol _public_symbol
+
+;--- invalid.txt
+# comment
+_simple_symbol _alias_symbol
+_hidden # no matching
+
+;--- expected.tbd
+{
+ "main_library": {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_exported_symbol", "_simple_symbol", "_moved_here_symbol",
+ "$ld$hide$os10.6$_moved_here_symbol", "$ld$hide$os10.4$_moved_here_symbol",
+ "$ld$hide$os10.5$_moved_here_symbol", "_public_symbol",
+ "_private_symbol", "_alias_symbol"
+ ]
+ }
+ }
+ ],
+ "flags": [
+ {
+ "attributes": [
+ "not_app_extension_safe"
+ ]
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/System/Library/Frameworks/AliasList.framework/Versions/A/AliasList"
+ }
+ ],
+ "target_info": [
+ {
+ "min_deployment": "13",
+ "target": "x86_64-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+;--- AliasList.yaml
+--- !mach-o
+FileHeader:
+ magic: 0xFEEDFACF
+ cputype: 0x1000007
+ cpusubtype: 0x3
+ filetype: 0x6
+ ncmds: 13
+ sizeofcmds: 920
+ flags: 0x100085
+ reserved: 0x0
+LoadCommands:
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __TEXT
+ vmaddr: 0
+ vmsize: 4096
+ fileoff: 0
+ filesize: 4096
+ maxprot: 5
+ initprot: 5
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __text
+ segname: __TEXT
+ addr: 0xBB8
+ size: 0
+ offset: 0xBB8
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x80000000
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: ''
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA_CONST
+ vmaddr: 4096
+ vmsize: 4096
+ fileoff: 4096
+ filesize: 4096
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 16
+ Sections:
+ - sectname: __objc_imageinfo
+ segname: __DATA_CONST
+ addr: 0x1000
+ size: 8
+ offset: 0x1000
+ align: 0
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x0
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ content: '0000000040000000'
+ - cmd: LC_SEGMENT_64
+ cmdsize: 152
+ segname: __DATA
+ vmaddr: 8192
+ vmsize: 4096
+ fileoff: 8192
+ filesize: 0
+ maxprot: 3
+ initprot: 3
+ nsects: 1
+ flags: 0
+ Sections:
+ - sectname: __common
+ segname: __DATA
+ addr: 0x2000
+ size: 40
+ offset: 0x0
+ align: 2
+ reloff: 0x0
+ nreloc: 0
+ flags: 0x1
+ reserved1: 0x0
+ reserved2: 0x0
+ reserved3: 0x0
+ - cmd: LC_SEGMENT_64
+ cmdsize: 72
+ segname: __LINKEDIT
+ vmaddr: 12288
+ vmsize: 672
+ fileoff: 8192
+ filesize: 672
+ maxprot: 1
+ initprot: 1
+ nsects: 0
+ flags: 0
+ - cmd: LC_DYLD_INFO_ONLY
+ cmdsize: 48
+ rebase_off: 0
+ rebase_size: 0
+ bind_off: 0
+ bind_size: 0
+ weak_bind_off: 0
+ weak_bind_size: 0
+ lazy_bind_off: 0
+ lazy_bind_size: 0
+ export_off: 8192
+ export_size: 248
+ - cmd: LC_SYMTAB
+ cmdsize: 24
+ symoff: 8448
+ nsyms: 11
+ stroff: 8624
+ strsize: 240
+ - cmd: LC_DYSYMTAB
+ cmdsize: 80
+ ilocalsym: 0
+ nlocalsym: 1
+ iextdefsym: 1
+ nextdefsym: 9
+ iundefsym: 10
+ nundefsym: 1
+ tocoff: 0
+ ntoc: 0
+ modtaboff: 0
+ nmodtab: 0
+ extrefsymoff: 0
+ nextrefsyms: 0
+ indirectsymoff: 0
+ nindirectsyms: 0
+ extreloff: 0
+ nextrel: 0
+ locreloff: 0
+ nlocrel: 0
+ - cmd: LC_ID_DYLIB
+ cmdsize: 96
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 65536
+ compatibility_version: 65536
+ Content: '/System/Library/Frameworks/AliasList.framework/Versions/A/AliasList'
+ ZeroPadBytes: 5
+ - cmd: LC_UUID
+ cmdsize: 24
+ uuid: 4C4C4468-5555-3144-A123-B0FDB87F9813
+ - cmd: LC_BUILD_VERSION
+ cmdsize: 32
+ platform: 1
+ minos: 851968
+ sdk: 983040
+ ntools: 1
+ Tools:
+ - tool: 4
+ version: 1245184
+ - cmd: LC_LOAD_DYLIB
+ cmdsize: 56
+ dylib:
+ name: 24
+ timestamp: 0
+ current_version: 88539136
+ compatibility_version: 65536
+ Content: '/usr/lib/libSystem.B.dylib'
+ ZeroPadBytes: 6
+ - cmd: LC_FUNCTION_STARTS
+ cmdsize: 16
+ dataoff: 8440
+ datasize: 8
+ - cmd: LC_DATA_IN_CODE
+ cmdsize: 16
+ dataoff: 8448
+ datasize: 0
+LinkEditData:
+ ExportTrie:
+ TerminalSize: 0
+ NodeOffset: 0
+ Name: ''
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 0
+ NodeOffset: 21
+ Name: '$ld$hide$os10.'
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 89
+ Name: '4$_moved_here_symbol'
+ Flags: 0x0
+ Address: 0x2000
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 94
+ Name: '6$_moved_here_symbol'
+ Flags: 0x0
+ Address: 0x2008
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 99
+ Name: '5$_moved_here_symbol'
+ Flags: 0x0
+ Address: 0x2004
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 0
+ NodeOffset: 104
+ Name: _
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 179
+ Name: alias_symbol
+ Flags: 0x0
+ Address: 0x2024
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 0
+ NodeOffset: 184
+ Name: p
+ Flags: 0x0
+ Address: 0x0
+ Other: 0x0
+ ImportName: ''
+ Children:
+ - TerminalSize: 3
+ NodeOffset: 217
+ Name: ublic_symbol
+ Flags: 0x0
+ Address: 0x2020
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 222
+ Name: rivate_symbol
+ Flags: 0x0
+ Address: 0x2018
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 227
+ Name: simple_symbol
+ Flags: 0x0
+ Address: 0x200C
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 232
+ Name: moved_here_symbol
+ Flags: 0x0
+ Address: 0x2014
+ Other: 0x0
+ ImportName: ''
+ - TerminalSize: 3
+ NodeOffset: 237
+ Name: exported_symbol
+ Flags: 0x0
+ Address: 0x201C
+ Other: 0x0
+ ImportName: ''
+ NameList:
+ - n_strx: 122
+ n_type: 0x1E
+ n_sect: 3
+ n_desc: 0
+ n_value: 8208
+ - n_strx: 2
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8192
+ - n_strx: 37
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8196
+ - n_strx: 72
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8200
+ - n_strx: 107
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8204
+ - n_strx: 137
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8212
+ - n_strx: 156
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8216
+ - n_strx: 172
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8220
+ - n_strx: 189
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8224
+ - n_strx: 204
+ n_type: 0xF
+ n_sect: 3
+ n_desc: 0
+ n_value: 8228
+ - n_strx: 218
+ n_type: 0x1
+ n_sect: 0
+ n_desc: 256
+ n_value: 0
+ StringTable:
+ - ' '
+ - '$ld$hide$os10.4$_moved_here_symbol'
+ - '$ld$hide$os10.5$_moved_here_symbol'
+ - '$ld$hide$os10.6$_moved_here_symbol'
+ - _simple_symbol
+ - _hidden_symbol
+ - _moved_here_symbol
+ - _private_symbol
+ - _exported_symbol
+ - _public_symbol
+ - _alias_symbol
+ - dyld_stub_binder
+ - ''
+ - ''
+ - ''
+ - ''
+ - ''
+...
+
+;--- inputs.json.in
+{
+ "headers": [
+ {
+ "path" : "DSTROOT/Frameworks/AliasList.framework/Headers/AliasList.h",
+ "type" : "public"
+ },
+ {
+ "path" : "DSTROOT/Frameworks/AliasList.framework/PrivateHeaders/AliasList_Private.h",
+ "type" : "private"
+ }
+ ],
+ "version": "3"
+}
diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp
index 3dc61476ce09d9..26c7f13721a3eb 100644
--- a/clang/tools/clang-installapi/Options.cpp
+++ b/clang/tools/clang-installapi/Options.cpp
@@ -259,7 +259,10 @@ bool Options::processLinkerOptions(InputArgList &Args) {
if (auto *Arg = Args.getLastArg(drv::OPT_umbrella))
LinkerOpts.ParentUmbrella = Arg->getValue();
- LinkerOpts.IsDylib = Args.hasArg(drv::OPT_dynamiclib);
+ for (auto *Arg : Args.filtered(drv::OPT_alias_list)) {
+ LinkerOpts.AliasLists.emplace_back(Arg->getValue());
+ Arg->claim();
+ }
LinkerOpts.AppExtensionSafe = Args.hasFlag(
drv::OPT_fapplication_extension, drv::OPT_fno_application_extension,
@@ -684,6 +687,23 @@ InstallAPIContext Options::createContext() {
return Ctx;
Ctx.Reexports = Reexports;
+ // Collect symbols from alias lists.
+ AliasMap Aliases;
+ for (const StringRef ListPath : LinkerOpts.AliasLists) {
+ auto Buffer = FM->getBufferForFile(ListPath);
+ if (auto Err = Buffer.getError()) {
+ Diags->Report(diag::err_cannot_open_file) << ListPath << Err.message();
+ return Ctx;
+ }
+ Expected<AliasMap> Result = parseAliasList(Buffer.get());
+ if (!Result) {
+ Diags->Report(diag::err_cannot_read_alias_list)
+ << ListPath << toString(Result.takeError());
+ return Ctx;
+ }
+ Aliases.insert(Result.get().begin(), Result.get().end());
+ }
+
// Attempt to find umbrella headers by capturing framework name.
StringRef FrameworkName;
if (!LinkerOpts.IsDylib)
@@ -849,7 +869,7 @@ InstallAPIContext Options::createContext() {
}
Ctx.Verifier = std::make_unique<DylibVerifier>(
- std::move(*Slices), std::move(ReexportedIFs), Diags,
+ std::move(*Slices), std::move(ReexportedIFs), std::move(Aliases), Diags,
DriverOpts.VerifyMode, DriverOpts.Zippered, DriverOpts.Demangle,
DriverOpts.DSYMPath);
return Ctx;
diff --git a/clang/tools/clang-installapi/Options.h b/clang/tools/clang-installapi/Options.h
index 984366c94e91ce..f7424c0e3cfd6e 100644
--- a/clang/tools/clang-installapi/Options.h
+++ b/clang/tools/clang-installapi/Options.h
@@ -107,6 +107,9 @@ struct LinkerOptions {
/// \brief Additional library search paths.
PathSeq LibPaths;
+ /// \brief List of aliased symbol exports.
+ PathSeq AliasLists;
+
/// \brief The install name to use for the dynamic library.
std::string InstallName;
diff --git a/llvm/include/llvm/TextAPI/Utils.h b/llvm/include/llvm/TextAPI/Utils.h
index ebfe88984f8034..87550851f091ef 100644
--- a/llvm/include/llvm/TextAPI/Utils.h
+++ b/llvm/include/llvm/TextAPI/Utils.h
@@ -16,8 +16,11 @@
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/Regex.h"
+#include "llvm/TextAPI/Symbol.h"
+#include <map>
#if !defined(PATH_MAX)
#define PATH_MAX 1024
@@ -75,5 +78,14 @@ bool isPrivateLibrary(StringRef Path, bool IsSymLink = false);
/// \return The equivalent regex rule.
llvm::Expected<llvm::Regex> createRegexFromGlob(llvm::StringRef Glob);
+using AliasEntry = std::pair<std::string, EncodeKind>;
+using AliasMap = std::map<AliasEntry, AliasEntry>;
+
+/// Parse input list and capture symbols and their alias.
+///
+/// \param Buffer Data contents of file for the alias list.
+/// \return Lookup table of alias to their base symbol.
+Expected<AliasMap> parseAliasList(std::unique_ptr<llvm::MemoryBuffer> &Buffer);
+
} // namespace llvm::MachO
#endif // LLVM_TEXTAPI_UTILS_H
diff --git a/llvm/lib/TextAPI/Utils.cpp b/llvm/lib/TextAPI/Utils.cpp
index c541645044955c..3b5e11e29de4a3 100644
--- a/llvm/lib/TextAPI/Utils.cpp
+++ b/llvm/lib/TextAPI/Utils.cpp
@@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/TextAPI/Utils.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/TextAPI/TextAPIError.h"
using namespace llvm;
using namespace llvm::MachO;
@@ -198,3 +200,35 @@ llvm::Expected<Regex> llvm::MachO::createRegexFromGlob(StringRef Glob) {
return std::move(Rule);
}
+
+Expected<AliasMap>
+llvm::MachO::parseAliasList(std::unique_ptr<llvm::MemoryBuffer> &Buffer) {
+ SmallVector<StringRef, 16> Lines;
+ AliasMap Aliases;
+ Buffer->getBuffer().split(Lines, "\n", /*MaxSplit=*/-1,
+ /*KeepEmpty=*/false);
+ for (const StringRef Line : Lines) {
+ StringRef L = Line.trim();
+ if (L.empty())
+ continue;
+ // Skip comments.
+ if (L.starts_with("#"))
+ continue;
+ StringRef Symbol, Remain, Alias;
+ // Base symbol is seperated by whitespace.
+ std::tie(Symbol, Remain) = getToken(L);
+ // The Alias symbol ends before a comment or EOL.
+ std::tie(Alias, Remain) = getToken(Remain, "#");
+ Alias = Alias.trim();
+ if (Alias.empty())
+ return make_error<TextAPIError>(
+ TextAPIError(TextAPIErrorCode::InvalidInputFormat,
+ ("missing alias for: " + Symbol).str()));
+ SimpleSymbol AliasSym = parseSymbol(Alias);
+ SimpleSymbol BaseSym = parseSymbol(Symbol);
+ Aliases[{AliasSym.Name.str(), AliasSym.Kind}] = {BaseSym.Name.str(),
+ BaseSym.Kind};
+ }
+
+ return Aliases;
+}
>From 1c4e55a96df43c9427605f2529589a2655d60f38 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Mon, 15 Apr 2024 10:05:34 -0700
Subject: [PATCH 2/3] Apply feedback suggestion.
Co-authored-by: Juergen Ributzka <juergen at ributzka.de>
---
clang/tools/clang-installapi/Options.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/tools/clang-installapi/Options.h b/clang/tools/clang-installapi/Options.h
index f7424c0e3cfd6e..e9ac75889ad30c 100644
--- a/clang/tools/clang-installapi/Options.h
+++ b/clang/tools/clang-installapi/Options.h
@@ -107,7 +107,7 @@ struct LinkerOptions {
/// \brief Additional library search paths.
PathSeq LibPaths;
- /// \brief List of aliased symbol exports.
+ /// \brief List of alias symbol files.
PathSeq AliasLists;
/// \brief The install name to use for the dynamic library.
>From 7edf27b0b53ba6011c9e7f3ee42f47626acd7027 Mon Sep 17 00:00:00 2001
From: Cyndy Ishida <cyndy_ishida at apple.com>
Date: Mon, 15 Apr 2024 10:20:04 -0700
Subject: [PATCH 3/3] s/getExports/takeExports/g
---
clang/include/clang/InstallAPI/DylibVerifier.h | 2 +-
clang/lib/InstallAPI/DylibVerifier.cpp | 2 +-
clang/tools/clang-installapi/ClangInstallAPI.cpp | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h
index f1a949d8f99394..ae0428abbb9c71 100644
--- a/clang/include/clang/InstallAPI/DylibVerifier.h
+++ b/clang/include/clang/InstallAPI/DylibVerifier.h
@@ -106,7 +106,7 @@ class DylibVerifier : llvm::MachO::RecordVisitor {
void setTarget(const Target &T);
/// Release ownership over exports.
- std::unique_ptr<SymbolSet> getExports();
+ std::unique_ptr<SymbolSet> takeExports();
/// Get result of verification.
Result getState() const { return Ctx.FrontendState; }
diff --git a/clang/lib/InstallAPI/DylibVerifier.cpp b/clang/lib/InstallAPI/DylibVerifier.cpp
index 27b28e59105983..216b5eb799cb34 100644
--- a/clang/lib/InstallAPI/DylibVerifier.cpp
+++ b/clang/lib/InstallAPI/DylibVerifier.cpp
@@ -978,7 +978,7 @@ bool DylibVerifier::verifyBinaryAttrs(const ArrayRef<Target> ProvidedTargets,
return true;
}
-std::unique_ptr<SymbolSet> DylibVerifier::getExports() {
+std::unique_ptr<SymbolSet> DylibVerifier::takeExports() {
for (const auto &[Alias, Base] : Aliases) {
TargetList Targets;
SymbolFlags Flags = SymbolFlags::None;
diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp
index fd71aaec59435b..add28ab4fcda20 100644
--- a/clang/tools/clang-installapi/ClangInstallAPI.cpp
+++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp
@@ -147,7 +147,7 @@ static bool run(ArrayRef<const char *> Args, const char *ProgName) {
return EXIT_FAILURE;
// Assign attributes for serialization.
- InterfaceFile IF(Ctx.Verifier->getExports());
+ InterfaceFile IF(Ctx.Verifier->takeExports());
// Assign attributes that are the same per slice first.
for (const auto &TargetInfo : Opts.DriverOpts.Targets) {
IF.addTarget(TargetInfo.first);
More information about the cfe-commits
mailing list