ELFSymbol.hxx revision 58611fc8193e7386698178f167a2e0cbdd6a4f6f
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            int r = posix_memalign(&my_addr,
136                                   std::max((size_t)getValue(), sizeof(void*)),
137                                   (size_t)getSize());
138            assert(r==0 && "posix_memalign failed.");
139#else
140            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
141                               (size_t)getSize());
142
143            assert(my_addr != NULL && "memalign failed.");
144#endif
145          }
146          break;
147
148        case SHN_ABS:
149        case SHN_UNDEF:
150        case SHN_XINDEX:
151          assert(0 && "STT_OBJECT with special st_shndx.");
152          break;
153      }
154      break;
155
156
157    case STT_FUNC:
158      switch (idx) {
159        default:
160          {
161#ifndef NDEBUG
162            ELFSectionHeaderTableTy const *header =
163              owner->getSectionHeaderTable();
164            assert((*header)[idx]->getType() == SHT_PROGBITS &&
165                   "STT_FUNC with not PROGBITS section.");
166#endif
167            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
168            assert(sec != 0 && "STT_FUNC with null section.");
169
170            ELFSectionProgBitsTy const &st =
171              static_cast<ELFSectionProgBitsTy const &>(*sec);
172            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
173          }
174          break;
175
176        case SHN_ABS:
177        case SHN_COMMON:
178        case SHN_UNDEF:
179        case SHN_XINDEX:
180          assert(0 && "STT_FUNC with special st_shndx.");
181          break;
182      }
183      break;
184
185
186    case STT_SECTION:
187      switch (idx) {
188        default:
189          {
190#ifndef NDEBUG
191            ELFSectionHeaderTableTy const *header =
192              owner->getSectionHeaderTable();
193            assert(((*header)[idx]->getType() == SHT_PROGBITS ||
194                    (*header)[idx]->getType() == SHT_NOBITS) &&
195                   "STT_SECTION with not BITS section.");
196#endif
197            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
198            assert(sec != 0 && "STT_SECTION with null section.");
199
200            ELFSectionBitsTy const &st =
201              static_cast<ELFSectionBitsTy const &>(*sec);
202            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
203          }
204          break;
205
206        case SHN_ABS:
207        case SHN_COMMON:
208        case SHN_UNDEF:
209        case SHN_XINDEX:
210          assert(0 && "STT_SECTION with special st_shndx.");
211          break;
212      }
213      break;
214
215    case STT_NOTYPE:
216      return 0;
217
218    case STT_COMMON:
219    case STT_FILE:
220    case STT_TLS:
221    case STT_LOOS:
222    case STT_HIOS:
223    case STT_LOPROC:
224    case STT_HIPROC:
225      assert(0 && "Not implement.");
226      return 0;
227  }
228  return my_addr;
229}
230
231#endif // ELF_SYMBOL_HXX
232