ELFSectionHeaderTable.hxx revision 58611fc8193e7386698178f167a2e0cbdd6a4f6f
1#ifndef ELF_SECTION_HEADER_TABLE_HXX
2#define ELF_SECTION_HEADER_TABLE_HXX
3
4#include "ELFHeader.h"
5#include "ELFObject.h"
6#include "ELFSectionHeader.h"
7
8#include <assert.h>
9
10template <unsigned Bitwidth>
11ELFSectionHeaderTable<Bitwidth>::~ELFSectionHeaderTable() {
12  for (size_t i = 0; i < table.size(); ++i) {
13    delete table[i];
14  }
15}
16
17template <unsigned Bitwidth>
18template <typename Archiver>
19inline ELFSectionHeaderTable<Bitwidth> *
20ELFSectionHeaderTable<Bitwidth>::read(Archiver &AR, ELFObjectTy *owner) {
21  if (!AR) {
22    // Archiver is in bad state before calling read function.
23    // Return NULL and do nothing.
24    return 0;
25  }
26
27  // Allocate a new section header table and assign the owner.
28  llvm::OwningPtr<ELFSectionHeaderTable> tab(new ELFSectionHeaderTable());
29
30  // Get ELF header
31  ELFHeaderTy const *header = owner->getHeader();
32
33  assert(header->getSectionHeaderEntrySize() >=
34         TypeTraits<ELFSectionHeaderTy>::size);
35
36  size_t pending = TypeTraits<ELFSectionHeaderTy>::size -
37                   header->getSectionHeaderEntrySize();
38
39  // Seek to the address of section header
40  AR.seek(header->getSectionHeaderTableOffset(), true);
41
42  for (size_t i = 0; i < header->getSectionHeaderNum(); ++i) {
43    llvm::OwningPtr<ELFSectionHeaderTy> sh(
44      ELFSectionHeaderTy::read(AR, owner, i));
45
46    if (!sh) {
47      // Something wrong while reading the section header.
48      return 0;
49    }
50
51    AR.seek(pending);
52    tab->table.push_back(sh.take());
53  }
54
55  return tab.take();
56}
57
58template <unsigned Bitwidth>
59inline void ELFSectionHeaderTable<Bitwidth>::print() const {
60  using namespace llvm;
61
62  out() << '\n' << fillformat('=', 79) << '\n';
63  out().changeColor(raw_ostream::WHITE, true);
64  out() << "ELF Section Header Table" << '\n';
65  out().resetColor();
66
67  for (size_t i = 0; i < table.size(); ++i) {
68    (*this)[i]->print();
69  }
70
71  out() << fillformat('=', 79) << '\n';
72}
73
74template <unsigned Bitwidth>
75inline ELFSectionHeader<Bitwidth> const *
76ELFSectionHeaderTable<Bitwidth>::getByName(const std::string &str) const {
77  // TODO: Use map
78  for (size_t i = 0; i < table.size(); ++i) {
79    if (str == std::string(table[i]->getName())) {
80      return table[i];
81    }
82  }
83  // Return SHN_UNDEF section header;
84  return table[0];
85}
86
87template <unsigned Bitwidth>
88inline ELFSectionHeader<Bitwidth> *
89ELFSectionHeaderTable<Bitwidth>::getByName(const std::string &str) {
90  ELFSectionHeaderTableTy const *const_this = this;
91  ELFSectionHeaderTy const *shptr = const_this->getByName(str);
92  // Const cast for the same API's const and non-const versions.
93  return const_cast<ELFSectionHeaderTy *>(shptr);
94}
95
96#endif // ELF_SECTION_HEADER_TABLE_HXX
97