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