LLVM  8.0.1
TBEHandler.cpp
Go to the documentation of this file.
1 //===- TBEHandler.cpp -----------------------------------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===-----------------------------------------------------------------------===/
9 
11 #include "llvm/ADT/StringSwitch.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/Error.h"
16 
17 using namespace llvm;
18 using namespace llvm::elfabi;
19 
20 LLVM_YAML_STRONG_TYPEDEF(ELFArch, ELFArchMapper)
21 
22 namespace llvm {
23 namespace yaml {
24 
25 /// YAML traits for ELFSymbolType.
26 template <> struct ScalarEnumerationTraits<ELFSymbolType> {
27  static void enumeration(IO &IO, ELFSymbolType &SymbolType) {
28  IO.enumCase(SymbolType, "NoType", ELFSymbolType::NoType);
29  IO.enumCase(SymbolType, "Func", ELFSymbolType::Func);
30  IO.enumCase(SymbolType, "Object", ELFSymbolType::Object);
31  IO.enumCase(SymbolType, "TLS", ELFSymbolType::TLS);
32  IO.enumCase(SymbolType, "Unknown", ELFSymbolType::Unknown);
33  // Treat other symbol types as noise, and map to Unknown.
34  if (!IO.outputting() && IO.matchEnumFallback())
35  SymbolType = ELFSymbolType::Unknown;
36  }
37 };
38 
39 /// YAML traits for ELFArch.
40 template <> struct ScalarTraits<ELFArchMapper> {
41  static void output(const ELFArchMapper &Value, void *,
42  llvm::raw_ostream &Out) {
43  // Map from integer to architecture string.
44  switch (Value) {
45  case (ELFArch)ELF::EM_X86_64:
46  Out << "x86_64";
47  break;
49  Out << "AArch64";
50  break;
51  case (ELFArch)ELF::EM_NONE:
52  default:
53  Out << "Unknown";
54  }
55  }
56 
57  static StringRef input(StringRef Scalar, void *, ELFArchMapper &Value) {
58  // Map from architecture string to integer.
60  .Case("x86_64", ELF::EM_X86_64)
61  .Case("AArch64", ELF::EM_AARCH64)
62  .Case("Unknown", ELF::EM_NONE)
64 
65  // Returning empty StringRef indicates successful parse.
66  return StringRef();
67  }
68 
69  // Don't place quotation marks around architecture value.
70  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
71 };
72 
73 /// YAML traits for TbeVersion.
74 template <> struct ScalarTraits<VersionTuple> {
75  static void output(const VersionTuple &Value, void *,
76  llvm::raw_ostream &Out) {
77  Out << Value.getAsString();
78  }
79 
81  if (Value.tryParse(Scalar))
82  return StringRef("Can't parse version: invalid version format.");
83 
84  if (Value > TBEVersionCurrent)
85  return StringRef("Unsupported TBE version.");
86 
87  // Returning empty StringRef indicates successful parse.
88  return StringRef();
89  }
90 
91  // Don't place quotation marks around version value.
92  static QuotingType mustQuote(StringRef) { return QuotingType::None; }
93 };
94 
95 /// YAML traits for ELFSymbol.
96 template <> struct MappingTraits<ELFSymbol> {
97  static void mapping(IO &IO, ELFSymbol &Symbol) {
98  IO.mapRequired("Type", Symbol.Type);
99  // The need for symbol size depends on the symbol type.
100  if (Symbol.Type == ELFSymbolType::NoType) {
101  IO.mapOptional("Size", Symbol.Size, (uint64_t)0);
102  } else if (Symbol.Type == ELFSymbolType::Func) {
103  Symbol.Size = 0;
104  } else {
105  IO.mapRequired("Size", Symbol.Size);
106  }
107  IO.mapOptional("Undefined", Symbol.Undefined, false);
108  IO.mapOptional("Weak", Symbol.Weak, false);
109  IO.mapOptional("Warning", Symbol.Warning);
110  }
111 
112  // Compacts symbol information into a single line.
113  static const bool flow = true;
114 };
115 
116 /// YAML traits for set of ELFSymbols.
117 template <> struct CustomMappingTraits<std::set<ELFSymbol>> {
118  static void inputOne(IO &IO, StringRef Key, std::set<ELFSymbol> &Set) {
119  ELFSymbol Sym(Key.str());
120  IO.mapRequired(Key.str().c_str(), Sym);
121  Set.insert(Sym);
122  }
123 
124  static void output(IO &IO, std::set<ELFSymbol> &Set) {
125  for (auto &Sym : Set)
126  IO.mapRequired(Sym.Name.c_str(), const_cast<ELFSymbol &>(Sym));
127  }
128 };
129 
130 /// YAML traits for ELFStub objects.
131 template <> struct MappingTraits<ELFStub> {
132  static void mapping(IO &IO, ELFStub &Stub) {
133  if (!IO.mapTag("!tapi-tbe", true))
134  IO.setError("Not a .tbe YAML file.");
135  IO.mapRequired("TbeVersion", Stub.TbeVersion);
136  IO.mapOptional("SoName", Stub.SoName);
137  IO.mapRequired("Arch", (ELFArchMapper &)Stub.Arch);
138  IO.mapOptional("NeededLibs", Stub.NeededLibs);
139  IO.mapRequired("Symbols", Stub.Symbols);
140  }
141 };
142 
143 } // end namespace yaml
144 } // end namespace llvm
145 
147  yaml::Input YamlIn(Buf);
148  std::unique_ptr<ELFStub> Stub(new ELFStub());
149  YamlIn >> *Stub;
150  if (std::error_code Err = YamlIn.error())
151  return createStringError(Err, "YAML failed reading as TBE");
152 
153  return std::move(Stub);
154 }
155 
157  yaml::Output YamlOut(OS, NULL, /*WrapColumn =*/0);
158 
159  YamlOut << const_cast<ELFStub &>(Stub);
160  return Error::success();
161 }
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:228
static void output(const ELFArchMapper &Value, void *, llvm::raw_ostream &Out)
Definition: TBEHandler.cpp:41
std::set< ELFSymbol > Symbols
Definition: ELFStub.h:60
This class represents lattice values for constants.
Definition: AllocatorList.h:24
static void mapping(IO &IO, ELFStub &Stub)
Definition: TBEHandler.cpp:132
Definition: BitVector.h:938
Error writeTBEToOutputStream(raw_ostream &OS, const ELFStub &Stub)
Attempts to write an ELF interface file to a raw_ostream.
Definition: TBEHandler.cpp:156
Optional< std::string > Warning
Definition: ELFStub.h:45
static QuotingType mustQuote(StringRef)
Definition: TBEHandler.cpp:70
Tagged union holding either a T or a Error.
Definition: CachePruning.h:23
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE R Default(T Value)
Definition: StringSwitch.h:203
static void mapping(IO &IO, ELFSymbol &Symbol)
Definition: TBEHandler.cpp:97
Key
PAL metadata keys.
Optional< std::string > SoName
Definition: ELFStub.h:57
static QuotingType mustQuote(StringRef)
Definition: TBEHandler.cpp:92
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:43
static void inputOne(IO &IO, StringRef Key, std::set< ELFSymbol > &Set)
Definition: TBEHandler.cpp:118
static StringRef input(StringRef Scalar, void *, VersionTuple &Value)
Definition: TBEHandler.cpp:80
std::vector< std::string > NeededLibs
Definition: ELFStub.h:59
ELFSymbolType Type
Definition: ELFStub.h:42
const VersionTuple TBEVersionCurrent(1, 0)
uint16_t ELFArch
Definition: ELFStub.h:26
static ErrorSuccess success()
Create a success value.
Definition: Error.h:327
bool tryParse(StringRef string)
Try to parse the given string as a version number.
static void output(const VersionTuple &Value, void *, llvm::raw_ostream &Out)
Definition: TBEHandler.cpp:75
This file declares an interface for reading and writing .tbe (text-based ELF) files.
LLVM_ATTRIBUTE_ALWAYS_INLINE StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:70
Represents a version number in the form major[.minor[.subminor[.build]]].
Definition: VersionTuple.h:27
std::string getAsString() const
Retrieve a string representation of the version number.
This file defines an internal representation of an ELF stub.
static void enumeration(IO &IO, ELFSymbolType &SymbolType)
Definition: TBEHandler.cpp:27
static void output(IO &IO, std::set< ELFSymbol > &Set)
Definition: TBEHandler.cpp:124
LLVM Value Representation.
Definition: Value.h:73
Lightweight error class with error context and mandatory checking.
Definition: Error.h:158
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
static StringRef input(StringRef Scalar, void *, ELFArchMapper &Value)
Definition: TBEHandler.cpp:57
Expected< std::unique_ptr< ELFStub > > readTBEFromBuffer(StringRef Buf)
Attempts to read an ELF interface file from a StringRef buffer.
Definition: TBEHandler.cpp:146
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1164
VersionTuple TbeVersion
Definition: ELFStub.h:56