• 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 #include <stdint.h>
29 #include <stdlib.h>
30 
31 class ELFSymbolHelperMixin {
32 protected:
33   static char const *getTypeStr(uint8_t);
34   static char const *getBindingAttributeStr(uint8_t);
35   static char const *getVisibilityStr(uint8_t);
36 };
37 
38 template <unsigned Bitwidth>
39 class ELFSymbol_CRTP : private ELFSymbolHelperMixin {
40 public:
41   ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
42 
43 protected:
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 
57 protected:
ELFSymbol_CRTP()58   ELFSymbol_CRTP() { my_addr = 0; }
59 
~ELFSymbol_CRTP()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 
70 public:
getIndex()71   size_t getIndex() const {
72     return index;
73   }
74 
getNameIndex()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))
getType()85   byte_t getType() const {
86     return ELF_ST_TYPE(st_info);
87   }
88 
getBindingAttribute()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)
getVisibility()97   byte_t getVisibility() const {
98     return ELF_ST_VISIBILITY(st_other);
99   }
100 #undef ELF_ST_VISIBILITY
101 
getSectionIndex()102   half_t getSectionIndex() const {
103     return st_shndx;
104   }
105 
getValue()106   addr_t getValue() const {
107     return st_value;
108   }
109 
getSize()110   symsize_t getSize() const {
111     return st_size;
112   }
113 
114   void *getAddress(int machine, bool autoAlloc = true) const;
115 
setAddress(void * addr)116   void setAddress(void *addr) {
117     my_addr = addr;
118   }
119 
isValid()120   bool isValid() const {
121     // FIXME: Should check the correctness of the section header.
122     return true;
123   }
124 
isConcreteFunc()125   bool isConcreteFunc() const {
126     return getType() == STT_FUNC;
127   }
128 
isExternFunc()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 
139 private:
concrete()140   ELFSymbolTy *concrete() {
141     return static_cast<ELFSymbolTy *>(this);
142   }
143 
concrete()144   ELFSymbolTy const *concrete() const {
145     return static_cast<ELFSymbolTy const *>(this);
146   }
147 };
148 
149 template <>
150 class ELFSymbol<32> : public ELFSymbol_CRTP<32> {
151   friend class ELFSymbol_CRTP<32>;
152 
153 private:
ELFSymbol()154   ELFSymbol() {
155   }
156 
157   template <typename Archiver>
serialize(Archiver & AR)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 
173 template <>
174 class ELFSymbol<64> : public ELFSymbol_CRTP<64> {
175   friend class ELFSymbol_CRTP<64>;
176 
177 private:
ELFSymbol()178   ELFSymbol() {
179   }
180 
181   template <typename Archiver>
serialize(Archiver & AR)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