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