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_SECTION_SYM_TAB_HXX
18#define ELF_SECTION_SYM_TAB_HXX
19
20#include "ELFSectionHeader.h"
21#include "ELFSymbol.h"
22#include "utils/rsl_assert.h"
23
24template <unsigned Bitwidth>
25ELFSectionSymTab<Bitwidth>::~ELFSectionSymTab() {
26  for (size_t i = 0; i < table.size(); ++i) {
27    delete table[i];
28  }
29}
30
31template <unsigned Bitwidth>
32size_t ELFSectionSymTab<Bitwidth>::getFuncCount() const {
33  size_t result = 0;
34  for (size_t i = 0; i < table.size(); ++i) {
35    if (table[i] && table[i]->isConcreteFunc()) {
36      result++;
37    }
38  }
39  return result;
40}
41
42template <unsigned Bitwidth>
43inline size_t ELFSectionSymTab<Bitwidth>::getExternFuncCount() const {
44  size_t result = 0;
45  for (size_t i = 0; i < table.size(); ++i) {
46    if (table[i] && table[i]->isExternFunc()) {
47      result++;
48    }
49  }
50  return result;
51}
52
53template <unsigned Bitwidth>
54inline void ELFSectionSymTab<Bitwidth>::buildNameMap() {
55  for (size_t i = 0; i < table.size(); ++i) {
56    ELFSymbolTy *symbol = table[i];
57    if ( symbol ) {
58      name_map[symbol->getName()] = symbol;
59    }
60  }
61}
62
63template <unsigned Bitwidth>
64inline ELFSymbol<Bitwidth> const *
65ELFSectionSymTab<Bitwidth>::getByName(std::string const &name) const {
66  typename llvm::StringMap<ELFSymbolTy *>::const_iterator symbol =
67    name_map.find(name);
68  if (symbol == name_map.end()) {
69    return NULL;
70  }
71  return symbol->getValue();
72}
73
74template <unsigned Bitwidth>
75inline void
76ELFSectionSymTab<Bitwidth>::getFuncNameList(size_t size,
77                                            char const **list) const {
78  for (size_t i = 0, j = 0; i < table.size() && j < size; ++i) {
79    if (table[i] && table[i]->isConcreteFunc()) {
80      list[j++] = table[i]->getName();
81    }
82  }
83}
84
85template <unsigned Bitwidth>
86template <typename Archiver>
87ELFSectionSymTab<Bitwidth> *
88ELFSectionSymTab<Bitwidth>::read(Archiver &AR,
89                                 ELFObjectTy *owner,
90                                 ELFSectionHeaderTy const *sh) {
91
92  std::unique_ptr<ELFSectionSymTabTy> st(new ELFSectionSymTabTy());
93
94  // Assert that entry size will be the same as standard.
95  rsl_assert(sh->getEntrySize() == TypeTraits<ELFSymbolTy>::size);
96
97  // Seek to the start of symbol table
98  AR.seek(sh->getOffset(), true);
99
100  // Read all symbol table entry
101  size_t size = sh->getSize() / sh->getEntrySize();
102  for (size_t i = 0; i < size; ++i) {
103    st->table.push_back(ELFSymbolTy::read(AR, owner, i));
104  }
105
106  if (!AR) {
107    // Unable to read the table.
108    return 0;
109  }
110
111  return st.release();
112}
113
114template <unsigned Bitwidth>
115void ELFSectionSymTab<Bitwidth>::print() const {
116  using namespace llvm;
117
118  out() << '\n' << fillformat('=', 79) << '\n';
119  out().changeColor(raw_ostream::WHITE, true);
120  out() << "Symbol Table" << '\n';
121  out().resetColor();
122
123  for (size_t i = 0; i < table.size(); ++i) {
124    table[i]->print();
125  }
126
127  out() << fillformat('=', 79) << '\n';
128}
129
130#endif // ELF_SECTION_SYM_TAB_HXX
131