1ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao/*
2ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Copyright 2011, The Android Open Source Project
3ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
4ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * you may not use this file except in compliance with the License.
6ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * You may obtain a copy of the License at
7ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
8ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
10ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
11ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * See the License for the specific language governing permissions and
14ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * limitations under the License.
15ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao */
16ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao
179f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#ifndef ELF_SYMBOL_HXX
189f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#define ELF_SYMBOL_HXX
199f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
209f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSectionHeaderTable.h"
219f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSection.h"
229f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSectionStrTab.h"
239f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
249f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFObject.h"
259f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSectionHeaderTable.h"
269f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSectionProgBits.h"
279f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "ELFSectionNoBits.h"
289f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
29c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#include "utils/rsl_assert.h"
30404833ada8caa7027105bd52bd36ab7822030369TDYa#include "ELF.h"
31c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa
329f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chientemplate <unsigned Bitwidth>
339f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chieninline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
3458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable();
359f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
3658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionTy const *section = owner->getSectionByIndex(index);
3758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSectionStrTabTy const &strtab =
3858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    *static_cast<ELFSectionStrTabTy const *>(section);
399f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  return strtab[getNameIndex()];
409f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien}
419f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
429f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chientemplate <unsigned Bitwidth>
439f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chientemplate <typename Archiver>
449f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chieninline ELFSymbol<Bitwidth> *
459f3703c8165b74517567e0d3a7a4f71ae8337c72Logan ChienELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
4658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien                               ELFObjectTy const *owner,
4758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien                               size_t index) {
489f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  if (!AR) {
499f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    // Archiver is in bad state before calling read function.
509f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    // Return NULL and do nothing.
519f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    return 0;
529f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
539f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
5458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  llvm::OwningPtr<ELFSymbolTy> sh(new ELFSymbolTy());
559f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
569f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  if (!sh->serialize(AR)) {
579f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    // Unable to read the structure.  Return NULL.
589f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    return 0;
599f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
609f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
619f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  if (!sh->isValid()) {
629f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    // SymTabEntry read from archiver is not valid.  Return NULL.
639f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    return 0;
649f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
659f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
669f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  // Set the section header index
679f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  sh->index = index;
689f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
699f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  // Set the owner elf object
709f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  sh->owner = owner;
719f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
729f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  return sh.take();
739f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien}
749f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
759f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chientemplate <unsigned Bitwidth>
7658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chieninline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
779f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  using namespace llvm;
789f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
799f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  if (shouldPrintHeader) {
809f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out() << '\n' << fillformat('=', 79) << '\n';
819f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out().changeColor(raw_ostream::WHITE, true);
829f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out() << "ELF Symbol Table Entry "
839f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          << this->getIndex() << '\n';
849f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out().resetColor();
859f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out() << fillformat('-', 79) << '\n';
869f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  } else {
879f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out() << fillformat('-', 79) << '\n';
889f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out().changeColor(raw_ostream::YELLOW, true);
899f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out() << "ELF Symbol Table Entry "
909f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          << this->getIndex() << " : " << '\n';
919f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    out().resetColor();
929f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
939f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
949f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#define PRINT_LINT(title, value) \
959f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
969f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Name",        getName()                                    );
979f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Type",        getTypeStr(getType())                        );
989f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
999f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
1009f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Shtab Index", getSectionIndex()                            );
1019f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Value",       getValue()                                   );
1029f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  PRINT_LINT("Size",        getSize()                                    );
1039f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#undef PRINT_LINT
1049f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
1059f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien// TODO: Horizontal type or vertical type can use option to decide.
1069f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#if 0
1079f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  using namespace term::color;
1089f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  using namespace std;
109ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao
1109f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  cout << setw(20) << getName() <<
1119f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(10) << getTypeStr(getType()) <<
1129f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
1139f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(15) << getVisibilityStr(getVisibility()) <<
1149f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(10) << getSectionIndex() <<
1159f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(7) << getValue() <<
1169f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          setw(7) << getSize() <<
1179f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          endl;
1189f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#endif
1199f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien}
1209f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
1219f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chientemplate <unsigned Bitwidth>
1229ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsiehvoid *ELFSymbol_CRTP<Bitwidth>::getAddress(int machine, bool autoAlloc) const {
1239f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  if (my_addr != 0) {
1249f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    return my_addr;
1259f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
1269f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  size_t idx = (size_t)getSectionIndex();
1279f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  switch (getType()) {
1289f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    default:
1299f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      break;
1309f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
1319f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_OBJECT:
1329f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      switch (idx) {
1339f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        default:
1349f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          {
13558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionHeaderTableTy const *header =
1369f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien              owner->getSectionHeaderTable();
137e1098159e6e99d941b89044c398c270965e90ce1Logan Chien
1381045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien            unsigned section_type = (*header)[idx]->getType();
1391045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1401045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien            rsl_assert((section_type == SHT_PROGBITS ||
1411045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                        section_type == SHT_NOBITS) &&
1421045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                       "STT_OBJECT with not BITS section.");
1431045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1441045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien            if (section_type == SHT_NOBITS) {
1451045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              // FIXME(logan): This is a workaround for .lcomm directives
1461045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              // bug of LLVM ARM MC code generator.  Remove this when the
1471045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              // LLVM bug is fixed.
1481045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1491045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              size_t align = 16;
1501045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1511045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              my_addr = const_cast<ELFObjectTy *>(owner)->
1521045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                allocateSHNCommonData((size_t)getSize(), align);
1531045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1541045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              if (!my_addr) {
1551045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
1561045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                abort();
1571045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              }
1581045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien            } else {
1591045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              ELFSectionTy const *sec = owner->getSectionByIndex(idx);
1601045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              rsl_assert(sec != 0 && "STT_OBJECT with null section.");
1611045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien
1621045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              ELFSectionBitsTy const &st =
1631045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien                static_cast<ELFSectionBitsTy const &>(*sec);
1641045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien              my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue());
1651045a1dabf49181e7cba2e37a891799ba9055d9fLogan Chien            }
1669f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          }
1679f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
1689f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
1699f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_COMMON:
1709f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          {
171b2584ebd9eff677283b23ab762ef411fe16ba22dLogan Chien            if (!autoAlloc) {
172b2584ebd9eff677283b23ab762ef411fe16ba22dLogan Chien              return NULL;
173b2584ebd9eff677283b23ab762ef411fe16ba22dLogan Chien            }
1749f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#if 0
1759f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
17671884036ac3215a7cb9f6f95bd0902efbb344071Logan Chien            if (posix_memalign(&my_addr,
17771884036ac3215a7cb9f6f95bd0902efbb344071Logan Chien                               std::max((size_t)getValue(), sizeof(void*)),
17871884036ac3215a7cb9f6f95bd0902efbb344071Logan Chien                               (size_t)getSize()) != 0) {
179c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa              rsl_assert(0 && "posix_memalign failed.");
18071884036ac3215a7cb9f6f95bd0902efbb344071Logan Chien            }
1819f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#else
1829f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
1839f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien                               (size_t)getSize());
1849f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
185c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa            rsl_assert(my_addr != NULL && "memalign failed.");
1869f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#endif
1873e262e0c44861b9c615e2843a83a354a42c0dde7Logan Chien            if (my_addr) {
1883e262e0c44861b9c615e2843a83a354a42c0dde7Logan Chien              memset(my_addr, '\0', getSize());
1893e262e0c44861b9c615e2843a83a354a42c0dde7Logan Chien            }
190c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#else
191b1a853b0e8639be08bc06594e092f3697c1ddd06Shih-wei Liao            size_t align = (size_t)getValue();
1929f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien            my_addr = const_cast<ELFObjectTy *>(owner)->
1939f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien                          allocateSHNCommonData((size_t)getSize(), align);
1949f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien            if (!my_addr) {
195c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa              rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
1969f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien              abort();
1979f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien            }
198c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#endif
1999f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          }
2009f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2019f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2029f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_UNDEF:
2039ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh          if (machine == EM_MIPS && strcmp(getName(), "_gp_disp") == 0) // OK for MIPS
2040a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu            break;
2059ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh
2060a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu        case SHN_ABS:
2079f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_XINDEX:
208c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa          rsl_assert(0 && "STT_OBJECT with special st_shndx.");
2099f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2109f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      }
2119f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      break;
2129f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2139f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2149f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_FUNC:
2159f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      switch (idx) {
2169f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        default:
2179f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          {
2189f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#ifndef NDEBUG
21958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionHeaderTableTy const *header =
2209f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien              owner->getSectionHeaderTable();
221c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa            rsl_assert((*header)[idx]->getType() == SHT_PROGBITS &&
2229f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien                   "STT_FUNC with not PROGBITS section.");
2239f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#endif
22458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
225c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa            rsl_assert(sec != 0 && "STT_FUNC with null section.");
2269f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
22758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionProgBitsTy const &st =
22858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien              static_cast<ELFSectionProgBitsTy const &>(*sec);
2299f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
2309f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          }
2319f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2329f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2339f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_ABS:
2349f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_COMMON:
2359f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_UNDEF:
2369f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_XINDEX:
237c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa          rsl_assert(0 && "STT_FUNC with special st_shndx.");
2389f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2399f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      }
2409f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      break;
2419f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2429f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2439f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_SECTION:
2449f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      switch (idx) {
2459f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        default:
2469f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          {
2479f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#ifndef NDEBUG
24858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionHeaderTableTy const *header =
2499f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien              owner->getSectionHeaderTable();
250c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
2519f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien                    (*header)[idx]->getType() == SHT_NOBITS) &&
2529f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien                   "STT_SECTION with not BITS section.");
2539f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#endif
25458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
255c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa            rsl_assert(sec != 0 && "STT_SECTION with null section.");
2569f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
25758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien            ELFSectionBitsTy const &st =
25858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien              static_cast<ELFSectionBitsTy const &>(*sec);
2599f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
2609f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          }
2619f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2629f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2639f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_ABS:
2649f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_COMMON:
2659f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_UNDEF:
2669f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien        case SHN_XINDEX:
267c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa          rsl_assert(0 && "STT_SECTION with special st_shndx.");
2689f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien          break;
2699f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      }
2709f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      break;
2719f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
2729f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_NOTYPE:
273f3f63d6ded54ea520f5066979b53c2356092692dTDYa      switch (idx) {
274f3f63d6ded54ea520f5066979b53c2356092692dTDYa        default:
275f3f63d6ded54ea520f5066979b53c2356092692dTDYa          {
276f3f63d6ded54ea520f5066979b53c2356092692dTDYa#ifndef NDEBUG
277f3f63d6ded54ea520f5066979b53c2356092692dTDYa            ELFSectionHeaderTableTy const *header =
278f3f63d6ded54ea520f5066979b53c2356092692dTDYa              owner->getSectionHeaderTable();
279f3f63d6ded54ea520f5066979b53c2356092692dTDYa            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
280f3f63d6ded54ea520f5066979b53c2356092692dTDYa                    (*header)[idx]->getType() == SHT_NOBITS) &&
281f3f63d6ded54ea520f5066979b53c2356092692dTDYa                   "STT_SECTION with not BITS section.");
282f3f63d6ded54ea520f5066979b53c2356092692dTDYa#endif
283f3f63d6ded54ea520f5066979b53c2356092692dTDYa            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
284f3f63d6ded54ea520f5066979b53c2356092692dTDYa            rsl_assert(sec != 0 && "STT_SECTION with null section.");
285f3f63d6ded54ea520f5066979b53c2356092692dTDYa
286f3f63d6ded54ea520f5066979b53c2356092692dTDYa            ELFSectionBitsTy const &st =
287f3f63d6ded54ea520f5066979b53c2356092692dTDYa              static_cast<ELFSectionBitsTy const &>(*sec);
288f3f63d6ded54ea520f5066979b53c2356092692dTDYa            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
289f3f63d6ded54ea520f5066979b53c2356092692dTDYa          }
290f3f63d6ded54ea520f5066979b53c2356092692dTDYa          break;
291f3f63d6ded54ea520f5066979b53c2356092692dTDYa
292f3f63d6ded54ea520f5066979b53c2356092692dTDYa        case SHN_ABS:
293f3f63d6ded54ea520f5066979b53c2356092692dTDYa        case SHN_COMMON:
294f3f63d6ded54ea520f5066979b53c2356092692dTDYa        case SHN_XINDEX:
295f3f63d6ded54ea520f5066979b53c2356092692dTDYa          rsl_assert(0 && "STT_SECTION with special st_shndx.");
296f3f63d6ded54ea520f5066979b53c2356092692dTDYa          break;
297f3f63d6ded54ea520f5066979b53c2356092692dTDYa        case SHN_UNDEF:
298f3f63d6ded54ea520f5066979b53c2356092692dTDYa          return 0;
299f3f63d6ded54ea520f5066979b53c2356092692dTDYa      }
300f3f63d6ded54ea520f5066979b53c2356092692dTDYa      break;
3019f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      return 0;
3029f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
3039f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_COMMON:
3049f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_FILE:
3059f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_TLS:
3069f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_LOOS:
3079f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_HIOS:
3089f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_LOPROC:
3099f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien    case STT_HIPROC:
310c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa      rsl_assert(0 && "Not implement.");
3119f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien      return 0;
3129f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  }
3139f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien  return my_addr;
3149f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien}
3159f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien
3169f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#endif // ELF_SYMBOL_HXX
317