Skip to content

Commit

Permalink
[ifs] Add --exclude flag
Browse files Browse the repository at this point in the history
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
  • Loading branch information
abrachet committed Feb 18, 2022
1 parent ff2e4c0 commit 1e11686
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 13 deletions.
6 changes: 4 additions & 2 deletions llvm/include/llvm/InterfaceStub/IFSHandler.h
Expand Up @@ -19,6 +19,8 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include <memory>
#include <string>
#include <vector>

namespace llvm {

Expand Down Expand Up @@ -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<std::string> &Exclude = {});

/// Parse llvm triple string into a IFSTarget struct.
IFSTarget parseTriple(StringRef TripleStr);
Expand Down
33 changes: 26 additions & 7 deletions llvm/lib/InterfaceStub/IFSHandler.cpp
Expand Up @@ -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 <functional>

using namespace llvm;
using namespace llvm::ifs;
Expand Down Expand Up @@ -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<std::string> &Exclude) {
std::function<bool(const IFSSymbol &)> Filter = [](const IFSSymbol &) {
return false;
};

if (StripUndefined) {
Filter = [Filter](const IFSSymbol &Sym) {
return Sym.Undefined || Filter(Sym);
};
}

for (StringRef Glob : Exclude) {
Expected<llvm::GlobPattern> 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();
}
30 changes: 30 additions & 0 deletions 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: ...
13 changes: 9 additions & 4 deletions llvm/tools/llvm-ifs/llvm-ifs.cpp
Expand Up @@ -106,6 +106,11 @@ cl::opt<bool>
cl::opt<bool> StripNeededLibs("strip-needed",
cl::desc("Strip needed libs from output"),
cl::cat(IfsCategory));
cl::list<std::string>
ExcludeSyms("exclude",
cl::desc("Remove symbols which match the pattern. Can be "
"specified multiple times"),
cl::cat(IfsCategory));

cl::opt<std::string>
SoName("soname",
Expand Down Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down

0 comments on commit 1e11686

Please sign in to comment.