ELFSymbol.h revision 9ed73923af9db7283a8c76b5dfa2dda5b732a852
1e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao/*
2e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Copyright 2011, The Android Open Source Project
3e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
4e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * you may not use this file except in compliance with the License.
6e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * You may obtain a copy of the License at
7e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
8e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
10e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Unless required by applicable law or agreed to in writing, software
11e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * See the License for the specific language governing permissions and
14e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * limitations under the License.
15e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao */
16e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao
17a3e9806ff102d256d38bd930d537c206adc8bb6cLogan Chien#ifndef ELF_SYMBOL_H
18a3e9806ff102d256d38bd930d537c206adc8bb6cLogan Chien#define ELF_SYMBOL_H
191e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include "ELFTypes.h"
21404833ada8caa7027105bd52bd36ab7822030369TDYa#include "ELF.h"
221e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
232956c0e06b1c51f521645a076802686976c4b2f6TDYa#include <llvm/ADT/OwningPtr.h>
242956c0e06b1c51f521645a076802686976c4b2f6TDYa
251e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include <string>
26937df4784a064c4f32b3354f76ef9c4361711173TDYa#include <algorithm>
271e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
280702eea209b208513ca9082a76abb929b287eceaYing Wang#ifdef MACOSX
290702eea209b208513ca9082a76abb929b287eceaYing Wang#include <malloc/malloc.h>
300702eea209b208513ca9082a76abb929b287eceaYing Wang#else
316a75cacd74aac486d2313f725555f323725cb1dbLogan Chien#include <malloc.h>
320702eea209b208513ca9082a76abb929b287eceaYing Wang#endif
331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include <stdint.h>
34921465005aca46a100d137c9608a0aedd846e290Logan Chien#include <stdlib.h>
351e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
36d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbolHelperMixin {
371e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
381e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getTypeStr(uint8_t);
391e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getBindingAttributeStr(uint8_t);
401e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getVisibilityStr(uint8_t);
411e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
421e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
43a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
44d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol_CRTP : private ELFSymbolHelperMixin {
451e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
461e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
471e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
491e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFObject<Bitwidth> const *owner;
501e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
511e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t index;
521e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
531e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t st_name;
541e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_info;
551e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_other;
561e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t st_shndx;
571e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t st_value;
589ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  symsize_t st_size;
591e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
60d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  mutable void *my_addr;
61d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
621e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
63d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol_CRTP() { my_addr = 0; }
6458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien
65d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ~ELFSymbol_CRTP() {
669f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#if 0
67d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    if (my_addr != 0 &&
68d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getType() == STT_OBJECT &&
69d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getSectionIndex() == SHN_COMMON) {
70d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      std::free(my_addr);
71d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    }
729f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#endif
73d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  }
741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t getIndex() const {
771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return index;
781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t getNameIndex() const {
811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_name;
821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
831e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  char const *getName() const;
851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa// I don't want to include elf.h in .h file, so define those macro by ourself.
871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_BIND(i)   ((i)>>4)
881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_TYPE(i)   ((i)&0xf)
891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getType() const {
911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_TYPE(st_info);
921e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
941e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getBindingAttribute() const {
951e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_BIND(st_info);
961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
971e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_BIND
981e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_TYPE
991e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_INFO
1001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1011e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_VISIBILITY(o) ((o)&0x3)
1021e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getVisibility() const {
1031e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_VISIBILITY(st_other);
1041e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1051e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_VISIBILITY
1061e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1071e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t getSectionIndex() const {
1081e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_shndx;
1091e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1101e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1111e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t getValue() const {
1121e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_value;
1131e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1141e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1159ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  symsize_t getSize() const {
1161e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_size;
1171e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1181e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1199ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh  void *getAddress(int machine, bool autoAlloc = true) const;
120d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
1215c543a0761c5a7f72565351bc16ec31d6f675602TDYa  void setAddress(void *addr) {
1225c543a0761c5a7f72565351bc16ec31d6f675602TDYa    my_addr = addr;
1235c543a0761c5a7f72565351bc16ec31d6f675602TDYa  }
1245c543a0761c5a7f72565351bc16ec31d6f675602TDYa
1251e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool isValid() const {
1261e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // FIXME: Should check the correctness of the section header.
1271e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return true;
1281e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1291e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
130388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien  bool isConcreteFunc() const {
131388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien    return getType() == STT_FUNC;
132388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien  }
133388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien
134e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien  bool isExternFunc() const {
135e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien    return getType() == STT_NOTYPE;
136e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien  }
137e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien
1381e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
13958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  static ELFSymbolTy *
1401e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
1411e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1421e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  void print(bool shouldPrintHeader = false) const;
1431e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1441e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
14558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSymbolTy *concrete() {
14658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFSymbolTy *>(this);
1471e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
14958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSymbolTy const *concrete() const {
15058611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFSymbolTy const *>(this);
1511e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1521e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1531e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1541e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
155d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<32> : public ELFSymbol_CRTP<32> {
156d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<32>;
1571e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1581e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
159d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
1601e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1611e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1621e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
1631e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
164d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
1651e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1661e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
1671e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
1681e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
1691e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
1701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
1711e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
1721e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
173d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
1741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
1751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
179d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<64> : public ELFSymbol_CRTP<64> {
180d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<64>;
1811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
183d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
1841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
1871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
188d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
1891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
1911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
1921e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
1931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
1941e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
1951e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
1961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
197d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
1981e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
1991e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
2001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
2011e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
2029f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "impl/ELFSymbol.hxx"
2031e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
204a3e9806ff102d256d38bd930d537c206adc8bb6cLogan Chien#endif // ELF_SYMBOL_H
205