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