ELFSymbol.h revision d90e4881f16d40cd045bbe094f073353328d5a09
11e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#ifndef ELF_SECTION_SYMTAB_ENTRY_H
21e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_SECTION_SYMTAB_ENTRY_H
31e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
41e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include "ELFTypes.h"
51e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
62956c0e06b1c51f521645a076802686976c4b2f6TDYa#include <llvm/ADT/OwningPtr.h>
72956c0e06b1c51f521645a076802686976c4b2f6TDYa
81e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include <string>
9937df4784a064c4f32b3354f76ef9c4361711173TDYa#include <algorithm>
101e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
11921465005aca46a100d137c9608a0aedd846e290Logan Chien#include <assert.h>
12921465005aca46a100d137c9608a0aedd846e290Logan Chien#include <elf.h>
136a75cacd74aac486d2313f725555f323725cb1dbLogan Chien#include <malloc.h>
141e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include <stdint.h>
15921465005aca46a100d137c9608a0aedd846e290Logan Chien#include <stdlib.h>
161e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
171e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <size_t Bitwidth> class ELFObject;
18d90e4881f16d40cd045bbe094f073353328d5a09Logan Chientemplate <size_t Bitwidth> class ELFSymbol;
19d90e4881f16d40cd045bbe094f073353328d5a09Logan Chientemplate <size_t Bitwidth> class ELFSymbol_CRTP;
201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
211e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
22d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbolHelperMixin {
231e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
241e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getTypeStr(uint8_t);
251e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getBindingAttributeStr(uint8_t);
261e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getVisibilityStr(uint8_t);
271e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
281e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
291e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
301e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <size_t Bitwidth>
31d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol_CRTP : private ELFSymbolHelperMixin {
321e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
341e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
35d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  typedef ELFSymbol<Bitwidth> ConcreteELFSymbol;
361e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
371e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
381e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFObject<Bitwidth> const *owner;
391e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
401e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t index;
411e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
421e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t st_name;
431e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_info;
441e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_other;
451e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t st_shndx;
461e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t st_value;
471e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  xword_t st_size;
481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
49d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  mutable void *my_addr;
50d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
511e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
52d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol_CRTP() { my_addr = 0; }
53d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ~ELFSymbol_CRTP() {
54d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    if (my_addr != 0 &&
55d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getType() == STT_OBJECT &&
56d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getSectionIndex() == SHN_COMMON) {
57d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      std::free(my_addr);
58d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    }
59d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  }
601e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
611e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
621e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t getIndex() const {
631e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return index;
641e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
651e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
661e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t getNameIndex() const {
671e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_name;
681e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
691e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  char const *getName() const;
711e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
721e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa// I don't want to include elf.h in .h file, so define those macro by ourself.
731e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_BIND(i)   ((i)>>4)
741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_TYPE(i)   ((i)&0xf)
751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getType() const {
771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_TYPE(st_info);
781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getBindingAttribute() const {
811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_BIND(st_info);
821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
831e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_BIND
841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_TYPE
851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_INFO
861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_VISIBILITY(o) ((o)&0x3)
881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getVisibility() const {
891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_VISIBILITY(st_other);
901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_VISIBILITY
921e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t getSectionIndex() const {
941e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_shndx;
951e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
971e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t getValue() const {
981e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_value;
991e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1011e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  xword_t getSize() const {
1021e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_size;
1031e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1041e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
105d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  void *getAddress() const;
106d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
1075c543a0761c5a7f72565351bc16ec31d6f675602TDYa  void setAddress(void *addr) {
1085c543a0761c5a7f72565351bc16ec31d6f675602TDYa    my_addr = addr;
1095c543a0761c5a7f72565351bc16ec31d6f675602TDYa  }
1105c543a0761c5a7f72565351bc16ec31d6f675602TDYa
1111e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool isValid() const {
1121e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // FIXME: Should check the correctness of the section header.
1131e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return true;
1141e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1151e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1161e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
117d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  static ConcreteELFSymbol *
1181e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
1191e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  void print(bool shouldPrintHeader = false) const;
1211e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1221e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
123d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ConcreteELFSymbol *concrete() {
124d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    return static_cast<ConcreteELFSymbol *>(this);
1251e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1261e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
127d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ConcreteELFSymbol const *concrete() const {
128d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    return static_cast<ConcreteELFSymbol const *>(this);
1291e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1301e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1311e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1321e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa//==================Inline Member Function Definition==========================
1331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1341e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include "ELFSectionHeaderTable.h"
1351e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include "ELFSection.h"
1361e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include "ELFSectionStrTab.h"
1371e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
138d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa#include "ELFObject.h"
139d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa#include "ELFSectionHeaderTable.h"
140d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa#include "ELFSectionProgBits.h"
141d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa#include "ELFSectionNoBits.h"
142d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
1431e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <size_t Bitwidth>
144d90e4881f16d40cd045bbe094f073353328d5a09Logan Chieninline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
1451e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFSectionHeaderTable<Bitwidth> const &shtab =
1461e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    *owner->getSectionHeaderTable();
1475b5dd5a0d5e07a6048abc6866a3ffdc0d0d4bc34TDYa  size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
1481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFSection<Bitwidth> const *section = owner->getSectionByIndex(index);
1491e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFSectionStrTab<Bitwidth> const &strtab =
1501e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    *static_cast<ELFSectionStrTab<Bitwidth> const *>(section);
1511e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  return strtab[getNameIndex()];
1521e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa}
1531e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1541e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <size_t Bitwidth>
1551e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <typename Archiver>
156d90e4881f16d40cd045bbe094f073353328d5a09Logan Chieninline ELFSymbol<Bitwidth> *
157d90e4881f16d40cd045bbe094f073353328d5a09Logan ChienELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
1581e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa                                           ELFObject<Bitwidth> const *owner,
1591e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa                                           size_t index) {
1601e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  if (!AR) {
1611e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // Archiver is in bad state before calling read function.
1621e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // Return NULL and do nothing.
1632956c0e06b1c51f521645a076802686976c4b2f6TDYa    return 0;
1641e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1651e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
166d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  llvm::OwningPtr<ConcreteELFSymbol> sh(
167d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    new ConcreteELFSymbol());
1681e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1691e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  if (!sh->serialize(AR)) {
1701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // Unable to read the structure.  Return NULL.
1712956c0e06b1c51f521645a076802686976c4b2f6TDYa    return 0;
1721e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1731e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  if (!sh->isValid()) {
1751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // SymTabEntry read from archiver is not valid.  Return NULL.
1762956c0e06b1c51f521645a076802686976c4b2f6TDYa    return 0;
1771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  // Set the section header index
1801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  sh->index = index;
1811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  // Set the owner elf object
1831e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  sh->owner = owner;
1841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1852956c0e06b1c51f521645a076802686976c4b2f6TDYa  return sh.take();
1861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa}
1871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <size_t Bitwidth>
189d90e4881f16d40cd045bbe094f073353328d5a09Logan Chieninline void ELFSymbol_CRTP<Bitwidth>::
1901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  print(bool shouldPrintHeader) const {
1915d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa  using namespace llvm;
1924a70163096c79402c2742d63c86c188fa35ff189TDYa
1931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  if (shouldPrintHeader) {
1945d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out() << '\n' << fillformat('=', 79) << '\n';
1955d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out().changeColor(raw_ostream::WHITE, true);
1965d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out() << "ELF Symbol Table Entry "
1975d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa          << this->getIndex() << '\n';
1985d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out().resetColor();
1995d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out() << fillformat('-', 79) << '\n';
2001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  } else {
2015d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out() << fillformat('-', 79) << '\n';
2025d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out().changeColor(raw_ostream::YELLOW, true);
2035d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out() << "ELF Symbol Table Entry "
2045d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa          << this->getIndex() << " : " << '\n';
2055d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa    out().resetColor();
2061e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
2071e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
2081e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define PRINT_LINT(title, value) \
2095d6763916b66a6e6bb9d4fe73311d0c9d1ca4821TDYa  out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
2101e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Name",        getName()                                    );
2111e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Type",        getTypeStr(getType())                        );
2121e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
2131e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
2141e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Shtab Index", getSectionIndex()                            );
2151e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Value",       getValue()                                   );
2161e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  PRINT_LINT("Size",        getSize()                                    );
2171e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef PRINT_LINT
2181e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
2191e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa// TODO: Horizontal type or vertical type can use option to decide.
2201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#if 0
2211e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  using namespace term::color;
2221e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  using namespace std;
2231e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
2241e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  cout << setw(20) << getName() <<
2251e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(10) << getTypeStr(getType()) <<
2261e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
2271e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(15) << getVisibilityStr(getVisibility()) <<
2281e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(10) << getSectionIndex() <<
2291e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(7) << getValue() <<
2301e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          setw(7) << getSize() <<
2311e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa          endl;
2321e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#endif
2331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa}
2341e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
235d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYatemplate <size_t Bitwidth>
236d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienvoid *ELFSymbol_CRTP<Bitwidth>::getAddress() const {
237d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  if (my_addr != 0) {
238d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    return my_addr;
239d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  }
240d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  size_t idx = (size_t)getSectionIndex();
241d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  switch (getType()) {
242d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    default:
243d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      break;
244d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
245d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_OBJECT:
246d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      switch (idx) {
247d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        default:
248d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          {
2492e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#ifndef NDEBUG
250d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionHeaderTable<Bitwidth> const *header =
251d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              owner->getSectionHeaderTable();
252d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(((*header)[idx]->getType() == SHT_PROGBITS ||
253d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                    (*header)[idx]->getType() == SHT_NOBITS) &&
254d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                   "STT_OBJECT with not BITS section.");
2552e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#endif
256d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSection<Bitwidth> const *sec = owner->getSectionByIndex(idx);
257d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(sec != 0 && "STT_OBJECT with null section.");
258d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
259d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionBits<Bitwidth> const &st =
260d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              static_cast<ELFSectionBits<Bitwidth> const &>(*sec);
261d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
262d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          }
263d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
264d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
265d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_COMMON:
266d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          {
2676a75cacd74aac486d2313f725555f323725cb1dbLogan Chien#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
268d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            int r = posix_memalign(&my_addr,
2696a75cacd74aac486d2313f725555f323725cb1dbLogan Chien                                   std::max((size_t)getValue(), sizeof(void*)),
270d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                                   (size_t)getSize());
271d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(r==0 && "posix_memalign failed.");
2726a75cacd74aac486d2313f725555f323725cb1dbLogan Chien#else
2736a75cacd74aac486d2313f725555f323725cb1dbLogan Chien            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
2746a75cacd74aac486d2313f725555f323725cb1dbLogan Chien                               (size_t)getSize());
2756a75cacd74aac486d2313f725555f323725cb1dbLogan Chien
2766a75cacd74aac486d2313f725555f323725cb1dbLogan Chien            assert(my_addr != NULL && "memalign failed.");
2776a75cacd74aac486d2313f725555f323725cb1dbLogan Chien#endif
278d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          }
279d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
280d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
281d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_ABS:
282d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_UNDEF:
283d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_XINDEX:
284d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          assert(0 && "STT_OBJECT with special st_shndx.");
285d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
286d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      }
287d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      break;
288d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
289d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
290d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_FUNC:
291d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      switch (idx) {
292d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        default:
293d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          {
2942e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#ifndef NDEBUG
295d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionHeaderTable<Bitwidth> const *header =
296d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              owner->getSectionHeaderTable();
297d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert((*header)[idx]->getType() == SHT_PROGBITS &&
298d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                   "STT_FUNC with not PROGBITS section.");
2992e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#endif
300d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSection<Bitwidth> const *sec = owner->getSectionByIndex(idx);
301d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(sec != 0 && "STT_FUNC with null section.");
302d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
303d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionProgBits<Bitwidth> const &st =
304d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              static_cast<ELFSectionProgBits<Bitwidth> const &>(*sec);
305d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
306d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          }
307d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
308d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
309d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_ABS:
310d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_COMMON:
311d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_UNDEF:
312d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_XINDEX:
313d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          assert(0 && "STT_FUNC with special st_shndx.");
314d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
315d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      }
316d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      break;
317d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
318d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
319d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_SECTION:
320d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      switch (idx) {
321d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        default:
322d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          {
3232e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#ifndef NDEBUG
324d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionHeaderTable<Bitwidth> const *header =
325d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              owner->getSectionHeaderTable();
326d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(((*header)[idx]->getType() == SHT_PROGBITS ||
327d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                    (*header)[idx]->getType() == SHT_NOBITS) &&
328d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa                   "STT_SECTION with not BITS section.");
3292e7f0beb30f2cb48c0fd5a4ebc7b8a26d19f96d5Logan Chien#endif
330d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSection<Bitwidth> const *sec = owner->getSectionByIndex(idx);
331d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            assert(sec != 0 && "STT_SECTION with null section.");
332d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
333d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            ELFSectionBits<Bitwidth> const &st =
334d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa              static_cast<ELFSectionBits<Bitwidth> const &>(*sec);
335d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
336d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          }
337d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
338d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
339d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_ABS:
340d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_COMMON:
341d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_UNDEF:
342d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        case SHN_XINDEX:
343d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          assert(0 && "STT_SECTION with special st_shndx.");
344d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa          break;
345d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      }
346d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      break;
347d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
348d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_NOTYPE:
3495c543a0761c5a7f72565351bc16ec31d6f675602TDYa      return 0;
3505c543a0761c5a7f72565351bc16ec31d6f675602TDYa
3515c543a0761c5a7f72565351bc16ec31d6f675602TDYa    case STT_COMMON:
352d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_FILE:
353d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_TLS:
354d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_LOOS:
355d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_HIOS:
356d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_LOPROC:
357d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    case STT_HIPROC:
358d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      assert(0 && "Not implement.");
359d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      return 0;
360d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  }
361d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  return my_addr;
362d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa}
3631e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3641e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3651e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3661e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3671e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
368d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<32> : public ELFSymbol_CRTP<32> {
369d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<32>;
3701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3711e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
372d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
3731e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
3741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
3761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
377d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
3781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
3801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
3811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
3821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
3831e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
3841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
3851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
386d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
3871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
3881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
3891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
3911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
3921e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
394d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<64> : public ELFSymbol_CRTP<64> {
395d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<64>;
3961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
3971e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
398d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
3991e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
4001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
4011e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
4021e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
403d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
4041e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
4051e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
4061e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
4071e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
4081e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
4091e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
4101e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
4111e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
412d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
4131e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
4141e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
4151e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
4161e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
4171e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
4181e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
4191e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
4201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#endif // ELF_SECTION_SYMTAB_ENTRY_H
421