ELFSymbol.hxx revision e0536b5e8bcf923e7f4bdb99674f4a3466676906
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_HXX
18#define ELF_SYMBOL_HXX
19
20#include "ELFSectionHeaderTable.h"
21#include "ELFSection.h"
22#include "ELFSectionStrTab.h"
23
24#include "ELFObject.h"
25#include "ELFSectionHeaderTable.h"
26#include "ELFSectionProgBits.h"
27#include "ELFSectionNoBits.h"
28
29#include "utils/rsl_assert.h"
30
31#ifdef __arm__
32#define LOG_TAG "bcc"
33#include "cutils/log.h"
34#endif
35
36template <unsigned Bitwidth>
37inline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
38  ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable();
39  size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
40  ELFSectionTy const *section = owner->getSectionByIndex(index);
41  ELFSectionStrTabTy const &strtab =
42    *static_cast<ELFSectionStrTabTy const *>(section);
43  return strtab[getNameIndex()];
44}
45
46template <unsigned Bitwidth>
47template <typename Archiver>
48inline ELFSymbol<Bitwidth> *
49ELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
50                               ELFObjectTy const *owner,
51                               size_t index) {
52  if (!AR) {
53    // Archiver is in bad state before calling read function.
54    // Return NULL and do nothing.
55    return 0;
56  }
57
58  llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy());
59
60  if (!sh->serialize(AR)) {
61    // Unable to read the structure.  Return NULL.
62    return 0;
63  }
64
65  if (!sh->isValid()) {
66    // SymTabEntry read from archiver is not valid.  Return NULL.
67    return 0;
68  }
69
70  // Set the section header index
71  sh->index = index;
72
73  // Set the owner elf object
74  sh->owner = owner;
75
76  return sh.take();
77}
78
79template <unsigned Bitwidth>
80inline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
81  using namespace llvm;
82
83  if (shouldPrintHeader) {
84    out() << '\n' << fillformat('=', 79) << '\n';
85    out().changeColor(raw_ostream::WHITE, true);
86    out() << "ELF Symbol Table Entry "
87          << this->getIndex() << '\n';
88    out().resetColor();
89    out() << fillformat('-', 79) << '\n';
90  } else {
91    out() << fillformat('-', 79) << '\n';
92    out().changeColor(raw_ostream::YELLOW, true);
93    out() << "ELF Symbol Table Entry "
94          << this->getIndex() << " : " << '\n';
95    out().resetColor();
96  }
97
98#define PRINT_LINT(title, value) \
99  out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
100  PRINT_LINT("Name",        getName()                                    );
101  PRINT_LINT("Type",        getTypeStr(getType())                        );
102  PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
103  PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
104  PRINT_LINT("Shtab Index", getSectionIndex()                            );
105  PRINT_LINT("Value",       getValue()                                   );
106  PRINT_LINT("Size",        getSize()                                    );
107#undef PRINT_LINT
108
109// TODO: Horizontal type or vertical type can use option to decide.
110#if 0
111  using namespace term::color;
112  using namespace std;
113
114  cout << setw(20) << getName() <<
115          setw(10) << getTypeStr(getType()) <<
116          setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
117          setw(15) << getVisibilityStr(getVisibility()) <<
118          setw(10) << getSectionIndex() <<
119          setw(7) << getValue() <<
120          setw(7) << getSize() <<
121          endl;
122#endif
123}
124
125template <unsigned Bitwidth>
126void *ELFSymbol_CRTP<Bitwidth>::getAddress(bool autoAlloc) const {
127  if (my_addr != 0) {
128    return my_addr;
129  }
130  size_t idx = (size_t)getSectionIndex();
131  switch (getType()) {
132    default:
133      break;
134
135    case STT_OBJECT:
136      switch (idx) {
137        default:
138          {
139#ifndef NDEBUG
140            ELFSectionHeaderTableTy const *header =
141              owner->getSectionHeaderTable();
142            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
143                    (*header)[idx]->getType() == SHT_NOBITS) &&
144                   "STT_OBJECT with not BITS section.");
145#endif
146            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
147            rsl_assert(sec != 0 && "STT_OBJECT with null section.");
148
149            size_t align = 16;
150            my_addr = const_cast<ELFObjectTy *>(owner)->
151                          allocateSHNCommonData((size_t)getSize(), align);
152            if (!my_addr) {
153              rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
154              abort();
155            }
156
157            ELFSectionBitsTy const &st =
158              static_cast<ELFSectionBitsTy const &>(*sec);
159            memcpy(my_addr, &st[0] + (off_t)getValue(), getSize());
160
161#if 0
162#ifdef __arm__
163            LOGD("Symbol %s\n", getName());
164            if (strcmp(getName(), "camera") == 0) {
165              uint32_t *p = (uint32_t *)(&st[0] + (size_t)getValue());
166              LOGD("     | %08x %08x %08x %08x\n", p[0], p[1], p[2], p[3]);
167              LOGD("     | %08x %08x %08x %08x\n", p[4], p[5], p[6], p[7]);
168              LOGD("     | %08x %08x %08x %08x\n", p[8], p[9], p[10], p[11]);
169              LOGD("     | %08x %08x %08x %08x\n", p[12], p[13], p[14], p[15]);
170            }
171#endif
172#endif
173          }
174          break;
175
176        case SHN_COMMON:
177          {
178            if (!autoAlloc) {
179              return NULL;
180            }
181#if 0
182#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
183            if (posix_memalign(&my_addr,
184                               std::max((size_t)getValue(), sizeof(void*)),
185                               (size_t)getSize()) != 0) {
186              rsl_assert(0 && "posix_memalign failed.");
187            }
188#else
189            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
190                               (size_t)getSize());
191
192            rsl_assert(my_addr != NULL && "memalign failed.");
193#endif
194            if (my_addr) {
195              memset(my_addr, '\0', getSize());
196            }
197#else
198            size_t align = 16;
199            my_addr = const_cast<ELFObjectTy *>(owner)->
200                          allocateSHNCommonData((size_t)getSize(), align);
201            if (!my_addr) {
202              rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
203              abort();
204            }
205#endif
206          }
207          break;
208
209        case SHN_ABS:
210        case SHN_UNDEF:
211        case SHN_XINDEX:
212          rsl_assert(0 && "STT_OBJECT with special st_shndx.");
213          break;
214      }
215      break;
216
217
218    case STT_FUNC:
219      switch (idx) {
220        default:
221          {
222#ifndef NDEBUG
223            ELFSectionHeaderTableTy const *header =
224              owner->getSectionHeaderTable();
225            rsl_assert((*header)[idx]->getType() == SHT_PROGBITS &&
226                   "STT_FUNC with not PROGBITS section.");
227#endif
228            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
229            rsl_assert(sec != 0 && "STT_FUNC with null section.");
230
231            ELFSectionProgBitsTy const &st =
232              static_cast<ELFSectionProgBitsTy const &>(*sec);
233            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
234          }
235          break;
236
237        case SHN_ABS:
238        case SHN_COMMON:
239        case SHN_UNDEF:
240        case SHN_XINDEX:
241          rsl_assert(0 && "STT_FUNC with special st_shndx.");
242          break;
243      }
244      break;
245
246
247    case STT_SECTION:
248      switch (idx) {
249        default:
250          {
251#ifndef NDEBUG
252            ELFSectionHeaderTableTy const *header =
253              owner->getSectionHeaderTable();
254            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
255                    (*header)[idx]->getType() == SHT_NOBITS) &&
256                   "STT_SECTION with not BITS section.");
257#endif
258            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
259            rsl_assert(sec != 0 && "STT_SECTION with null section.");
260
261            ELFSectionBitsTy const &st =
262              static_cast<ELFSectionBitsTy const &>(*sec);
263            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
264          }
265          break;
266
267        case SHN_ABS:
268        case SHN_COMMON:
269        case SHN_UNDEF:
270        case SHN_XINDEX:
271          rsl_assert(0 && "STT_SECTION with special st_shndx.");
272          break;
273      }
274      break;
275
276    case STT_NOTYPE:
277      switch (idx) {
278        default:
279          {
280#ifndef NDEBUG
281            ELFSectionHeaderTableTy const *header =
282              owner->getSectionHeaderTable();
283            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
284                    (*header)[idx]->getType() == SHT_NOBITS) &&
285                   "STT_SECTION with not BITS section.");
286#endif
287            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
288            rsl_assert(sec != 0 && "STT_SECTION with null section.");
289
290            ELFSectionBitsTy const &st =
291              static_cast<ELFSectionBitsTy const &>(*sec);
292            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
293          }
294          break;
295
296        case SHN_ABS:
297        case SHN_COMMON:
298        case SHN_XINDEX:
299          rsl_assert(0 && "STT_SECTION with special st_shndx.");
300          break;
301        case SHN_UNDEF:
302          return 0;
303      }
304      break;
305      return 0;
306
307    case STT_COMMON:
308    case STT_FILE:
309    case STT_TLS:
310    case STT_LOOS:
311    case STT_HIOS:
312    case STT_LOPROC:
313    case STT_HIPROC:
314      rsl_assert(0 && "Not implement.");
315      return 0;
316  }
317  return my_addr;
318}
319
320#endif // ELF_SYMBOL_HXX
321