1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/*
2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project
3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License.
6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at
7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software
11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and
14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License.
15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */
16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef ELF_SYMBOL_HXX
18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_SYMBOL_HXX
19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionHeaderTable.h"
21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSection.h"
22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionStrTab.h"
23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFObject.h"
25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionHeaderTable.h"
26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionProgBits.h"
27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionNoBits.h"
28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/rsl_assert.h"
30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELF.h"
31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline char const *ELFSymbol_CRTP<Bitwidth>::getName() const {
34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionHeaderTableTy const &shtab = *owner->getSectionHeaderTable();
35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t const index = shtab.getByName(std::string(".strtab"))->getIndex();
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionTy const *section = owner->getSectionByIndex(index);
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSectionStrTabTy const &strtab =
38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    *static_cast<ELFSectionStrTabTy const *>(section);
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return strtab[getNameIndex()];
40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <typename Archiver>
44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFSymbol<Bitwidth> *
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFSymbol_CRTP<Bitwidth>::read(Archiver &AR,
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                               ELFObjectTy const *owner,
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                               size_t index) {
48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!AR) {
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Archiver is in bad state before calling read function.
50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Return NULL and do nothing.
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
54d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  std::unique_ptr<ELFSymbolTy> sh(new ELFSymbolTy());
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->serialize(AR)) {
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Unable to read the structure.  Return NULL.
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->isValid()) {
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // SymTabEntry read from archiver is not valid.  Return NULL.
63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  // Set the section header index
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  sh->index = index;
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  // Set the owner elf object
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  sh->owner = owner;
71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
72d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  return sh.release();
73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline void ELFSymbol_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  using namespace llvm;
78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (shouldPrintHeader) {
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << '\n' << fillformat('=', 79) << '\n';
81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().changeColor(raw_ostream::WHITE, true);
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << "ELF Symbol Table Entry "
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          << this->getIndex() << '\n';
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().resetColor();
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << fillformat('-', 79) << '\n';
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  } else {
87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << fillformat('-', 79) << '\n';
88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().changeColor(raw_ostream::YELLOW, true);
89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << "ELF Symbol Table Entry "
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          << this->getIndex() << " : " << '\n';
91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().resetColor();
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define PRINT_LINT(title, value) \
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  out() << format("  %-11s : ", (char const *)(title)) << (value) << '\n'
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Name",        getName()                                    );
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Type",        getTypeStr(getType())                        );
98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Bind",        getBindingAttributeStr(getBindingAttribute()));
99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Visibility",  getVisibilityStr(getVisibility())            );
100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Shtab Index", getSectionIndex()                            );
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Value",       getValue()                                   );
102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Size",        getSize()                                    );
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef PRINT_LINT
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines// TODO: Horizontal type or vertical type can use option to decide.
106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#if 0
107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  using namespace term::color;
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  using namespace std;
109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  cout << setw(20) << getName() <<
111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(10) << getTypeStr(getType()) <<
112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(10) << getBindingAttributeStr(getBindingAttribute()) <<
113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(15) << getVisibilityStr(getVisibility()) <<
114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(10) << getSectionIndex() <<
115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(7) << getValue() <<
116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          setw(7) << getSize() <<
117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          endl;
118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesvoid *ELFSymbol_CRTP<Bitwidth>::getAddress(int machine, bool autoAlloc) const {
123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (my_addr != 0) {
124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return my_addr;
125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t idx = (size_t)getSectionIndex();
127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  switch (getType()) {
128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    default:
129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      break;
130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_OBJECT:
132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      switch (idx) {
133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        default:
134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          {
135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionHeaderTableTy const *header =
136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              owner->getSectionHeaderTable();
137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            unsigned section_type = (*header)[idx]->getType();
139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert((section_type == SHT_PROGBITS ||
141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                        section_type == SHT_NOBITS) &&
142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                       "STT_OBJECT with not BITS section.");
143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            if (section_type == SHT_NOBITS) {
145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              // FIXME(logan): This is a workaround for .lcomm directives
146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              // bug of LLVM ARM MC code generator.  Remove this when the
147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              // LLVM bug is fixed.
148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              size_t align = 16;
150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              my_addr = const_cast<ELFObjectTy *>(owner)->
152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                allocateSHNCommonData((size_t)getSize(), align);
153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              if (!my_addr) {
155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
156b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                abort();
157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              }
158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            } else {
159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              ELFSectionTy const *sec = owner->getSectionByIndex(idx);
160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              rsl_assert(sec != 0 && "STT_OBJECT with null section.");
161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
162b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              ELFSectionBitsTy const &st =
163b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                static_cast<ELFSectionBitsTy const &>(*sec);
164b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              my_addr =const_cast<unsigned char *>(&st[0] + (off_t)getValue());
165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            }
166b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          }
167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
168b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
169b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_COMMON:
170b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          {
171b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            if (!autoAlloc) {
172b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              return NULL;
173b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            }
174b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#if 0
175b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#if _POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600
176b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            if (posix_memalign(&my_addr,
177b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                               std::max((size_t)getValue(), sizeof(void*)),
178b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                               (size_t)getSize()) != 0) {
179b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              rsl_assert(0 && "posix_memalign failed.");
180b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            }
181b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#else
182b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            my_addr = memalign(std::max((size_t)getValue(), sizeof(void *)),
183b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                               (size_t)getSize());
184b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
185b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(my_addr != NULL && "memalign failed.");
186b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
187b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            if (my_addr) {
188b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              memset(my_addr, '\0', getSize());
189b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            }
190b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#else
191b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            size_t align = (size_t)getValue();
192b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            my_addr = const_cast<ELFObjectTy *>(owner)->
193b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                          allocateSHNCommonData((size_t)getSize(), align);
194b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            if (!my_addr) {
195b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              rsl_assert(0 && "Unable to allocate memory for SHN_COMMON.");
196b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              abort();
197b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            }
198b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
199b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          }
200b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
201b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
202b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_UNDEF:
203b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          if (machine == EM_MIPS && strcmp(getName(), "_gp_disp") == 0) // OK for MIPS
204b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            break;
205b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
206b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_ABS:
207b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_XINDEX:
208b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          rsl_assert(0 && "STT_OBJECT with special st_shndx.");
209b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
210b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
211b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      break;
212b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
213b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
214b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_FUNC:
215b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      switch (idx) {
216b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        default:
217b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          {
218b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef NDEBUG
219b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionHeaderTableTy const *header =
220b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              owner->getSectionHeaderTable();
221b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert((*header)[idx]->getType() == SHT_PROGBITS &&
222b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                   "STT_FUNC with not PROGBITS section.");
223b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
224b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
225b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(sec != 0 && "STT_FUNC with null section.");
226b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
227b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionProgBitsTy const &st =
228b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              static_cast<ELFSectionProgBitsTy const &>(*sec);
229b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
230b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          }
231b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
232b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
233b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_ABS:
234b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_COMMON:
235b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_UNDEF:
236b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_XINDEX:
237b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          rsl_assert(0 && "STT_FUNC with special st_shndx.");
238b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
239b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
240b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      break;
241b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
242b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
243b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_SECTION:
244b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      switch (idx) {
245b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        default:
246b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          {
247b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef NDEBUG
248b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionHeaderTableTy const *header =
249b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              owner->getSectionHeaderTable();
250b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
251b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                    (*header)[idx]->getType() == SHT_NOBITS) &&
252b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                   "STT_SECTION with not BITS section.");
253b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
254b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
255b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(sec != 0 && "STT_SECTION with null section.");
256b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
257b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionBitsTy const &st =
258b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              static_cast<ELFSectionBitsTy const &>(*sec);
259b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
260b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          }
261b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
262b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
263b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_ABS:
264b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_COMMON:
265b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_UNDEF:
266b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_XINDEX:
267b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          rsl_assert(0 && "STT_SECTION with special st_shndx.");
268b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
269b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
270b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      break;
271b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
272b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_NOTYPE:
273b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      switch (idx) {
274b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        default:
275b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          {
276b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef NDEBUG
277b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionHeaderTableTy const *header =
278b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              owner->getSectionHeaderTable();
279b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(((*header)[idx]->getType() == SHT_PROGBITS ||
280b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                    (*header)[idx]->getType() == SHT_NOBITS) &&
281b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines                   "STT_SECTION with not BITS section.");
282b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
283b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionTy const *sec = owner->getSectionByIndex(idx);
284b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            rsl_assert(sec != 0 && "STT_SECTION with null section.");
285b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
286b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            ELFSectionBitsTy const &st =
287b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines              static_cast<ELFSectionBitsTy const &>(*sec);
288b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines            my_addr = const_cast<unsigned char *>(&st[0] + (off_t)getValue());
289b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          }
290b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
291b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
292b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_ABS:
293b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_COMMON:
294b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_XINDEX:
295b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          rsl_assert(0 && "STT_SECTION with special st_shndx.");
296b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          break;
297b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        case SHN_UNDEF:
298b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          return 0;
299b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      }
300b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      break;
301b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      return 0;
302b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
303b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_COMMON:
304b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_FILE:
305b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_TLS:
306b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_LOOS:
307b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_HIOS:
308b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_LOPROC:
309b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    case STT_HIPROC:
310b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      rsl_assert(0 && "Not implement.");
311b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      return 0;
312b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
313b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  return my_addr;
314b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
315b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
316b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_SYMBOL_HXX
317