ELFSymbol.hxx revision 71884036ac3215a7cb9f6f95bd0902efbb344071
1#ifndef ELF_SYMBOL_HXX
2#define ELF_SYMBOL_HXX
3
4#include "ELFSectionHeaderTable.h"
5#include "ELFSection.h"
6#include "ELFSectionStrTab.h"
7
8#include "ELFObject.h"
9#include "ELFSectionHeaderTable.h"
10#include "ELFSectionProgBits.h"
11#include "ELFSectionNoBits.h"
12
13template <unsigned Bitwidth>
14inline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
15  ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable();
16  size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
17  ELFSectionTy const *section = owner->getSectionByIndex(index);
18  ELFSectionStrTabTy const &strtab =
19    *static_cast<ELFSectionStrTabTy const *>(section);
20  return strtab[getNameIndex()];
21}
22
23template <unsigned Bitwidth>
24template <typename Archiver>
25inline ELFSymbol<Bitwidth> *
26ELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
27                               ELFObjectTy const *owner,
28                               size_t index) {
29  if (!AR) {
30    // Archiver is in bad state before calling read function.
31    // Return NULL and do nothing.
32    return 0;
33  }
34
35  llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy());
36
37  if (!sh->serialize(AR)) {
38    // Unable to read the structure.  Return NULL.
39    return 0;
40  }
41
42  if (!sh->isValid()) {
43    // SymTabEntry read from archiver is not valid.  Return NULL.
44    return 0;
45  }
46
47  // Set the section header index
48  sh->index = index;
49
50  // Set the owner elf object
51  sh->owner = owner;
52
53  return sh.take();
54}
55
56template <unsigned Bitwidth>
57inline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
58  using namespace llvm;
59
60  if (shouldPrintHeader) {
61    out() << '\n' << fillformat('=', 79) << '\n';
62    out().changeColor(raw_ostream::WHITE, true);
63    out() << "ELF Symbol Table Entry "
64          << this->getIndex() << '\n';
65    out().resetColor();
66    out() << fillformat('-', 79) << '\n';
67  } else {
68    out() << fillformat('-', 79) << '\n';
69    out().changeColor(raw_ostream::YELLOW, true);
70    out() << "ELF Symbol Table Entry "
71          << this->getIndex() << " : " << '\n';
72    out().resetColor();
73  }
74
75#define PRINT_LINT(title, value) \
76  out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
77  PRINT_LINT("Name",        getName()                                    );
78  PRINT_LINT("Type",        getTypeStr(getType())                        );
79  PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
80  PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
81  PRINT_LINT("Shtab Index", getSectionIndex()                            );
82  PRINT_LINT("Value",       getValue()                                   );
83  PRINT_LINT("Size",        getSize()                                    );
84#undef PRINT_LINT
85
86// TODO: Horizontal type or vertical type can use option to decide.
87#if 0
88  using namespace term::color;
89  using namespace std;
90
91  cout << setw(20) << getName() <<
92          setw(10) << getTypeStr(getType()) <<
93          setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
94          setw(15) << getVisibilityStr(getVisibility()) <<
95          setw(10) << getSectionIndex() <<
96          setw(7) << getValue() <<
97          setw(7) << getSize() <<
98          endl;
99#endif
100}
101
102template <unsigned Bitwidth>
103void *ELFSymbol_CRTP<Bitwidth>::getAddress() const {
104  if (my_addr != 0) {
105    return my_addr;
106  }
107  size_t idx = (size_t)getSectionIndex();
108  switch (getType()) {
109    default:
110      break;
111
112    case STT_OBJECT:
113      switch (idx) {
114        default:
115          {
116#ifndef NDEBUG
117            ELFSectionHeaderTableTy const *header =
118              owner->getSectionHeaderTable();
119            assert(((*header)[idx]->getType() == SHT_PROGBITS ||
120                    (*header)[idx]->getType() == SHT_NOBITS) &&
121                   "STT_OBJECT with not BITS section.");
122#endif
123            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
124            assert(sec != 0 && "STT_OBJECT with null section.");
125
126            ELFSectionBitsTy const &st =
127              static_cast<ELFSectionBitsTy const &>(*sec);
128            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
129          }
130          break;
131
132        case SHN_COMMON:
133          {
134#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
135            if (posix_memalign(&my_addr,
136                               std::max((size_t)getValue(), sizeof(void*)),
137                               (size_t)getSize()) != 0) {
138              assert(0 && "posix_memalign failed.");
139            }
140#else
141            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
142                               (size_t)getSize());
143
144            assert(my_addr != NULL && "memalign failed.");
145#endif
146          }
147          break;
148
149        case SHN_ABS:
150        case SHN_UNDEF:
151        case SHN_XINDEX:
152          assert(0 && "STT_OBJECT with special st_shndx.");
153          break;
154      }
155      break;
156
157
158    case STT_FUNC:
159      switch (idx) {
160        default:
161          {
162#ifndef NDEBUG
163            ELFSectionHeaderTableTy const *header =
164              owner->getSectionHeaderTable();
165            assert((*header)[idx]->getType() == SHT_PROGBITS &&
166                   "STT_FUNC with not PROGBITS section.");
167#endif
168            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
169            assert(sec != 0 && "STT_FUNC with null section.");
170
171            ELFSectionProgBitsTy const &st =
172              static_cast<ELFSectionProgBitsTy const &>(*sec);
173            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
174          }
175          break;
176
177        case SHN_ABS:
178        case SHN_COMMON:
179        case SHN_UNDEF:
180        case SHN_XINDEX:
181          assert(0 && "STT_FUNC with special st_shndx.");
182          break;
183      }
184      break;
185
186
187    case STT_SECTION:
188      switch (idx) {
189        default:
190          {
191#ifndef NDEBUG
192            ELFSectionHeaderTableTy const *header =
193              owner->getSectionHeaderTable();
194            assert(((*header)[idx]->getType() == SHT_PROGBITS ||
195                    (*header)[idx]->getType() == SHT_NOBITS) &&
196                   "STT_SECTION with not BITS section.");
197#endif
198            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
199            assert(sec != 0 && "STT_SECTION with null section.");
200
201            ELFSectionBitsTy const &st =
202              static_cast<ELFSectionBitsTy const &>(*sec);
203            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
204          }
205          break;
206
207        case SHN_ABS:
208        case SHN_COMMON:
209        case SHN_UNDEF:
210        case SHN_XINDEX:
211          assert(0 && "STT_SECTION with special st_shndx.");
212          break;
213      }
214      break;
215
216    case STT_NOTYPE:
217      return 0;
218
219    case STT_COMMON:
220    case STT_FILE:
221    case STT_TLS:
222    case STT_LOOS:
223    case STT_HIOS:
224    case STT_LOPROC:
225    case STT_HIPROC:
226      assert(0 && "Not implement.");
227      return 0;
228  }
229  return my_addr;
230}
231
232#endif // ELF_SYMBOL_HXX
233