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_H
18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_SYMBOL_H
19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFTypes.h"
21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELF.h"
22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/ADT/OwningPtr.h>
24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <string>
26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <algorithm>
27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdint.h>
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdlib.h>
30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFSymbolHelperMixin {
32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getTypeStr(uint8_t);
34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getBindingAttributeStr(uint8_t);
35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static char const *getVisibilityStr(uint8_t);
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFSymbol_CRTP : private ELFSymbolHelperMixin {
40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFObject<Bitwidth> const *owner;
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t index;
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t st_name;
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t st_info;
50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t st_other;
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t st_shndx;
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t st_value;
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  symsize_t st_size;
54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  mutable void *my_addr;
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbol_CRTP() { my_addr = 0; }
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ~ELFSymbol_CRTP() {
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#if 0
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    if (my_addr != 0 &&
63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        getType() == STT_OBJECT &&
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines        getSectionIndex() == SHN_COMMON) {
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines      std::free(my_addr);
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    }
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t getIndex() const {
72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return index;
73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t getNameIndex() const {
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return st_name;
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  char const *getName() const;
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines// I don't want to include elf.h in .h file, so define those macro by ourself.
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_ST_BIND(i)   ((i)>>4)
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_ST_TYPE(i)   ((i)&0xf)
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getType() const {
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF_ST_TYPE(st_info);
87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getBindingAttribute() const {
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF_ST_BIND(st_info);
91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF_ST_BIND
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF_ST_TYPE
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF_ST_INFO
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_ST_VISIBILITY(o) ((o)&0x3)
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  byte_t getVisibility() const {
98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF_ST_VISIBILITY(st_other);
99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF_ST_VISIBILITY
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  half_t getSectionIndex() const {
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return st_shndx;
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t getValue() const {
107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return st_value;
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  symsize_t getSize() const {
111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return st_size;
112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  void *getAddress(int machine, bool autoAlloc = true) const;
115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  void setAddress(void *addr) {
117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    my_addr = addr;
118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValid() const {
121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // FIXME: Should check the correctness of the section header.
122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return true;
123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isConcreteFunc() const {
126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return getType() == STT_FUNC;
127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isExternFunc() const {
130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return getType() == STT_NOTYPE;
131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static ELFSymbolTy *
135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  void print(bool shouldPrintHeader = false) const;
138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbolTy *concrete() {
141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return static_cast<ELFSymbolTy *>(this);
142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbolTy const *concrete() const {
145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return static_cast<ELFSymbolTy const *>(this);
146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <>
150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFSymbol<32> : public ELFSymbol_CRTP<32> {
151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  friend class ELFSymbol_CRTP<32>;
152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
153b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
154b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbol() {
155b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
156b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
157b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
158b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool serialize(Archiver &AR) {
159b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.prologue(TypeTraits<ELFSymbol>::size);
160b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
161b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_name;
162b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_value;
163b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_size;
164b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_info;
165b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_other;
166b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_shndx;
167b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
168b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.epilogue(TypeTraits<ELFSymbol>::size);
169b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return AR;
170b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
171b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
172b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
173b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <>
174b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFSymbol<64> : public ELFSymbol_CRTP<64> {
175b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  friend class ELFSymbol_CRTP<64>;
176b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
177b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
178b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFSymbol() {
179b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
180b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
181b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
182b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool serialize(Archiver &AR) {
183b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.prologue(TypeTraits<ELFSymbol>::size);
184b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
185b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_name;
186b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_info;
187b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_other;
188b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_shndx;
189b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_value;
190b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & st_size;
191b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
192b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.epilogue(TypeTraits<ELFSymbol>::size);
193b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return AR;
194b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
195b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
196b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
197b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "impl/ELFSymbol.hxx"
198b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
199b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_SYMBOL_H
200