aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/llvm/include/llvm/InterfaceStub/IFSStub.h
blob: 8c3cd171b1a2b2312e0fee9847d9d09aa50dfa1c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//===- IFSStub.h ------------------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===-----------------------------------------------------------------------===/
///
/// \file
/// This file defines an internal representation of an InterFace Stub.
///
//===-----------------------------------------------------------------------===/

#ifndef LLVM_INTERFACESTUB_IFSSTUB_H
#define LLVM_INTERFACESTUB_IFSSTUB_H

#include "llvm/Support/Error.h"
#include "llvm/Support/VersionTuple.h"
#include <set>
#include <vector>

namespace llvm {
namespace ifs {

typedef uint16_t IFSArch;

enum class IFSSymbolType {
  NoType,
  Object,
  Func,
  TLS,

  // Type information is 4 bits, so 16 is safely out of range.
  Unknown = 16,
};

enum class IFSEndiannessType {
  Little,
  Big,

  // Endianness info is 1 bytes, 256 is safely out of range.
  Unknown = 256,
};

enum class IFSBitWidthType {
  IFS32,
  IFS64,

  // Bit width info is 1 bytes, 256 is safely out of range.
  Unknown = 256,
};

struct IFSSymbol {
  IFSSymbol() = default;
  explicit IFSSymbol(std::string SymbolName) : Name(std::move(SymbolName)) {}
  std::string Name;
  uint64_t Size;
  IFSSymbolType Type;
  bool Undefined;
  bool Weak;
  Optional<std::string> Warning;
  bool operator<(const IFSSymbol &RHS) const { return Name < RHS.Name; }
};

struct IFSTarget {
  Optional<std::string> Triple;
  Optional<std::string> ObjectFormat;
  Optional<IFSArch> Arch;
  Optional<std::string> ArchString;
  Optional<IFSEndiannessType> Endianness;
  Optional<IFSBitWidthType> BitWidth;

  bool empty();
};

inline bool operator==(const IFSTarget &Lhs, const IFSTarget &Rhs) {
  if (Lhs.Arch != Rhs.Arch || Lhs.BitWidth != Rhs.BitWidth ||
      Lhs.Endianness != Rhs.Endianness ||
      Lhs.ObjectFormat != Rhs.ObjectFormat || Lhs.Triple != Rhs.Triple)
    return false;
  return true;
}

inline bool operator!=(const IFSTarget &Lhs, const IFSTarget &Rhs) {
  return !(Lhs == Rhs);
}

// A cumulative representation of InterFace stubs.
// Both textual and binary stubs will read into and write from this object.
struct IFSStub {
  // TODO: Add support for symbol versioning.
  VersionTuple IfsVersion;
  Optional<std::string> SoName;
  IFSTarget Target;
  std::vector<std::string> NeededLibs;
  std::vector<IFSSymbol> Symbols;

  IFSStub() = default;
  IFSStub(const IFSStub &Stub);
  IFSStub(IFSStub &&Stub);
};

// Create a alias class for IFSStub.
// LLVM's YAML library does not allow mapping a class with 2 traits,
// which prevents us using 'Target:' field with different definitions.
// This class makes it possible to map a second traits so the same data
// structure can be used for 2 different yaml schema.
struct IFSStubTriple : IFSStub {
  IFSStubTriple() = default;
  IFSStubTriple(const IFSStub &Stub);
  IFSStubTriple(const IFSStubTriple &Stub);
  IFSStubTriple(IFSStubTriple &&Stub);
};

/// This function convert bit width type from IFS enum to ELF format
/// Currently, ELFCLASS32 and ELFCLASS64 are supported.
///
/// @param BitWidth IFS bit width type.
uint8_t convertIFSBitWidthToELF(IFSBitWidthType BitWidth);

/// This function convert endianness type from IFS enum to ELF format
/// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
///
/// @param Endianness IFS endianness type.
uint8_t convertIFSEndiannessToELF(IFSEndiannessType Endianness);

/// This function convert symbol type from IFS enum to ELF format
/// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
///
/// @param SymbolType IFS symbol type.
uint8_t convertIFSSymbolTypeToELF(IFSSymbolType SymbolType);

/// This function extracts ELF bit width from e_ident[EI_CLASS] of an ELF file
/// Currently, ELFCLASS32 and ELFCLASS64 are supported.
/// Other endianness types are mapped to IFSBitWidthType::Unknown.
///
/// @param BitWidth e_ident[EI_CLASS] value to extract bit width from.
IFSBitWidthType convertELFBitWidthToIFS(uint8_t BitWidth);

/// This function extracts ELF endianness from e_ident[EI_DATA] of an ELF file
/// Currently, ELFDATA2LSB and ELFDATA2MSB are supported.
/// Other endianness types are mapped to IFSEndiannessType::Unknown.
///
/// @param Endianness e_ident[EI_DATA] value to extract endianness type from.
IFSEndiannessType convertELFEndiannessToIFS(uint8_t Endianness);

/// This function extracts symbol type from a symbol's st_info member and
/// maps it to an IFSSymbolType enum.
/// Currently, STT_NOTYPE, STT_OBJECT, STT_FUNC, and STT_TLS are supported.
/// Other symbol types are mapped to IFSSymbolType::Unknown.
///
/// @param SymbolType Binary symbol st_info to extract symbol type from.
IFSSymbolType convertELFSymbolTypeToIFS(uint8_t SymbolType);
} // namespace ifs
} // end namespace llvm

#endif // LLVM_INTERFACESTUB_IFSSTUB_H