From 1e116867dbc84ebc6e7165996a8bbef7261c3ccd Mon Sep 17 00:00:00 2001 From: Alex Brachet Date: Fri, 18 Feb 2022 19:13:55 +0000 Subject: [PATCH] [ifs] Add --exclude flag Use to remove certain symbols which match the glob pattern. Can be used with --strip-undefined Reviewed By: haowei, mcgrathr Differential Revision: https://reviews.llvm.org/D119962 --- llvm/include/llvm/InterfaceStub/IFSHandler.h | 6 +++-- llvm/lib/InterfaceStub/IFSHandler.cpp | 33 ++++++++++++++++++++++------ llvm/test/tools/llvm-ifs/exclude.test | 30 +++++++++++++++++++++++++ llvm/tools/llvm-ifs/llvm-ifs.cpp | 13 +++++++---- 4 files changed, 69 insertions(+), 13 deletions(-) create mode 100644 llvm/test/tools/llvm-ifs/exclude.test diff --git a/llvm/include/llvm/InterfaceStub/IFSHandler.h b/llvm/include/llvm/InterfaceStub/IFSHandler.h index 6ae6a42..bfa5692 100644 --- a/llvm/include/llvm/InterfaceStub/IFSHandler.h +++ b/llvm/include/llvm/InterfaceStub/IFSHandler.h @@ -19,6 +19,8 @@ #include "llvm/Support/Error.h" #include "llvm/Support/VersionTuple.h" #include +#include +#include namespace llvm { @@ -51,8 +53,8 @@ Error validateIFSTarget(IFSStub &Stub, bool ParseTriple); void stripIFSTarget(IFSStub &Stub, bool StripTriple, bool StripArch, bool StripEndianness, bool StripBitWidth); -/// Strips symbols from IFS symbol table that are undefined. -void stripIFSUndefinedSymbols(IFSStub &Stub); +Error filterIFSSyms(IFSStub &Stub, bool StripUndefined, + const std::vector &Exclude = {}); /// Parse llvm triple string into a IFSTarget struct. IFSTarget parseTriple(StringRef TripleStr); diff --git a/llvm/lib/InterfaceStub/IFSHandler.cpp b/llvm/lib/InterfaceStub/IFSHandler.cpp index 4ccbb18..92c8830 100644 --- a/llvm/lib/InterfaceStub/IFSHandler.cpp +++ b/llvm/lib/InterfaceStub/IFSHandler.cpp @@ -7,14 +7,17 @@ //===-----------------------------------------------------------------------===/ #include "llvm/InterfaceStub/IFSHandler.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Triple.h" #include "llvm/BinaryFormat/ELF.h" #include "llvm/InterfaceStub/IFSStub.h" #include "llvm/Support/Error.h" +#include "llvm/Support/GlobPattern.h" #include "llvm/Support/LineIterator.h" #include "llvm/Support/YAMLTraits.h" +#include using namespace llvm; using namespace llvm::ifs; @@ -328,12 +331,28 @@ void ifs::stripIFSTarget(IFSStub &Stub, bool StripTriple, bool StripArch, } } -void ifs::stripIFSUndefinedSymbols(IFSStub &Stub) { - for (auto Iter = Stub.Symbols.begin(); Iter != Stub.Symbols.end();) { - if (Iter->Undefined) { - Iter = Stub.Symbols.erase(Iter); - } else { - Iter++; - } +Error ifs::filterIFSSyms(IFSStub &Stub, bool StripUndefined, + const std::vector &Exclude) { + std::function Filter = [](const IFSSymbol &) { + return false; + }; + + if (StripUndefined) { + Filter = [Filter](const IFSSymbol &Sym) { + return Sym.Undefined || Filter(Sym); + }; + } + + for (StringRef Glob : Exclude) { + Expected PatternOrErr = llvm::GlobPattern::create(Glob); + if (!PatternOrErr) + return PatternOrErr.takeError(); + Filter = [Pattern = *PatternOrErr, Filter](const IFSSymbol &Sym) { + return Pattern.match(Sym.Name) || Filter(Sym); + }; } + + llvm::erase_if(Stub.Symbols, Filter); + + return Error::success(); } diff --git a/llvm/test/tools/llvm-ifs/exclude.test b/llvm/test/tools/llvm-ifs/exclude.test new file mode 100644 index 0000000..29f9ab8 --- /dev/null +++ b/llvm/test/tools/llvm-ifs/exclude.test @@ -0,0 +1,30 @@ +## Test --exclude flag + +# RUN: llvm-ifs --input-format=IFS --output-ifs=- --exclude='exclude*' %s | FileCheck %s + +# RUN: llvm-ifs --input-format=IFS --output-ifs=- --exclude='exclude*' \ +# RUN: --strip-undefined %s | FileCheck %s --check-prefix=BOTH + +# RUN: not llvm-ifs --input-format=IFS --output-ifs=- --exclude='[' %s 2>&1 | \ +# RUN: FileCheck %s --check-prefix=BAD-GLOB + +# BAD-GLOB: error: invalid glob pattern: [ + +--- !ifs-v1 +SoName: somelib.so +IfsVersion: 3.0 +Symbols: + - { Name: dont_exclude, Type: Func, Undefined: true } + - { Name: exclude_1, Type: Func } + - { Name: exclude_2, Type: Func, Undefined: true } + - { Name: no_match_not_undef, Type: Func } +... + +# CHECK: Symbols: +# CHECK-NEXT: - { Name: dont_exclude, Type: Func, Undefined: true } +# CHECK-NEXT: - { Name: no_match_not_undef, Type: Func } +# CHECK-NEXT: ... + +# BOTH: Symbols: +# BOTH-NEXT: - { Name: no_match_not_undef, Type: Func } +# BOTH-NEXT: ... diff --git a/llvm/tools/llvm-ifs/llvm-ifs.cpp b/llvm/tools/llvm-ifs/llvm-ifs.cpp index ef8864e..feced92 100644 --- a/llvm/tools/llvm-ifs/llvm-ifs.cpp +++ b/llvm/tools/llvm-ifs/llvm-ifs.cpp @@ -106,6 +106,11 @@ cl::opt cl::opt StripNeededLibs("strip-needed", cl::desc("Strip needed libs from output"), cl::cat(IfsCategory)); +cl::list + ExcludeSyms("exclude", + cl::desc("Remove symbols which match the pattern. Can be " + "specified multiple times"), + cl::cat(IfsCategory)); cl::opt SoName("soname", @@ -479,8 +484,8 @@ int main(int argc, char *argv[]) { stripIFSTarget(Stub, StripIFSTarget, StripIFSArch, StripIFSEndiannessWidth, StripIFSBitWidth); } - if (StripUndefined) - stripIFSUndefinedSymbols(Stub); + if (Error E = filterIFSSyms(Stub, StripUndefined, ExcludeSyms)) + fatalError(std::move(E)); Error IFSWriteError = writeIFS(OutputFilePath.getValue(), Stub); if (IFSWriteError) fatalError(std::move(IFSWriteError)); @@ -531,8 +536,8 @@ int main(int argc, char *argv[]) { stripIFSTarget(Stub, StripIFSTarget, StripIFSArch, StripIFSEndiannessWidth, StripIFSBitWidth); } - if (StripUndefined) - stripIFSUndefinedSymbols(Stub); + if (Error E = filterIFSSyms(Stub, StripUndefined, ExcludeSyms)) + fatalError(std::move(E)); Error IFSWriteError = writeIFS(OutputIFSFilePath.getValue(), Stub); if (IFSWriteError) fatalError(std::move(IFSWriteError)); -- 2.7.4