ELFSectionHeaderTable.h revision 8ec15a3ebbf0037872574d364881f7c0c8533eac
161dfca9e892597db79889addb7a3abf54cd50588Logan Chien#ifndef ELF_SECTION_HEADER_TABLE_H
261dfca9e892597db79889addb7a3abf54cd50588Logan Chien#define ELF_SECTION_HEADER_TABLE_H
361dfca9e892597db79889addb7a3abf54cd50588Logan Chien
45b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa#include "ELFSectionHeader.h"
55b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa#include "ELFSectionTable_CRTP.h"
65b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa
71f100419d794fa433336190aa47bb0862f93f978TDYa#include <llvm/ADT/OwningPtr.h>
8921465005aca46a100d137c9608a0aedd846e290Logan Chien
961dfca9e892597db79889addb7a3abf54cd50588Logan Chien#include <vector>
10541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa#include <string>
1161dfca9e892597db79889addb7a3abf54cd50588Logan Chien
1261dfca9e892597db79889addb7a3abf54cd50588Logan Chien#include <assert.h>
1361dfca9e892597db79889addb7a3abf54cd50588Logan Chien
14a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth> class ELFObject;
1561dfca9e892597db79889addb7a3abf54cd50588Logan Chien
16a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
178ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chienclass ELFSectionHeaderTable {
1861dfca9e892597db79889addb7a3abf54cd50588Logan Chienprivate:
198ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  std::vector<ELFSectionHeader<Bitwidth> *> table;
2061dfca9e892597db79889addb7a3abf54cd50588Logan Chien
2161dfca9e892597db79889addb7a3abf54cd50588Logan Chienprivate:
2261dfca9e892597db79889addb7a3abf54cd50588Logan Chien  ELFSectionHeaderTable() {
2361dfca9e892597db79889addb7a3abf54cd50588Logan Chien  }
2461dfca9e892597db79889addb7a3abf54cd50588Logan Chien
2561dfca9e892597db79889addb7a3abf54cd50588Logan Chienpublic:
2661dfca9e892597db79889addb7a3abf54cd50588Logan Chien  template <typename Archiver>
271f100419d794fa433336190aa47bb0862f93f978TDYa  static ELFSectionHeaderTable<Bitwidth> *
2861dfca9e892597db79889addb7a3abf54cd50588Logan Chien  read(Archiver &AR, ELFObject<Bitwidth> *owner);
2961dfca9e892597db79889addb7a3abf54cd50588Logan Chien
308ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  ELFSectionHeader<Bitwidth> const *operator[](size_t i) const {
318ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien    return table[i];
328ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  }
338ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien
348ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  ELFSectionHeader<Bitwidth> *operator[](size_t i) {
358ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien    return table[i];
368ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  }
37af521b05a143c96604dbb7488e155c5248e34462Logan Chien
385b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa  ELFSectionHeader<Bitwidth> const *getByName(const std::string &str) const;
395b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa  ELFSectionHeader<Bitwidth> *getByName(const std::string &str);
40541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa
418ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  void print() const;
4261dfca9e892597db79889addb7a3abf54cd50588Logan Chien};
4361dfca9e892597db79889addb7a3abf54cd50588Logan Chien
44af521b05a143c96604dbb7488e155c5248e34462Logan Chien
4561dfca9e892597db79889addb7a3abf54cd50588Logan Chien#include "ELFObject.h"
4661dfca9e892597db79889addb7a3abf54cd50588Logan Chien#include "ELFHeader.h"
4761dfca9e892597db79889addb7a3abf54cd50588Logan Chien
48a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
4961dfca9e892597db79889addb7a3abf54cd50588Logan Chientemplate <typename Archiver>
501f100419d794fa433336190aa47bb0862f93f978TDYainline ELFSectionHeaderTable<Bitwidth> *
5161dfca9e892597db79889addb7a3abf54cd50588Logan ChienELFSectionHeaderTable<Bitwidth>::read(Archiver &AR,
5261dfca9e892597db79889addb7a3abf54cd50588Logan Chien                                      ELFObject<Bitwidth> *owner) {
5361dfca9e892597db79889addb7a3abf54cd50588Logan Chien  if (!AR) {
5461dfca9e892597db79889addb7a3abf54cd50588Logan Chien    // Archiver is in bad state before calling read function.
5561dfca9e892597db79889addb7a3abf54cd50588Logan Chien    // Return NULL and do nothing.
561f100419d794fa433336190aa47bb0862f93f978TDYa    return 0;
5761dfca9e892597db79889addb7a3abf54cd50588Logan Chien  }
5861dfca9e892597db79889addb7a3abf54cd50588Logan Chien
5961dfca9e892597db79889addb7a3abf54cd50588Logan Chien  // Allocate a new section header table and assign the owner.
601f100419d794fa433336190aa47bb0862f93f978TDYa  llvm::OwningPtr<ELFSectionHeaderTable> tab(new ELFSectionHeaderTable());
6161dfca9e892597db79889addb7a3abf54cd50588Logan Chien
6261dfca9e892597db79889addb7a3abf54cd50588Logan Chien  // Get ELF header
6361dfca9e892597db79889addb7a3abf54cd50588Logan Chien  ELFHeader<Bitwidth> const *header = owner->getHeader();
6461dfca9e892597db79889addb7a3abf54cd50588Logan Chien
6561dfca9e892597db79889addb7a3abf54cd50588Logan Chien  assert(header->getSectionHeaderEntrySize() >=
6661dfca9e892597db79889addb7a3abf54cd50588Logan Chien         TypeTraits<ELFSectionHeader<Bitwidth> >::size);
6761dfca9e892597db79889addb7a3abf54cd50588Logan Chien
6861dfca9e892597db79889addb7a3abf54cd50588Logan Chien  size_t pending = TypeTraits<ELFSectionHeader<Bitwidth> >::size -
6961dfca9e892597db79889addb7a3abf54cd50588Logan Chien                   header->getSectionHeaderEntrySize();
7061dfca9e892597db79889addb7a3abf54cd50588Logan Chien
7161dfca9e892597db79889addb7a3abf54cd50588Logan Chien  // Seek to the address of section header
7261dfca9e892597db79889addb7a3abf54cd50588Logan Chien  AR.seek(header->getSectionHeaderTableOffset(), true);
7361dfca9e892597db79889addb7a3abf54cd50588Logan Chien
7461dfca9e892597db79889addb7a3abf54cd50588Logan Chien  for (size_t i = 0; i < header->getSectionHeaderNum(); ++i) {
751f100419d794fa433336190aa47bb0862f93f978TDYa    llvm::OwningPtr<ELFSectionHeader<Bitwidth> > sh(
7655b5e7c242e599b88f5727352758808461483000Logan Chien      ELFSectionHeader<Bitwidth>::read(AR, owner, i));
7761dfca9e892597db79889addb7a3abf54cd50588Logan Chien
7861dfca9e892597db79889addb7a3abf54cd50588Logan Chien    if (!sh) {
7961dfca9e892597db79889addb7a3abf54cd50588Logan Chien      // Something wrong while reading the section header.
801f100419d794fa433336190aa47bb0862f93f978TDYa      return 0;
8161dfca9e892597db79889addb7a3abf54cd50588Logan Chien    }
8261dfca9e892597db79889addb7a3abf54cd50588Logan Chien
8361dfca9e892597db79889addb7a3abf54cd50588Logan Chien    AR.seek(pending);
841f100419d794fa433336190aa47bb0862f93f978TDYa    tab->table.push_back(sh.take());
8561dfca9e892597db79889addb7a3abf54cd50588Logan Chien  }
8661dfca9e892597db79889addb7a3abf54cd50588Logan Chien
871f100419d794fa433336190aa47bb0862f93f978TDYa  return tab.take();
8861dfca9e892597db79889addb7a3abf54cd50588Logan Chien}
8961dfca9e892597db79889addb7a3abf54cd50588Logan Chien
90a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
918ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chieninline void ELFSectionHeaderTable<Bitwidth>::print() const {
928ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  using namespace llvm;
938ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien
948ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  out() << '\n' << fillformat('=', 79) << '\n';
958ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  out().changeColor(raw_ostream::WHITE, true);
968ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  out() << "ELF Section Header Table" << '\n';
978ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  out().resetColor();
988ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien
998ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  for (size_t i = 0; i < table.size(); ++i) {
1008ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien    (*this)[i]->print();
1018ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  }
1028ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien
1038ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  out() << fillformat('=', 79) << '\n';
1048ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien}
10561dfca9e892597db79889addb7a3abf54cd50588Logan Chien
106a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
107541763d9f2395cf4170d6f8fad0b58098f35c70cTDYainline ELFSectionHeader<Bitwidth> const *
1085b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYaELFSectionHeaderTable<Bitwidth>::getByName(const std::string &str) const {
109541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa  // TODO: Use map
1108ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  for (size_t i = 0; i < table.size(); ++i) {
1118ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien    if (str == std::string(table[i]->getName())) {
1128ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien      return table[i];
113541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa    }
114541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa  }
115541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa  // Return SHN_UNDEF section header;
1168ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien  return table[0];
117541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa}
118541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa
119a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
120541763d9f2395cf4170d6f8fad0b58098f35c70cTDYainline ELFSectionHeader<Bitwidth> *
1215b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYaELFSectionHeaderTable<Bitwidth>::getByName(const std::string &str) {
1225c543a0761c5a7f72565351bc16ec31d6f675602TDYa  ELFSectionHeaderTable<Bitwidth> const *const_this = this;
1235c543a0761c5a7f72565351bc16ec31d6f675602TDYa  ELFSectionHeader<Bitwidth> const *shptr = const_this->getByName(str);
124541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa  // Const cast for the same API's const and non-const versions.
125541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa  return const_cast<ELFSectionHeader<Bitwidth> *>(shptr);
126541763d9f2395cf4170d6f8fad0b58098f35c70cTDYa}
1278ec15a3ebbf0037872574d364881f7c0c8533eacLogan Chien
12861dfca9e892597db79889addb7a3abf54cd50588Logan Chien#endif // ELF_SECTION_HEADER_TABLE_H
129