1 //===- IFSStub.h ------------------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===-----------------------------------------------------------------------===/
8 ///
9 /// \file
10 /// This file defines an internal representation of an InterFace Stub.
11 ///
12 //===-----------------------------------------------------------------------===/
13 
14 #ifndef LLVM_INTERFACESTUB_IFSSTUB_H
15 #define LLVM_INTERFACESTUB_IFSSTUB_H
16 
17 #include "llvm/Support/VersionTuple.h"
18 #include <optional>
19 #include <vector>
20 
21 namespace llvm {
22 namespace ifs {
23 
24 typedef uint16_t IFSArch;
25 
26 enum class IFSSymbolType {
27   NoType,
28   Object,
29   Func,
30   TLS,
31 
32   // Type information is 4 bits, so 16 is safely out of range.
33   Unknown = 16,
34 };
35 
36 enum class IFSEndiannessType {
37   Little,
38   Big,
39 
40   // Endianness info is 1 bytes, 256 is safely out of range.
41   Unknown = 256,
42 };
43 
44 enum class IFSBitWidthType {
45   IFS32,
46   IFS64,
47 
48   // Bit width info is 1 bytes, 256 is safely out of range.
49   Unknown = 256,
50 };
51 
52 struct IFSSymbol {
53   IFSSymbol() = default;
54   explicit IFSSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {}
55   std::string Name;
56   std::optional<uint64_t> Size;
57   IFSSymbolType Type = IFSSymbolType::NoType;
58   bool Undefined = false;
59   bool Weak = false;
60   std::optional<std::string> Warning;
61   bool operator<(const IFSSymbol &RHS) const { return Name < RHS.Name; }
62 };
63 
64 struct IFSTarget {
65   std::optional<std::string> Triple;
66   std::optional<std::string> ObjectFormat;
67   std::optional<IFSArch> Arch;
68   std::optional<std::string> ArchString;
69   std::optional<IFSEndiannessType> Endianness;
70   std::optional<IFSBitWidthType> BitWidth;
71 
72   bool empty();
73 };
74 
75 inline bool operator==(const IFSTarget &Lhs, const IFSTarget &Rhs) {
76   if (Lhs.Arch != Rhs.Arch || Lhs.BitWidth != Rhs.BitWidth ||
77       Lhs.Endianness != Rhs.Endianness ||
78       Lhs.ObjectFormat != Rhs.ObjectFormat || Lhs.Triple != Rhs.Triple)
79     return false;
80   return true;
81 }
82 
83 inline bool operator!=(const IFSTarget &Lhs, const IFSTarget &Rhs) {
84   return !(Lhs == Rhs);
85 }
86 
87 // A cumulative representation of InterFace stubs.
88 // Both textual and binary stubs will read into and write from this object.
89 struct IFSStub {
90   // TODO: Add support for symbol versioning.
91   VersionTuple IfsVersion;
92   std::optional<std::string> SoName;
93   IFSTarget Target;
94   std::vector<std::string> NeededLibs;
95   std::vector<IFSSymbol> Symbols;
96 
97   IFSStub() = default;
98   IFSStub(const IFSStub &Stub);
99   IFSStub(IFSStub &&Stub);
100   virtual ~IFSStub() = default;
101 };
102 
103 // Create a alias class for IFSStub.
104 // LLVM's YAML library does not allow mapping a class with 2 traits,
105 // which prevents us using 'Target:' field with different definitions.
106 // This class makes it possible to map a second traits so the same data
107 // structure can be used for 2 different yaml schema.
108 struct IFSStubTriple : IFSStub {
109   IFSStubTriple() = default;
110   IFSStubTriple(const IFSStub &Stub);
111   IFSStubTriple(const IFSStubTriple &Stub);
112   IFSStubTriple(IFSStubTriple &&Stub);
113 };
114 
115 /// This function convert bit width type from IFS enum to ELF format
116 /// Currently, ELFCLASS32 and ELFCLASS64 are supported.
117 ///
118 /// @param BitWidth IFS bit width type.
119 uint8_t convertIFSBitWidthToELF(IFSBitWidthType BitWidth);
120 
121 /// This function convert endianness type from IFS enum to ELF format
122 /// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
123 ///
124 /// @param Endianness IFS endianness type.
125 uint8_t convertIFSEndiannessToELF(IFSEndiannessType Endianness);
126 
127 /// This function convert symbol type from IFS enum to ELF format
128 /// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
129 ///
130 /// @param SymbolType IFS symbol type.
131 uint8_t convertIFSSymbolTypeToELF(IFSSymbolType SymbolType);
132 
133 /// This function extracts ELF bit width from e_ident[EI_CLASS] of an ELF file
134 /// Currently, ELFCLASS32 and ELFCLASS64 are supported.
135 /// Other endianness types are mapped to IFSBitWidthType::Unknown.
136 ///
137 /// @param BitWidth e_ident[EI_CLASS] value to extract bit width from.
138 IFSBitWidthType convertELFBitWidthToIFS(uint8_t BitWidth);
139 
140 /// This function extracts ELF endianness from e_ident[EI_DATA] of an ELF file
141 /// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
142 /// Other endianness types are mapped to IFSEndiannessType::Unknown.
143 ///
144 /// @param Endianness e_ident[EI_DATA] value to extract endianness type from.
145 IFSEndiannessType convertELFEndiannessToIFS(uint8_t Endianness);
146 
147 /// This function extracts symbol type from a symbol's st_info member and
148 /// maps it to an IFSSymbolType enum.
149 /// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
150 /// Other symbol types are mapped to IFSSymbolType::Unknown.
151 ///
152 /// @param SymbolType Binary symbol st_info to extract symbol type from.
153 IFSSymbolType convertELFSymbolTypeToIFS(uint8_t SymbolType);
154 } // namespace ifs
155 } // end namespace llvm
156 
157 #endif // LLVM_INTERFACESTUB_IFSSTUB_H
158