161fa9afeSHaowei Wu //===- IFSHandler.cpp -----------------------------------------------------===//
261fa9afeSHaowei Wu //
361fa9afeSHaowei Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
461fa9afeSHaowei Wu // See https://llvm.org/LICENSE.txt for license information.
561fa9afeSHaowei Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
661fa9afeSHaowei Wu //
761fa9afeSHaowei Wu //===-----------------------------------------------------------------------===/
861fa9afeSHaowei Wu
961fa9afeSHaowei Wu #include "llvm/InterfaceStub/IFSHandler.h"
101e116867SAlex Brachet #include "llvm/ADT/STLExtras.h"
1161fa9afeSHaowei Wu #include "llvm/ADT/StringRef.h"
1261fa9afeSHaowei Wu #include "llvm/ADT/StringSwitch.h"
1361fa9afeSHaowei Wu #include "llvm/BinaryFormat/ELF.h"
1461fa9afeSHaowei Wu #include "llvm/InterfaceStub/IFSStub.h"
1561fa9afeSHaowei Wu #include "llvm/Support/Error.h"
161e116867SAlex Brachet #include "llvm/Support/GlobPattern.h"
1761fa9afeSHaowei Wu #include "llvm/Support/LineIterator.h"
1861fa9afeSHaowei Wu #include "llvm/Support/YAMLTraits.h"
1962c7f035SArchibald Elliott #include "llvm/TargetParser/Triple.h"
201e116867SAlex Brachet #include <functional>
21c589730aSKrzysztof Parzyszek #include <optional>
2261fa9afeSHaowei Wu
2361fa9afeSHaowei Wu using namespace llvm;
246103fdfaSHaowei Wu using namespace llvm::ifs;
2561fa9afeSHaowei Wu
2661fa9afeSHaowei Wu LLVM_YAML_IS_SEQUENCE_VECTOR(IFSSymbol)
2761fa9afeSHaowei Wu
2861fa9afeSHaowei Wu namespace llvm {
2961fa9afeSHaowei Wu namespace yaml {
3061fa9afeSHaowei Wu
3161fa9afeSHaowei Wu /// YAML traits for ELFSymbolType.
3261fa9afeSHaowei Wu template <> struct ScalarEnumerationTraits<IFSSymbolType> {
enumerationllvm::yaml::ScalarEnumerationTraits3361fa9afeSHaowei Wu static void enumeration(IO &IO, IFSSymbolType &SymbolType) {
3461fa9afeSHaowei Wu IO.enumCase(SymbolType, "NoType", IFSSymbolType::NoType);
3561fa9afeSHaowei Wu IO.enumCase(SymbolType, "Func", IFSSymbolType::Func);
3661fa9afeSHaowei Wu IO.enumCase(SymbolType, "Object", IFSSymbolType::Object);
3761fa9afeSHaowei Wu IO.enumCase(SymbolType, "TLS", IFSSymbolType::TLS);
3861fa9afeSHaowei Wu IO.enumCase(SymbolType, "Unknown", IFSSymbolType::Unknown);
3961fa9afeSHaowei Wu // Treat other symbol types as noise, and map to Unknown.
4061fa9afeSHaowei Wu if (!IO.outputting() && IO.matchEnumFallback())
4161fa9afeSHaowei Wu SymbolType = IFSSymbolType::Unknown;
4261fa9afeSHaowei Wu }
4361fa9afeSHaowei Wu };
4461fa9afeSHaowei Wu
4561fa9afeSHaowei Wu template <> struct ScalarTraits<IFSEndiannessType> {
outputllvm::yaml::ScalarTraits4661fa9afeSHaowei Wu static void output(const IFSEndiannessType &Value, void *,
4761fa9afeSHaowei Wu llvm::raw_ostream &Out) {
4861fa9afeSHaowei Wu switch (Value) {
4961fa9afeSHaowei Wu case IFSEndiannessType::Big:
5061fa9afeSHaowei Wu Out << "big";
5161fa9afeSHaowei Wu break;
5261fa9afeSHaowei Wu case IFSEndiannessType::Little:
5361fa9afeSHaowei Wu Out << "little";
5461fa9afeSHaowei Wu break;
5561fa9afeSHaowei Wu default:
5661fa9afeSHaowei Wu llvm_unreachable("Unsupported endianness");
5761fa9afeSHaowei Wu }
5861fa9afeSHaowei Wu }
5961fa9afeSHaowei Wu
inputllvm::yaml::ScalarTraits6061fa9afeSHaowei Wu static StringRef input(StringRef Scalar, void *, IFSEndiannessType &Value) {
6161fa9afeSHaowei Wu Value = StringSwitch<IFSEndiannessType>(Scalar)
6261fa9afeSHaowei Wu .Case("big", IFSEndiannessType::Big)
6361fa9afeSHaowei Wu .Case("little", IFSEndiannessType::Little)
6461fa9afeSHaowei Wu .Default(IFSEndiannessType::Unknown);
6561fa9afeSHaowei Wu if (Value == IFSEndiannessType::Unknown) {
6661fa9afeSHaowei Wu return "Unsupported endianness";
6761fa9afeSHaowei Wu }
6861fa9afeSHaowei Wu return StringRef();
6961fa9afeSHaowei Wu }
7061fa9afeSHaowei Wu
mustQuotellvm::yaml::ScalarTraits7161fa9afeSHaowei Wu static QuotingType mustQuote(StringRef) { return QuotingType::None; }
7261fa9afeSHaowei Wu };
7361fa9afeSHaowei Wu
7461fa9afeSHaowei Wu template <> struct ScalarTraits<IFSBitWidthType> {
outputllvm::yaml::ScalarTraits7561fa9afeSHaowei Wu static void output(const IFSBitWidthType &Value, void *,
7661fa9afeSHaowei Wu llvm::raw_ostream &Out) {
7761fa9afeSHaowei Wu switch (Value) {
7861fa9afeSHaowei Wu case IFSBitWidthType::IFS32:
7961fa9afeSHaowei Wu Out << "32";
8061fa9afeSHaowei Wu break;
8161fa9afeSHaowei Wu case IFSBitWidthType::IFS64:
8261fa9afeSHaowei Wu Out << "64";
8361fa9afeSHaowei Wu break;
8461fa9afeSHaowei Wu default:
8561fa9afeSHaowei Wu llvm_unreachable("Unsupported bit width");
8661fa9afeSHaowei Wu }
8761fa9afeSHaowei Wu }
8861fa9afeSHaowei Wu
inputllvm::yaml::ScalarTraits8961fa9afeSHaowei Wu static StringRef input(StringRef Scalar, void *, IFSBitWidthType &Value) {
9061fa9afeSHaowei Wu Value = StringSwitch<IFSBitWidthType>(Scalar)
9161fa9afeSHaowei Wu .Case("32", IFSBitWidthType::IFS32)
9261fa9afeSHaowei Wu .Case("64", IFSBitWidthType::IFS64)
9361fa9afeSHaowei Wu .Default(IFSBitWidthType::Unknown);
9461fa9afeSHaowei Wu if (Value == IFSBitWidthType::Unknown) {
9561fa9afeSHaowei Wu return "Unsupported bit width";
9661fa9afeSHaowei Wu }
9761fa9afeSHaowei Wu return StringRef();
9861fa9afeSHaowei Wu }
9961fa9afeSHaowei Wu
mustQuotellvm::yaml::ScalarTraits10061fa9afeSHaowei Wu static QuotingType mustQuote(StringRef) { return QuotingType::None; }
10161fa9afeSHaowei Wu };
10261fa9afeSHaowei Wu
10361fa9afeSHaowei Wu template <> struct MappingTraits<IFSTarget> {
mappingllvm::yaml::MappingTraits10461fa9afeSHaowei Wu static void mapping(IO &IO, IFSTarget &Target) {
10561fa9afeSHaowei Wu IO.mapOptional("ObjectFormat", Target.ObjectFormat);
10661fa9afeSHaowei Wu IO.mapOptional("Arch", Target.ArchString);
10761fa9afeSHaowei Wu IO.mapOptional("Endianness", Target.Endianness);
10861fa9afeSHaowei Wu IO.mapOptional("BitWidth", Target.BitWidth);
10961fa9afeSHaowei Wu }
11061fa9afeSHaowei Wu
11161fa9afeSHaowei Wu // Compacts symbol information into a single line.
11261fa9afeSHaowei Wu static const bool flow = true; // NOLINT(readability-identifier-naming)
11361fa9afeSHaowei Wu };
11461fa9afeSHaowei Wu
11561fa9afeSHaowei Wu /// YAML traits for ELFSymbol.
11661fa9afeSHaowei Wu template <> struct MappingTraits<IFSSymbol> {
mappingllvm::yaml::MappingTraits11761fa9afeSHaowei Wu static void mapping(IO &IO, IFSSymbol &Symbol) {
11861fa9afeSHaowei Wu IO.mapRequired("Name", Symbol.Name);
11961fa9afeSHaowei Wu IO.mapRequired("Type", Symbol.Type);
12061fa9afeSHaowei Wu // The need for symbol size depends on the symbol type.
12161fa9afeSHaowei Wu if (Symbol.Type == IFSSymbolType::NoType) {
122a74d9e74SAlex Brachet // Size is None, so we are reading it in, or it is non 0 so we
123a74d9e74SAlex Brachet // should emit it.
124a74d9e74SAlex Brachet if (!Symbol.Size || *Symbol.Size)
125a74d9e74SAlex Brachet IO.mapOptional("Size", Symbol.Size);
126a74d9e74SAlex Brachet } else if (Symbol.Type != IFSSymbolType::Func) {
127a74d9e74SAlex Brachet IO.mapOptional("Size", Symbol.Size);
12861fa9afeSHaowei Wu }
12961fa9afeSHaowei Wu IO.mapOptional("Undefined", Symbol.Undefined, false);
13061fa9afeSHaowei Wu IO.mapOptional("Weak", Symbol.Weak, false);
13161fa9afeSHaowei Wu IO.mapOptional("Warning", Symbol.Warning);
13261fa9afeSHaowei Wu }
13361fa9afeSHaowei Wu
13461fa9afeSHaowei Wu // Compacts symbol information into a single line.
13561fa9afeSHaowei Wu static const bool flow = true; // NOLINT(readability-identifier-naming)
13661fa9afeSHaowei Wu };
13761fa9afeSHaowei Wu
13861fa9afeSHaowei Wu /// YAML traits for ELFStub objects.
13961fa9afeSHaowei Wu template <> struct MappingTraits<IFSStub> {
mappingllvm::yaml::MappingTraits14061fa9afeSHaowei Wu static void mapping(IO &IO, IFSStub &Stub) {
14161fa9afeSHaowei Wu if (!IO.mapTag("!ifs-v1", true))
14261fa9afeSHaowei Wu IO.setError("Not a .tbe YAML file.");
14361fa9afeSHaowei Wu IO.mapRequired("IfsVersion", Stub.IfsVersion);
14461fa9afeSHaowei Wu IO.mapOptional("SoName", Stub.SoName);
14561fa9afeSHaowei Wu IO.mapOptional("Target", Stub.Target);
14661fa9afeSHaowei Wu IO.mapOptional("NeededLibs", Stub.NeededLibs);
14761fa9afeSHaowei Wu IO.mapRequired("Symbols", Stub.Symbols);
14861fa9afeSHaowei Wu }
14961fa9afeSHaowei Wu };
15061fa9afeSHaowei Wu
15161fa9afeSHaowei Wu /// YAML traits for ELFStubTriple objects.
15261fa9afeSHaowei Wu template <> struct MappingTraits<IFSStubTriple> {
mappingllvm::yaml::MappingTraits15361fa9afeSHaowei Wu static void mapping(IO &IO, IFSStubTriple &Stub) {
15461fa9afeSHaowei Wu if (!IO.mapTag("!ifs-v1", true))
15561fa9afeSHaowei Wu IO.setError("Not a .tbe YAML file.");
15661fa9afeSHaowei Wu IO.mapRequired("IfsVersion", Stub.IfsVersion);
15761fa9afeSHaowei Wu IO.mapOptional("SoName", Stub.SoName);
15861fa9afeSHaowei Wu IO.mapOptional("Target", Stub.Target.Triple);
15961fa9afeSHaowei Wu IO.mapOptional("NeededLibs", Stub.NeededLibs);
16061fa9afeSHaowei Wu IO.mapRequired("Symbols", Stub.Symbols);
16161fa9afeSHaowei Wu }
16261fa9afeSHaowei Wu };
16361fa9afeSHaowei Wu } // end namespace yaml
16461fa9afeSHaowei Wu } // end namespace llvm
16561fa9afeSHaowei Wu
16661fa9afeSHaowei Wu /// Attempt to determine if a Text stub uses target triple.
usesTriple(StringRef Buf)16761fa9afeSHaowei Wu bool usesTriple(StringRef Buf) {
16861fa9afeSHaowei Wu for (line_iterator I(MemoryBufferRef(Buf, "ELFStub")); !I.is_at_eof(); ++I) {
16961fa9afeSHaowei Wu StringRef Line = (*I).trim();
170586ecdf2SKazu Hirata if (Line.starts_with("Target:")) {
171d14d7068SKazu Hirata if (Line == "Target:" || Line.contains("{")) {
17261fa9afeSHaowei Wu return false;
17361fa9afeSHaowei Wu }
17461fa9afeSHaowei Wu }
17561fa9afeSHaowei Wu }
17661fa9afeSHaowei Wu return true;
17761fa9afeSHaowei Wu }
17861fa9afeSHaowei Wu
readIFSFromBuffer(StringRef Buf)1796103fdfaSHaowei Wu Expected<std::unique_ptr<IFSStub>> ifs::readIFSFromBuffer(StringRef Buf) {
18061fa9afeSHaowei Wu yaml::Input YamlIn(Buf);
18161fa9afeSHaowei Wu std::unique_ptr<IFSStubTriple> Stub(new IFSStubTriple());
18261fa9afeSHaowei Wu if (usesTriple(Buf)) {
18361fa9afeSHaowei Wu YamlIn >> *Stub;
18461fa9afeSHaowei Wu } else {
18561fa9afeSHaowei Wu YamlIn >> *static_cast<IFSStub *>(Stub.get());
18661fa9afeSHaowei Wu }
18761fa9afeSHaowei Wu if (std::error_code Err = YamlIn.error()) {
18861fa9afeSHaowei Wu return createStringError(Err, "YAML failed reading as IFS");
18961fa9afeSHaowei Wu }
19061fa9afeSHaowei Wu
1916103fdfaSHaowei Wu if (Stub->IfsVersion > IFSVersionCurrent)
19261fa9afeSHaowei Wu return make_error<StringError>(
19361fa9afeSHaowei Wu "IFS version " + Stub->IfsVersion.getAsString() + " is unsupported.",
19461fa9afeSHaowei Wu std::make_error_code(std::errc::invalid_argument));
19561fa9afeSHaowei Wu if (Stub->Target.ArchString) {
196420526fbSHaowei Wu uint16_t eMachine =
1977a47ee51SKazu Hirata ELF::convertArchNameToEMachine(*Stub->Target.ArchString);
198420526fbSHaowei Wu if (eMachine == ELF::EM_NONE)
199420526fbSHaowei Wu return createStringError(
200420526fbSHaowei Wu std::make_error_code(std::errc::invalid_argument),
201420526fbSHaowei Wu "IFS arch '" + *Stub->Target.ArchString + "' is unsupported");
202420526fbSHaowei Wu Stub->Target.Arch = eMachine;
20361fa9afeSHaowei Wu }
204*8e9c5319SHaowei for (const auto &Item : Stub->Symbols) {
205*8e9c5319SHaowei if (Item.Type == IFSSymbolType::Unknown)
206*8e9c5319SHaowei return createStringError(
207*8e9c5319SHaowei std::make_error_code(std::errc::invalid_argument),
208*8e9c5319SHaowei "IFS symbol type for symbol '" + Item.Name + "' is unsupported");
209*8e9c5319SHaowei }
21061fa9afeSHaowei Wu return std::move(Stub);
21161fa9afeSHaowei Wu }
21261fa9afeSHaowei Wu
writeIFSToOutputStream(raw_ostream & OS,const IFSStub & Stub)2136103fdfaSHaowei Wu Error ifs::writeIFSToOutputStream(raw_ostream &OS, const IFSStub &Stub) {
2145a667c0eSKazu Hirata yaml::Output YamlOut(OS, nullptr, /*WrapColumn =*/0);
21561fa9afeSHaowei Wu std::unique_ptr<IFSStubTriple> CopyStub(new IFSStubTriple(Stub));
21661fa9afeSHaowei Wu if (Stub.Target.Arch) {
217611ffcf4SKazu Hirata CopyStub->Target.ArchString =
2182fa744e6SFangrui Song std::string(ELF::convertEMachineToArchName(*Stub.Target.Arch));
21961fa9afeSHaowei Wu }
22061fa9afeSHaowei Wu IFSTarget Target = Stub.Target;
22161fa9afeSHaowei Wu
22261fa9afeSHaowei Wu if (CopyStub->Target.Triple ||
22361fa9afeSHaowei Wu (!CopyStub->Target.ArchString && !CopyStub->Target.Endianness &&
22461fa9afeSHaowei Wu !CopyStub->Target.BitWidth))
22561fa9afeSHaowei Wu YamlOut << *CopyStub;
22661fa9afeSHaowei Wu else
22761fa9afeSHaowei Wu YamlOut << *static_cast<IFSStub *>(CopyStub.get());
22861fa9afeSHaowei Wu return Error::success();
22961fa9afeSHaowei Wu }
23061fa9afeSHaowei Wu
overrideIFSTarget(IFSStub & Stub,std::optional<IFSArch> OverrideArch,std::optional<IFSEndiannessType> OverrideEndianness,std::optional<IFSBitWidthType> OverrideBitWidth,std::optional<std::string> OverrideTriple)231c589730aSKrzysztof Parzyszek Error ifs::overrideIFSTarget(
232c589730aSKrzysztof Parzyszek IFSStub &Stub, std::optional<IFSArch> OverrideArch,
233c589730aSKrzysztof Parzyszek std::optional<IFSEndiannessType> OverrideEndianness,
234c589730aSKrzysztof Parzyszek std::optional<IFSBitWidthType> OverrideBitWidth,
235c589730aSKrzysztof Parzyszek std::optional<std::string> OverrideTriple) {
23661fa9afeSHaowei Wu std::error_code OverrideEC(1, std::generic_category());
23761fa9afeSHaowei Wu if (OverrideArch) {
238036e0922SFangrui Song if (Stub.Target.Arch && *Stub.Target.Arch != *OverrideArch) {
23961fa9afeSHaowei Wu return make_error<StringError>(
24061fa9afeSHaowei Wu "Supplied Arch conflicts with the text stub", OverrideEC);
24161fa9afeSHaowei Wu }
2422fa744e6SFangrui Song Stub.Target.Arch = *OverrideArch;
24361fa9afeSHaowei Wu }
24461fa9afeSHaowei Wu if (OverrideEndianness) {
24561fa9afeSHaowei Wu if (Stub.Target.Endianness &&
246036e0922SFangrui Song *Stub.Target.Endianness != *OverrideEndianness) {
24761fa9afeSHaowei Wu return make_error<StringError>(
24861fa9afeSHaowei Wu "Supplied Endianness conflicts with the text stub", OverrideEC);
24961fa9afeSHaowei Wu }
2502fa744e6SFangrui Song Stub.Target.Endianness = *OverrideEndianness;
25161fa9afeSHaowei Wu }
25261fa9afeSHaowei Wu if (OverrideBitWidth) {
253036e0922SFangrui Song if (Stub.Target.BitWidth && *Stub.Target.BitWidth != *OverrideBitWidth) {
25461fa9afeSHaowei Wu return make_error<StringError>(
25561fa9afeSHaowei Wu "Supplied BitWidth conflicts with the text stub", OverrideEC);
25661fa9afeSHaowei Wu }
2572fa744e6SFangrui Song Stub.Target.BitWidth = *OverrideBitWidth;
25861fa9afeSHaowei Wu }
25961fa9afeSHaowei Wu if (OverrideTriple) {
260036e0922SFangrui Song if (Stub.Target.Triple && *Stub.Target.Triple != *OverrideTriple) {
26161fa9afeSHaowei Wu return make_error<StringError>(
26261fa9afeSHaowei Wu "Supplied Triple conflicts with the text stub", OverrideEC);
26361fa9afeSHaowei Wu }
2642fa744e6SFangrui Song Stub.Target.Triple = *OverrideTriple;
26561fa9afeSHaowei Wu }
26661fa9afeSHaowei Wu return Error::success();
26761fa9afeSHaowei Wu }
26861fa9afeSHaowei Wu
validateIFSTarget(IFSStub & Stub,bool ParseTriple)2696103fdfaSHaowei Wu Error ifs::validateIFSTarget(IFSStub &Stub, bool ParseTriple) {
27061fa9afeSHaowei Wu std::error_code ValidationEC(1, std::generic_category());
27161fa9afeSHaowei Wu if (Stub.Target.Triple) {
27261fa9afeSHaowei Wu if (Stub.Target.Arch || Stub.Target.BitWidth || Stub.Target.Endianness ||
27361fa9afeSHaowei Wu Stub.Target.ObjectFormat) {
27461fa9afeSHaowei Wu return make_error<StringError>(
27561fa9afeSHaowei Wu "Target triple cannot be used simultaneously with ELF target format",
27661fa9afeSHaowei Wu ValidationEC);
27761fa9afeSHaowei Wu }
27861fa9afeSHaowei Wu if (ParseTriple) {
2797a47ee51SKazu Hirata IFSTarget TargetFromTriple = parseTriple(*Stub.Target.Triple);
28061fa9afeSHaowei Wu Stub.Target.Arch = TargetFromTriple.Arch;
28161fa9afeSHaowei Wu Stub.Target.BitWidth = TargetFromTriple.BitWidth;
28261fa9afeSHaowei Wu Stub.Target.Endianness = TargetFromTriple.Endianness;
28361fa9afeSHaowei Wu }
28461fa9afeSHaowei Wu return Error::success();
28561fa9afeSHaowei Wu }
28661fa9afeSHaowei Wu if (!Stub.Target.Arch || !Stub.Target.BitWidth || !Stub.Target.Endianness) {
28761fa9afeSHaowei Wu // TODO: unify the error message.
28861fa9afeSHaowei Wu if (!Stub.Target.Arch) {
28961fa9afeSHaowei Wu return make_error<StringError>("Arch is not defined in the text stub",
29061fa9afeSHaowei Wu ValidationEC);
29161fa9afeSHaowei Wu }
29261fa9afeSHaowei Wu if (!Stub.Target.BitWidth) {
29361fa9afeSHaowei Wu return make_error<StringError>("BitWidth is not defined in the text stub",
29461fa9afeSHaowei Wu ValidationEC);
29561fa9afeSHaowei Wu }
29661fa9afeSHaowei Wu if (!Stub.Target.Endianness) {
29761fa9afeSHaowei Wu return make_error<StringError>(
29861fa9afeSHaowei Wu "Endianness is not defined in the text stub", ValidationEC);
29961fa9afeSHaowei Wu }
30061fa9afeSHaowei Wu }
30161fa9afeSHaowei Wu return Error::success();
30261fa9afeSHaowei Wu }
30361fa9afeSHaowei Wu
parseTriple(StringRef TripleStr)3046103fdfaSHaowei Wu IFSTarget ifs::parseTriple(StringRef TripleStr) {
30561fa9afeSHaowei Wu Triple IFSTriple(TripleStr);
30661fa9afeSHaowei Wu IFSTarget RetTarget;
30761fa9afeSHaowei Wu // TODO: Implement a Triple Arch enum to e_machine map.
30861fa9afeSHaowei Wu switch (IFSTriple.getArch()) {
30961fa9afeSHaowei Wu case Triple::ArchType::aarch64:
31061fa9afeSHaowei Wu RetTarget.Arch = (IFSArch)ELF::EM_AARCH64;
31161fa9afeSHaowei Wu break;
31261fa9afeSHaowei Wu case Triple::ArchType::x86_64:
31361fa9afeSHaowei Wu RetTarget.Arch = (IFSArch)ELF::EM_X86_64;
31461fa9afeSHaowei Wu break;
315c53eff55SAlex Brachet case Triple::ArchType::riscv64:
316c53eff55SAlex Brachet RetTarget.Arch = (IFSArch)ELF::EM_RISCV;
317c53eff55SAlex Brachet break;
31861fa9afeSHaowei Wu default:
31961fa9afeSHaowei Wu RetTarget.Arch = (IFSArch)ELF::EM_NONE;
32061fa9afeSHaowei Wu }
32161fa9afeSHaowei Wu RetTarget.Endianness = IFSTriple.isLittleEndian() ? IFSEndiannessType::Little
32261fa9afeSHaowei Wu : IFSEndiannessType::Big;
32361fa9afeSHaowei Wu RetTarget.BitWidth =
32461fa9afeSHaowei Wu IFSTriple.isArch64Bit() ? IFSBitWidthType::IFS64 : IFSBitWidthType::IFS32;
32561fa9afeSHaowei Wu return RetTarget;
32661fa9afeSHaowei Wu }
32761fa9afeSHaowei Wu
stripIFSTarget(IFSStub & Stub,bool StripTriple,bool StripArch,bool StripEndianness,bool StripBitWidth)3286103fdfaSHaowei Wu void ifs::stripIFSTarget(IFSStub &Stub, bool StripTriple, bool StripArch,
32961fa9afeSHaowei Wu bool StripEndianness, bool StripBitWidth) {
33061fa9afeSHaowei Wu if (StripTriple || StripArch) {
33161fa9afeSHaowei Wu Stub.Target.Arch.reset();
33261fa9afeSHaowei Wu Stub.Target.ArchString.reset();
33361fa9afeSHaowei Wu }
33461fa9afeSHaowei Wu if (StripTriple || StripEndianness) {
33561fa9afeSHaowei Wu Stub.Target.Endianness.reset();
33661fa9afeSHaowei Wu }
33761fa9afeSHaowei Wu if (StripTriple || StripBitWidth) {
33861fa9afeSHaowei Wu Stub.Target.BitWidth.reset();
33961fa9afeSHaowei Wu }
34061fa9afeSHaowei Wu if (StripTriple) {
34161fa9afeSHaowei Wu Stub.Target.Triple.reset();
34261fa9afeSHaowei Wu }
34361fa9afeSHaowei Wu if (!Stub.Target.Arch && !Stub.Target.BitWidth && !Stub.Target.Endianness) {
34461fa9afeSHaowei Wu Stub.Target.ObjectFormat.reset();
34561fa9afeSHaowei Wu }
34661fa9afeSHaowei Wu }
34731e61c58SHaowei Wu
filterIFSSyms(IFSStub & Stub,bool StripUndefined,const std::vector<std::string> & Exclude)3481e116867SAlex Brachet Error ifs::filterIFSSyms(IFSStub &Stub, bool StripUndefined,
3491e116867SAlex Brachet const std::vector<std::string> &Exclude) {
3501e116867SAlex Brachet std::function<bool(const IFSSymbol &)> Filter = [](const IFSSymbol &) {
3511e116867SAlex Brachet return false;
3521e116867SAlex Brachet };
3531e116867SAlex Brachet
3541e116867SAlex Brachet if (StripUndefined) {
3551e116867SAlex Brachet Filter = [Filter](const IFSSymbol &Sym) {
3561e116867SAlex Brachet return Sym.Undefined || Filter(Sym);
3571e116867SAlex Brachet };
35831e61c58SHaowei Wu }
3591e116867SAlex Brachet
3601e116867SAlex Brachet for (StringRef Glob : Exclude) {
3611e116867SAlex Brachet Expected<llvm::GlobPattern> PatternOrErr = llvm::GlobPattern::create(Glob);
3621e116867SAlex Brachet if (!PatternOrErr)
3631e116867SAlex Brachet return PatternOrErr.takeError();
3641e116867SAlex Brachet Filter = [Pattern = *PatternOrErr, Filter](const IFSSymbol &Sym) {
3651e116867SAlex Brachet return Pattern.match(Sym.Name) || Filter(Sym);
3661e116867SAlex Brachet };
36731e61c58SHaowei Wu }
3681e116867SAlex Brachet
3691e116867SAlex Brachet llvm::erase_if(Stub.Symbols, Filter);
3701e116867SAlex Brachet
3711e116867SAlex Brachet return Error::success();
37231e61c58SHaowei Wu }
373