[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
This commit is contained in:
Alex Brachet 2022-02-18 19:13:55 +00:00
parent ff2e4c04c4
commit 1e116867db
4 changed files with 69 additions and 13 deletions

View File

@ -19,6 +19,8 @@
#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include <memory>
#include <string>
#include <vector>
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<std::string> &Exclude = {});
/// Parse llvm triple string into a IFSTarget struct.
IFSTarget parseTriple(StringRef TripleStr);

View File

@ -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;
@ -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();
}

View File

@ -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: ...

View File

@ -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",
@ -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));