diff --git a/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td b/clang/include/clang/Basic/DiagnosticInstallAPIKinds.td index 396bff0146a37..91a40cd589b38 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 e24626913add7..8c38acb72362c 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, HelpText<"Extract API information">; diff --git a/clang/include/clang/InstallAPI/DylibVerifier.h b/clang/include/clang/InstallAPI/DylibVerifier.h index 31de212fc423a..ae0428abbb9c7 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()), 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 getExports() { return std::move(Exports); } + std::unique_ptr takeExports(); /// 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 854399f54ba6c..9da91a62e2331 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 84d9b5892e88d..216b5eb799cb3 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 ProvidedTargets, return true; } +std::unique_ptr DylibVerifier::takeExports() { + 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 0000000000000..3e12221e088c4 --- /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/test/InstallAPI/mismatching-objc-class-symbols.test b/clang/test/InstallAPI/mismatching-objc-class-symbols.test index 3b4acf1035ace..ee35f81c58b3c 100644 --- a/clang/test/InstallAPI/mismatching-objc-class-symbols.test +++ b/clang/test/InstallAPI/mismatching-objc-class-symbols.test @@ -19,7 +19,7 @@ ; RUN: llvm-readtapi -compare %t/mismatching.tbd %t/mismatching-expected.tbd // Try out a dylib that only has 1 symbol for a ObjCClass, but is represented in header. -; RUN: clang-installapi -target arm64-apple-macos14 \ +; RUN: clang-installapi -target arm64-apple-macos14 -dynamiclib \ ; RUN: -install_name tmp.dylib --verify-against=%t/libswift-objc.dylib \ ; RUN: -I%t/usr/include %t/inputs.json -o %t/matching.tbd \ ; RUN: --verify-mode=Pedantic \ diff --git a/clang/tools/clang-installapi/ClangInstallAPI.cpp b/clang/tools/clang-installapi/ClangInstallAPI.cpp index fd71aaec59435..add28ab4fcda2 100644 --- a/clang/tools/clang-installapi/ClangInstallAPI.cpp +++ b/clang/tools/clang-installapi/ClangInstallAPI.cpp @@ -147,7 +147,7 @@ static bool run(ArrayRef 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); diff --git a/clang/tools/clang-installapi/Options.cpp b/clang/tools/clang-installapi/Options.cpp index 3dc61476ce09d..191e944ae91e0 100644 --- a/clang/tools/clang-installapi/Options.cpp +++ b/clang/tools/clang-installapi/Options.cpp @@ -261,6 +261,11 @@ bool Options::processLinkerOptions(InputArgList &Args) { 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, /*Default=*/LinkerOpts.AppExtensionSafe); @@ -684,6 +689,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 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 +871,7 @@ InstallAPIContext Options::createContext() { } Ctx.Verifier = std::make_unique( - 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 984366c94e91c..e9ac75889ad30 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 alias symbol files. + 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 ebfe88984f803..87550851f091e 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 #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 createRegexFromGlob(llvm::StringRef Glob); +using AliasEntry = std::pair; +using AliasMap = std::map; + +/// 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 parseAliasList(std::unique_ptr &Buffer); + } // namespace llvm::MachO #endif // LLVM_TEXTAPI_UTILS_H diff --git a/llvm/lib/TextAPI/Utils.cpp b/llvm/lib/TextAPI/Utils.cpp index c541645044955..3b5e11e29de4a 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 llvm::MachO::createRegexFromGlob(StringRef Glob) { return std::move(Rule); } + +Expected +llvm::MachO::parseAliasList(std::unique_ptr &Buffer) { + SmallVector 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(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; +}