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
281e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#include <stdint.h>
29921465005aca46a100d137c9608a0aedd846e290Logan Chien#include <stdlib.h>
301e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
31d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbolHelperMixin {
321e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getTypeStr(uint8_t);
341e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getBindingAttributeStr(uint8_t);
351e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  static char const *getVisibilityStr(uint8_t);
361e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
371e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
38a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
39d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol_CRTP : private ELFSymbolHelperMixin {
401e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
411e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
421e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
431e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
441e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  ELFObject<Bitwidth> const *owner;
451e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
461e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t index;
471e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t st_name;
491e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_info;
501e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t st_other;
511e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t st_shndx;
521e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t st_value;
539ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  symsize_t st_size;
541e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
55d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  mutable void *my_addr;
56d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
571e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprotected:
58d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol_CRTP() { my_addr = 0; }
5958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien
60d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ~ELFSymbol_CRTP() {
619f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#if 0
62d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    if (my_addr != 0 &&
63d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getType() == STT_OBJECT &&
64d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa        getSectionIndex() == SHN_COMMON) {
65d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa      std::free(my_addr);
66d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa    }
679f64da291148a9c09bef5d062e9047bff64f56b9Logan Chien#endif
68d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa  }
691e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYapublic:
711e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  size_t getIndex() const {
721e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return index;
731e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
741e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
751e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  word_t getNameIndex() const {
761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_name;
771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
781e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  char const *getName() const;
801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa// I don't want to include elf.h in .h file, so define those macro by ourself.
821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_BIND(i)   ((i)>>4)
831e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_TYPE(i)   ((i)&0xf)
841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_INFO(b,t) (((b)<<4)+((t)&0xf))
851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getType() const {
861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_TYPE(st_info);
871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getBindingAttribute() const {
901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_BIND(st_info);
911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
921e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_BIND
931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_TYPE
941e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_INFO
951e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#define ELF_ST_VISIBILITY(o) ((o)&0x3)
971e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  byte_t getVisibility() const {
981e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return ELF_ST_VISIBILITY(st_other);
991e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1001e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa#undef ELF_ST_VISIBILITY
1011e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1021e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  half_t getSectionIndex() const {
1031e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_shndx;
1041e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1051e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1061e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  addr_t getValue() const {
1071e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_value;
1081e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1091e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1109ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  symsize_t getSize() const {
1111e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return st_size;
1121e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1131e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1149ed73923af9db7283a8c76b5dfa2dda5b732a852Andrew Hsieh  void *getAddress(int machine, bool autoAlloc = true) const;
115d91d1813cc1b99b171f16dc0f7ec4c58b7fc9cfeTDYa
1165c543a0761c5a7f72565351bc16ec31d6f675602TDYa  void setAddress(void *addr) {
1175c543a0761c5a7f72565351bc16ec31d6f675602TDYa    my_addr = addr;
1185c543a0761c5a7f72565351bc16ec31d6f675602TDYa  }
1195c543a0761c5a7f72565351bc16ec31d6f675602TDYa
1201e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool isValid() const {
1211e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    // FIXME: Should check the correctness of the section header.
1221e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return true;
1231e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1241e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
125388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien  bool isConcreteFunc() const {
126388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien    return getType() == STT_FUNC;
127388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien  }
128388f443ba0c474ffcc2e06f8d2a668c4488c3c1bLogan Chien
129e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien  bool isExternFunc() const {
130e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien    return getType() == STT_NOTYPE;
131e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien  }
132e586f183e46f921301281352a87f67dbdc1a43b6Logan Chien
1331e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
13458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  static ELFSymbolTy *
1351e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  read(Archiver &AR, ELFObject<Bitwidth> const *owner, size_t index = 0);
1361e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1371e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  void print(bool shouldPrintHeader = false) const;
1381e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1391e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
14058611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSymbolTy *concrete() {
14158611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFSymbolTy *>(this);
1421e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1431e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
14458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFSymbolTy const *concrete() const {
14558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFSymbolTy const *>(this);
1461e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1471e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1481e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1491e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
150d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<32> : public ELFSymbol_CRTP<32> {
151d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<32>;
1521e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1531e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
154d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
1551e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1561e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1571e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
1581e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
159d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
1601e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1611e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
1621e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
1631e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
1641e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
1651e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
1661e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
1671e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
168d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
1691e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
1701e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1711e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1721e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1731e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYatemplate <>
174d90e4881f16d40cd045bbe094f073353328d5a09Logan Chienclass ELFSymbol<64> : public ELFSymbol_CRTP<64> {
175d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  friend class ELFSymbol_CRTP<64>;
1761e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1771e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYaprivate:
178d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien  ELFSymbol() {
1791e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1801e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1811e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  template <typename Archiver>
1821e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  bool serialize(Archiver &AR) {
183d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.prologue(TypeTraits<ELFSymbol>::size);
1841e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1851e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_name;
1861e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_info;
1871e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_other;
1881e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_shndx;
1891e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_value;
1901e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    AR & st_size;
1911e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
192d90e4881f16d40cd045bbe094f073353328d5a09Logan Chien    AR.epilogue(TypeTraits<ELFSymbol>::size);
1931e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa    return AR;
1941e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa  }
1951e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa};
1961e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
1979f3703c8165b74517567e0d3a7a4f71ae8337c72Logan Chien#include "impl/ELFSymbol.hxx"
1981e278e29f1ce0a00a4626cb3c839ad37e46abcdfTDYa
199a3e9806ff102d256d38bd930d537c206adc8bb6cLogan Chien#endif // ELF_SYMBOL_H
200