1/*
2 * Copyright 2011, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *     http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ELF_TYPES_H
18#define ELF_TYPES_H
19
20#include "utils/traits.h"
21
22#include <stdint.h>
23#include <llvm/Support/raw_ostream.h>
24
25
26// ELF structure forward declarations
27template <unsigned Bitwidth> class ELFHeader;
28template <unsigned Bitwidth> class ELFObject;
29template <unsigned Bitwidth> class ELFProgramHeader;
30template <unsigned Bitwidth> class ELFReloc;
31template <unsigned Bitwidth> class ELFRelocRel; // For TypeTraits
32template <unsigned Bitwidth> class ELFRelocRela; // For TypeTraits
33template <unsigned Bitwidth> class ELFSection;
34template <unsigned Bitwidth> class ELFSectionBits;
35template <unsigned Bitwidth> class ELFSectionHeader;
36template <unsigned Bitwidth> class ELFSectionHeaderTable;
37template <unsigned Bitwidth> class ELFSectionNoBits;
38template <unsigned Bitwidth> class ELFSectionProgBits;
39template <unsigned Bitwidth> class ELFSectionRelTable;
40template <unsigned Bitwidth> class ELFSectionStrTab;
41template <unsigned Bitwidth> class ELFSectionSymTab;
42template <unsigned Bitwidth> class ELFSymbol;
43
44// Note: Following TypeTraits specialization MUST be compliant to the
45// System V Application Binary Interface, Chap 4, Data Representation.
46
47TYPE_TRAITS_SPECIALIZE(ELFHeader<32>        , 52, 4)
48TYPE_TRAITS_SPECIALIZE(ELFHeader<64>        , 64, 8)
49
50TYPE_TRAITS_SPECIALIZE(ELFProgramHeader<32> , 32, 4)
51TYPE_TRAITS_SPECIALIZE(ELFProgramHeader<64> , 56, 8)
52
53TYPE_TRAITS_SPECIALIZE(ELFSectionHeader<32> , 40, 4)
54TYPE_TRAITS_SPECIALIZE(ELFSectionHeader<64> , 64, 8)
55
56TYPE_TRAITS_SPECIALIZE(ELFSymbol<32>        , 16, 4)
57TYPE_TRAITS_SPECIALIZE(ELFSymbol<64>        , 24, 8)
58
59TYPE_TRAITS_SPECIALIZE(ELFRelocRel<32>      , 8, 4)
60TYPE_TRAITS_SPECIALIZE(ELFRelocRel<64>      , 16, 8)
61
62TYPE_TRAITS_SPECIALIZE(ELFRelocRela<32>     , 12, 4)
63TYPE_TRAITS_SPECIALIZE(ELFRelocRela<64>     , 24, 8)
64
65
66// ELF primitive type wrappers
67namespace detail {
68#define ELF_TYPE_WRAPPER(TYPE, IMPL)                                        \
69  struct TYPE {                                                             \
70    IMPL value;                                                             \
71                                                                            \
72    TYPE() : value(0) { }                                                   \
73    TYPE(IMPL val) : value(val) { }                                         \
74                                                                            \
75    TYPE &operator=(TYPE const &with) { value = with.value; return *this; } \
76    TYPE &operator=(IMPL val) { value = val; return *this; }                \
77                                                                            \
78    operator IMPL() const { return value; }                                 \
79  };
80
81  ELF_TYPE_WRAPPER(ELFHalf      , uint16_t)
82  ELF_TYPE_WRAPPER(ELFWord      , uint32_t)
83  ELF_TYPE_WRAPPER(ELFSword     , int32_t)
84  ELF_TYPE_WRAPPER(ELFXword     , uint64_t)
85  ELF_TYPE_WRAPPER(ELFSxword    , int64_t)
86  ELF_TYPE_WRAPPER(ELF32Address , uint32_t)
87  ELF_TYPE_WRAPPER(ELF32Offset  , uint32_t)
88  ELF_TYPE_WRAPPER(ELF64Address , uint64_t)
89  ELF_TYPE_WRAPPER(ELF64Offset  , uint64_t)
90
91#undef ELF_TYPE_WRAPPER
92
93  extern llvm::raw_ostream &operator<<(llvm::raw_ostream &,
94                                       ELF32Address const &);
95  extern llvm::raw_ostream &operator<<(llvm::raw_ostream &,
96                                       ELF32Offset const &);
97  extern llvm::raw_ostream &operator<<(llvm::raw_ostream &,
98                                       ELF64Address const &);
99  extern llvm::raw_ostream &operator<<(llvm::raw_ostream &,
100                                       ELF64Offset const &);
101}
102
103// Note: Following TypeTraits specialization MUST be compliant to the
104// System V Application Binary Interface, Chap 4, Data Representation.
105
106TYPE_TRAITS_SPECIALIZE(detail::ELFHalf      , 2, 2)
107TYPE_TRAITS_SPECIALIZE(detail::ELFWord      , 4, 4)
108TYPE_TRAITS_SPECIALIZE(detail::ELFSword     , 4, 4)
109TYPE_TRAITS_SPECIALIZE(detail::ELFXword     , 8, 8)
110TYPE_TRAITS_SPECIALIZE(detail::ELFSxword    , 8, 8)
111TYPE_TRAITS_SPECIALIZE(detail::ELF32Address , 4, 4)
112TYPE_TRAITS_SPECIALIZE(detail::ELF32Offset  , 4, 4)
113TYPE_TRAITS_SPECIALIZE(detail::ELF64Address , 8, 8)
114TYPE_TRAITS_SPECIALIZE(detail::ELF64Offset  , 8, 8)
115
116template <unsigned Bitwidth>
117struct ELFPrimitiveTypes;
118
119template <>
120struct ELFPrimitiveTypes<32> {
121  typedef detail::ELF32Address  address;
122  typedef detail::ELF32Offset   offset;
123
124  typedef unsigned char         byte;
125  typedef detail::ELFHalf       half;
126  typedef detail::ELFWord       word;
127  typedef detail::ELFSword      sword;
128
129  typedef detail::ELFWord       relinfo;
130  typedef detail::ELFSword      addend;
131  typedef detail::ELFWord       symsize;
132
133  // Note: Don't use these types.  They are not in the specification of
134  // ELF 32.  However, we need these typedefs to define the type introduce
135  // macro.
136  typedef void xword;
137  typedef void sxword;
138};
139
140template <>
141struct ELFPrimitiveTypes<64> {
142  typedef detail::ELF64Address  address;
143  typedef detail::ELF64Offset   offset;
144
145  typedef unsigned char         byte;
146  typedef detail::ELFHalf       half;
147  typedef detail::ELFWord       word;
148  typedef detail::ELFSword      sword;
149  typedef detail::ELFXword      xword;
150  typedef detail::ELFSxword     sxword;
151
152  typedef detail::ELFXword      relinfo;
153  typedef detail::ELFSxword     addend;
154  typedef detail::ELFXword      symsize;
155};
156
157
158// Macros to introduce these ELF types to a specific scope
159
160#define ELF_STRUCT_TYPE_INTRO_TO_SCOPE(BITWIDTH)                            \
161  typedef ELFHeader<BITWIDTH>             ELFHeaderTy;                      \
162  typedef ELFObject<BITWIDTH>             ELFObjectTy;                      \
163  typedef ELFProgramHeader<BITWIDTH>      ELFProgramHeaderTy;               \
164  typedef ELFReloc<BITWIDTH>              ELFRelocTy;                       \
165  typedef ELFRelocRel<BITWIDTH>           ELFRelocRelTy;                    \
166  typedef ELFRelocRela<BITWIDTH>          ELFRelocRelaTy;                   \
167  typedef ELFSection<BITWIDTH>            ELFSectionTy;                     \
168  typedef ELFSectionBits<BITWIDTH>        ELFSectionBitsTy;                 \
169  typedef ELFSectionHeader<BITWIDTH>      ELFSectionHeaderTy;               \
170  typedef ELFSectionHeaderTable<BITWIDTH> ELFSectionHeaderTableTy;          \
171  typedef ELFSectionNoBits<BITWIDTH>      ELFSectionNoBitsTy;               \
172  typedef ELFSectionProgBits<BITWIDTH>    ELFSectionProgBitsTy;             \
173  typedef ELFSectionRelTable<BITWIDTH>    ELFSectionRelTableTy;             \
174  typedef ELFSectionStrTab<BITWIDTH>      ELFSectionStrTabTy;               \
175  typedef ELFSectionSymTab<BITWIDTH>      ELFSectionSymTabTy;               \
176  typedef ELFSymbol<BITWIDTH>             ELFSymbolTy;
177
178
179#define ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(BITWIDTH)                          \
180  /* ELF structures */                                                      \
181  ELF_STRUCT_TYPE_INTRO_TO_SCOPE(BITWIDTH)                                  \
182                                                                            \
183  /* ELF primitives */                                                      \
184  typedef typename ELFPrimitiveTypes<BITWIDTH>::address addr_t;             \
185  typedef typename ELFPrimitiveTypes<BITWIDTH>::offset  offset_t;           \
186  typedef typename ELFPrimitiveTypes<BITWIDTH>::byte    byte_t;             \
187  typedef typename ELFPrimitiveTypes<BITWIDTH>::half    half_t;             \
188  typedef typename ELFPrimitiveTypes<BITWIDTH>::word    word_t;             \
189  typedef typename ELFPrimitiveTypes<BITWIDTH>::sword   sword_t;            \
190  typedef typename ELFPrimitiveTypes<BITWIDTH>::xword   xword_t;            \
191  typedef typename ELFPrimitiveTypes<BITWIDTH>::sxword  sxword_t;           \
192  typedef typename ELFPrimitiveTypes<BITWIDTH>::relinfo relinfo_t;          \
193  typedef typename ELFPrimitiveTypes<BITWIDTH>::addend  addend_t;           \
194  typedef typename ELFPrimitiveTypes<BITWIDTH>::symsize symsize_t;
195
196
197#define ELF_TYPE_INTRO_TO_SCOPE(BITWIDTH)                                   \
198  /* ELF structures */                                                      \
199  ELF_STRUCT_TYPE_INTRO_TO_SCOPE(BITWIDTH)                                  \
200                                                                            \
201  /* ELF primitives */                                                      \
202  typedef ELFPrimitiveTypes<BITWIDTH>::address  addr_t;                     \
203  typedef ELFPrimitiveTypes<BITWIDTH>::offset   offset_t;                   \
204  typedef ELFPrimitiveTypes<BITWIDTH>::byte     byte_t;                     \
205  typedef ELFPrimitiveTypes<BITWIDTH>::half     half_t;                     \
206  typedef ELFPrimitiveTypes<BITWIDTH>::word     word_t;                     \
207  typedef ELFPrimitiveTypes<BITWIDTH>::sword    sword_t;                    \
208  typedef ELFPrimitiveTypes<BITWIDTH>::xword    xword_t;                    \
209  typedef ELFPrimitiveTypes<BITWIDTH>::sxword   sxword_t;                   \
210  typedef ELFPrimitiveTypes<BITWIDTH>::relinfo  relinfo_t;                  \
211  typedef ELFPrimitiveTypes<BITWIDTH>::addend   addend_t;                   \
212  typedef ELFPrimitiveTypes<BITWIDTH>::symsize  symsize_t;
213
214
215#endif // ELF_TYPES_H
216