ELFSymbol.h revision 6ba6c664f773a53d7b6ddaf2c216d11404fd18fc
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_SYMBOL_H
18#define ELF_SYMBOL_H
19
20#include "ELFTypes.h"
21#include "ELF.h"
22
23#include <llvm/ADT/OwningPtr.h>
24
25#include <string>
26#include <algorithm>
27
28#include <stdint.h>
29#include <stdlib.h>
30
31class ELFSymbolHelperMixin {
32protected:
33  static char const *getTypeStr(uint8_t);
34  static char const *getBindingAttributeStr(uint8_t);
35  static char const *getVisibilityStr(uint8_t);
36};
37
38template <unsigned Bitwidth>
39class ELFSymbol_CRTP : private ELFSymbolHelperMixin {
40public:
41  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
42
43protected:
44  ELFObject<Bitwidth> const *owner;
45
46  size_t index;
47
48  word_t st_name;
49  byte_t st_info;
50  byte_t st_other;
51  half_t st_shndx;
52  addr_t st_value;
53  symsize_t st_size;
54
55  mutable void *my_addr;
56
57protected:
58  ELFSymbol_CRTP() { my_addr = 0; }
59
60  ~ELFSymbol_CRTP() {
61#if 0
62    if (my_addr != 0 &&
63        getType() == STT_OBJECT &&
64        getSectionIndex() == SHN_COMMON) {
65      std::free(my_addr);
66    }
67#endif
68  }
69
70public:
71  size_t getIndex() const {
72    return index;
73  }
74
75  word_t getNameIndex() const {
76    return st_name;
77  }
78
79  char const *getName() const;
80
81// I don't want to include elf.h in .h file, so define those macro by ourself.
82#define ELF_ST_BIND(i)   ((i)>>4)
83#define ELF_ST_TYPE(i)   ((i)&0xf)
84#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
85  byte_t getType() const {
86    return ELF_ST_TYPE(st_info);
87  }
88
89  byte_t getBindingAttribute() const {
90    return ELF_ST_BIND(st_info);
91  }
92#undef ELF_ST_BIND
93#undef ELF_ST_TYPE
94#undef ELF_ST_INFO
95
96#define ELF_ST_VISIBILITY(o) ((o)&0x3)
97  byte_t getVisibility() const {
98    return ELF_ST_VISIBILITY(st_other);
99  }
100#undef ELF_ST_VISIBILITY
101
102  half_t getSectionIndex() const {
103    return st_shndx;
104  }
105
106  addr_t getValue() const {
107    return st_value;
108  }
109
110  symsize_t getSize() const {
111    return st_size;
112  }
113
114  void *getAddress(int machine, bool autoAlloc = true) const;
115
116  void setAddress(void *addr) {
117    my_addr = addr;
118  }
119
120  bool isValid() const {
121    // FIXME: Should check the correctness of the section header.
122    return true;
123  }
124
125  bool isConcreteFunc() const {
126    return getType() == STT_FUNC;
127  }
128
129  bool isExternFunc() const {
130    return getType() == STT_NOTYPE;
131  }
132
133  template <typename Archiver>
134  static ELFSymbolTy *
135  read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
136
137  void print(bool shouldPrintHeader = false) const;
138
139private:
140  ELFSymbolTy *concrete() {
141    return static_cast<ELFSymbolTy *>(this);
142  }
143
144  ELFSymbolTy const *concrete() const {
145    return static_cast<ELFSymbolTy const *>(this);
146  }
147};
148
149template <>
150class ELFSymbol<32> : public ELFSymbol_CRTP<32> {
151  friend class ELFSymbol_CRTP<32>;
152
153private:
154  ELFSymbol() {
155  }
156
157  template <typename Archiver>
158  bool serialize(Archiver &AR) {
159    AR.prologue(TypeTraits<ELFSymbol>::size);
160
161    AR & st_name;
162    AR & st_value;
163    AR & st_size;
164    AR & st_info;
165    AR & st_other;
166    AR & st_shndx;
167
168    AR.epilogue(TypeTraits<ELFSymbol>::size);
169    return AR;
170  }
171};
172
173template <>
174class ELFSymbol<64> : public ELFSymbol_CRTP<64> {
175  friend class ELFSymbol_CRTP<64>;
176
177private:
178  ELFSymbol() {
179  }
180
181  template <typename Archiver>
182  bool serialize(Archiver &AR) {
183    AR.prologue(TypeTraits<ELFSymbol>::size);
184
185    AR & st_name;
186    AR & st_info;
187    AR & st_other;
188    AR & st_shndx;
189    AR & st_value;
190    AR & st_size;
191
192    AR.epilogue(TypeTraits<ELFSymbol>::size);
193    return AR;
194  }
195};
196
197#include "impl/ELFSymbol.hxx"
198
199#endif // ELF_SYMBOL_H
200