ELFSectionHeaderTable.h revision 541763d9f2395cf4170d6f8fad0b58098f35c70c
1#ifndef ELF_SECTION_HEADER_TABLE_H
2#define ELF_SECTION_HEADER_TABLE_H
3
4#include <boost/shared_ptr.hpp>
5#include <vector>
6#include <string>
7
8#include <assert.h>
9
10template <size_t Bitwidth> class ELFObject;
11template <size_t Bitwidth> class ELFSectionHeader;
12
13template <size_t Bitwidth>
14class ELFSectionHeaderTable {
15private:
16  ELFObject<Bitwidth> *owner;
17  std::vector<boost::shared_ptr<ELFSectionHeader<Bitwidth> > > table;
18
19private:
20  ELFSectionHeaderTable() {
21  }
22
23public:
24  template <typename Archiver>
25  static boost::shared_ptr<ELFSectionHeaderTable<Bitwidth> >
26  read(Archiver &AR, ELFObject<Bitwidth> *owner);
27
28  ELFSectionHeader<Bitwidth> const *operator[](size_t i) const {
29    return table[i].get();
30  }
31
32  ELFSectionHeader<Bitwidth> *operator[](size_t i) {
33    return table[i].get();
34  }
35
36  ELFSectionHeader<Bitwidth> const *operator[](const std::string &str) const;
37  ELFSectionHeader<Bitwidth> *operator[](const std::string &str);
38
39  void print();
40};
41
42
43#include "ELFObject.h"
44#include "ELFHeader.h"
45#include "ELFSectionHeader.h"
46#include "ELFSection.h"
47#include "ELFTypes.h"
48
49
50template <size_t Bitwidth>
51template <typename Archiver>
52inline boost::shared_ptr<ELFSectionHeaderTable<Bitwidth> >
53ELFSectionHeaderTable<Bitwidth>::read(Archiver &AR,
54                                      ELFObject<Bitwidth> *owner) {
55  if (!AR) {
56    // Archiver is in bad state before calling read function.
57    // Return NULL and do nothing.
58    return boost::shared_ptr<ELFSectionHeaderTable>();
59  }
60
61  // Allocate a new section header table and assign the owner.
62  boost::shared_ptr<ELFSectionHeaderTable> tab(new ELFSectionHeaderTable());
63  tab->owner = owner;
64
65  // Get ELF header
66  ELFHeader<Bitwidth> const *header = owner->getHeader();
67
68  assert(header->getSectionHeaderEntrySize() >=
69         TypeTraits<ELFSectionHeader<Bitwidth> >::size);
70
71  size_t pending = TypeTraits<ELFSectionHeader<Bitwidth> >::size -
72                   header->getSectionHeaderEntrySize();
73
74  // Seek to the address of section header
75  AR.seek(header->getSectionHeaderTableOffset(), true);
76
77  for (size_t i = 0; i < header->getSectionHeaderNum(); ++i) {
78    boost::shared_ptr<ELFSectionHeader<Bitwidth> > sh(
79      ELFSectionHeader<Bitwidth>::read(AR, owner, i));
80
81    if (!sh) {
82      // Something wrong while reading the section header.
83      return boost::shared_ptr<ELFSectionHeaderTable>();
84    }
85
86    AR.seek(pending);
87    tab->table.push_back(sh);
88  }
89
90  return tab;
91}
92
93template <size_t Bitwidth>
94inline void ELFSectionHeaderTable<Bitwidth>::print() {
95  using namespace std;
96  using namespace term;
97  using namespace term::color;
98
99  cout << endl << setw(79) << setfill('=') << '=' << endl;
100  cout << light::white()
101       << "ELF Section Header Table" << normal() << endl;
102
103  for (size_t i = 0; i < table.size(); ++i) {
104    table[i]->print();
105  }
106
107  cout << setw(79) << setfill('=') << '=' << endl << endl;
108}
109
110template <size_t Bitwidth>
111inline ELFSectionHeader<Bitwidth> const *
112ELFSectionHeaderTable<Bitwidth>::operator[](const std::string &str) const {
113  // TODO: Use map
114  for (size_t i = 0; i < table.size(); ++i) {
115    if (str == string(table[i]->getName())) {
116      return table[i].get();
117    }
118  }
119  // Return SHN_UNDEF section header;
120  return table[0].get();
121}
122
123template <size_t Bitwidth>
124inline ELFSectionHeader<Bitwidth> *
125ELFSectionHeaderTable<Bitwidth>::operator[](const std::string &str) {
126  ELFSectionHeader<Bitwidth> const *shptr = (*this)[str];
127  // Const cast for the same API's const and non-const versions.
128  return const_cast<ELFSectionHeader<Bitwidth> *>(shptr);
129}
130#endif // ELF_SECTION_HEADER_TABLE_H
131