From cd74b2f83b532f75235c878fa8f8591de5dcd4da Mon Sep 17 00:00:00 2001 From: Hsin-Yi Chen Date: Fri, 12 Apr 2024 20:10:26 +0800 Subject: Add header-abi-linker -symbol-tag-policy The command line option supports the policies to filter llndk, apex and systemapi. Usage: `-api 34 -include-symbol-tag llndk=202404 -symbol-tag-policy MatchTagOnly` includes the symbols tagged with "llndk=202404", "introduced=34", or "llndk=202404 introduced=35". `-api 34 -include-symbol-tag apex -symbol-tag-policy MatchTagAndApi` includes the symbols tagged with "apex" or "introduced=34", but excludes those tagged with "apex introduced=35". Test: LD_LIBRARY_PATH=out/soong/dist/lib64 \ out/soong/host/linux-x86/nativetest64/header-checker-unittests/header-checker-unittests Bug: 314010764 Change-Id: I6517e902e2b648bfefedb914caf800cd47408c37 --- .../src/linker/header_abi_linker.cpp | 14 ++++ .../src/repr/symbol/version_script_parser.cpp | 17 ++++- .../src/repr/symbol/version_script_parser.h | 8 ++ .../src/repr/symbol/version_script_parser_test.cpp | 87 +++++++++++++++++----- 4 files changed, 105 insertions(+), 21 deletions(-) diff --git a/vndk/tools/header-checker/src/linker/header_abi_linker.cpp b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp index a12677796..3ca3b0715 100644 --- a/vndk/tools/header-checker/src/linker/header_abi_linker.cpp +++ b/vndk/tools/header-checker/src/linker/header_abi_linker.cpp @@ -37,6 +37,7 @@ using namespace header_checker; +using header_checker::repr::ModeTagPolicy; using header_checker::repr::TextFormatIR; using header_checker::utils::CollectAllExportedHeaders; using header_checker::utils::HideIrrelevantCommandLineOptions; @@ -102,6 +103,18 @@ static llvm::cl::opt api_map( "API levels."), llvm::cl::Optional, llvm::cl::cat(header_linker_category)); +static llvm::cl::opt symbol_tag_policy( + "symbol-tag-policy", + llvm::cl::desc("Specify how to match -include-symbol-tag."), + llvm::cl::values(clEnumValN(ModeTagPolicy::MatchTagAndApi, "MatchTagAndApi", + "If a symbol has mode tags, match both the " + "mode tags and the \"introduced\" tag."), + clEnumValN(ModeTagPolicy::MatchTagOnly, "MatchTagOnly", + "If a symbol has mode tags, match the mode " + "tags and ignore the \"introduced\" tag.")), + llvm::cl::init(ModeTagPolicy::MatchTagAndApi), + llvm::cl::cat(header_linker_category)); + static llvm::cl::opt arch( "arch", llvm::cl::desc(""), llvm::cl::Optional, llvm::cl::cat(header_linker_category)); @@ -496,6 +509,7 @@ static bool InitializeVersionScriptParser(repr::VersionScriptParser &parser) { return false; } } + parser.SetModeTagPolicy(symbol_tag_policy); return true; } diff --git a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp index 931064b21..2fc9bf4ea 100644 --- a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.cpp @@ -185,6 +185,10 @@ VersionScriptParser::ParsedTags VersionScriptParser::ParseSymbolTags( bool VersionScriptParser::MatchModeTags(const ParsedTags &tags) { + if (included_mode_tags_.empty()) { + // Include all tags if the user does not specify the option. + return true; + } for (const auto &mode_tag : tags.mode_tags_) { auto included_mode_tag = included_mode_tags_.find(mode_tag.first); if (included_mode_tag != included_mode_tags_.end() && @@ -216,11 +220,18 @@ bool VersionScriptParser::IsSymbolExported(const ParsedTags &tags) { return false; } - if (!included_mode_tags_.empty() && !tags.mode_tags_.empty()) { - return MatchModeTags(tags); + if (tags.mode_tags_.empty()) { + return MatchIntroducedTags(tags); } - return MatchIntroducedTags(tags); + switch (mode_tag_policy_) { + case MatchTagAndApi: + return MatchModeTags(tags) && MatchIntroducedTags(tags); + case MatchTagOnly: + return MatchModeTags(tags); + } + // Unreachable + return false; } diff --git a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h index 0f468b55d..818450a61 100644 --- a/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser.h @@ -28,6 +28,11 @@ namespace header_checker { namespace repr { +enum ModeTagPolicy { + MatchTagAndApi, + MatchTagOnly, +}; + class VersionScriptParser { private: // This comparison function allows finding elements by string_view. @@ -89,6 +94,8 @@ class VersionScriptParser { // Returns whether the argument is valid. bool AddModeTag(std::string_view mode_tag); + void SetModeTagPolicy(ModeTagPolicy policy) { mode_tag_policy_ = policy; } + void SetErrorHandler(std::unique_ptr error_handler) { error_handler_ = std::move(error_handler); } @@ -133,6 +140,7 @@ class VersionScriptParser { utils::StringSet excluded_symbol_versions_; utils::StringSet excluded_symbol_tags_; ModeTagLevelMap included_mode_tags_; + ModeTagPolicy mode_tag_policy_; std::istream *stream_; int line_no_; diff --git a/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp b/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp index 41955f3b0..ed079c8a0 100644 --- a/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp +++ b/vndk/tools/header-checker/src/repr/symbol/version_script_parser_test.cpp @@ -363,14 +363,11 @@ TEST(VersionScriptParserTest, IncludeSymbolTags) { always; # unknown api34; # introduced=34 api35; # introduced=35 - api35_llndk202404; # introduced=35 llndk=202404 + llndk202404; # llndk=202404 + llndk202504; # llndk=202504 systemapi; # systemapi systemapi_llndk; # systemapi llndk }; - LIBEX_2.0 { # introduced=36 - api36_llndk202504; - api36_llndk202504; # llndk=202504 - }; )TESTDATA"; { @@ -384,9 +381,8 @@ TEST(VersionScriptParserTest, IncludeSymbolTags) { const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); - EXPECT_THAT(funcs, - ElementsAre(Key("always"), Key("api34"), - Key("api35_llndk202404"), Key("systemapi_llndk"))); + EXPECT_THAT(funcs, ElementsAre(Key("always"), Key("api34"), + Key("llndk202404"), Key("systemapi_llndk"))); } { @@ -400,10 +396,9 @@ TEST(VersionScriptParserTest, IncludeSymbolTags) { const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); - EXPECT_THAT( - funcs, - ElementsAre(Key("always"), Key("api34"), Key("api35_llndk202404"), - Key("api36_llndk202504"), Key("systemapi_llndk"))); + EXPECT_THAT(funcs, + ElementsAre(Key("always"), Key("api34"), Key("llndk202404"), + Key("llndk202504"), Key("systemapi_llndk"))); } // Include all mode tags @@ -417,10 +412,9 @@ TEST(VersionScriptParserTest, IncludeSymbolTags) { const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); - EXPECT_THAT(funcs, - ElementsAre(Key("always"), Key("api34"), Key("api35"), - Key("api35_llndk202404"), Key("api36_llndk202504"), - Key("systemapi"), Key("systemapi_llndk"))); + EXPECT_THAT(funcs, ElementsAre(Key("always"), Key("api34"), Key("api35"), + Key("llndk202404"), Key("llndk202504"), + Key("systemapi"), Key("systemapi_llndk"))); } // Exclude all mode tags @@ -435,8 +429,65 @@ TEST(VersionScriptParserTest, IncludeSymbolTags) { const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); - EXPECT_THAT(funcs, ElementsAre(Key("always"), Key("api34"), Key("api35"), - Key("api36_llndk202504"))); + EXPECT_THAT(funcs, ElementsAre(Key("always"), Key("api34"), Key("api35"))); + } +} + + +TEST(VersionScriptParserTest, SetModeTagPolicy) { + static const char testdata[] = R"TESTDATA( + LIBEX_1.0 { # introduced=36 + api36; + api36_llndk202504; + api36_llndk202504; # llndk=202504 + llndk202504; # llndk=202504 + }; + )TESTDATA"; + + { + VersionScriptParser parser; + parser.SetApiLevel(35); + parser.AddModeTag("llndk=202504"); + parser.SetModeTagPolicy(ModeTagPolicy::MatchTagAndApi); + + std::istringstream stream(testdata); + std::unique_ptr result(parser.Parse(stream)); + ASSERT_TRUE(result); + + const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); + + EXPECT_TRUE(funcs.empty()); + } + + { + VersionScriptParser parser; + parser.SetApiLevel(35); + parser.AddModeTag("llndk=202504"); + parser.SetModeTagPolicy(ModeTagPolicy::MatchTagOnly); + + std::istringstream stream(testdata); + std::unique_ptr result(parser.Parse(stream)); + ASSERT_TRUE(result); + + const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); + + EXPECT_THAT(funcs, + ElementsAre(Key("api36_llndk202504"), Key("llndk202504"))); + } + + { + VersionScriptParser parser; + parser.SetApiLevel(36); + parser.SetModeTagPolicy(ModeTagPolicy::MatchTagAndApi); + + std::istringstream stream(testdata); + std::unique_ptr result(parser.Parse(stream)); + ASSERT_TRUE(result); + + const ExportedSymbolSet::FunctionMap &funcs = result->GetFunctions(); + + EXPECT_THAT(funcs, ElementsAre(Key("api36"), Key("api36_llndk202504"), + Key("llndk202504"))); } } -- cgit v1.2.3