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
17b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien#ifndef ELF_SECTION_REL_TABLE_HXX
18b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien#define ELF_SECTION_REL_TABLE_HXX
19b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
207cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien#include "ELF.h"
217cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien#include "ELFHeader.h"
227cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien#include "ELFObject.h"
23b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien#include "ELFReloc.h"
247cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien#include "ELFTypes.h"
257cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
267cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien#include <set>
27b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
28b27ccae0d5900e923c13936274369f754d8e28e9Logan Chientemplate <unsigned Bitwidth>
29b27ccae0d5900e923c13936274369f754d8e28e9Logan ChienELFSectionRelTable<Bitwidth>::~ELFSectionRelTable() {
30b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  using namespace std;
3168aab0239525454d17465d927028cdbd2bfd2969Logan Chien  for (size_t i = 0; i < table.size(); ++i) {
3268aab0239525454d17465d927028cdbd2bfd2969Logan Chien    delete table[i];
33b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  }
34b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien}
35b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
36b27ccae0d5900e923c13936274369f754d8e28e9Logan Chientemplate <unsigned Bitwidth>
37b27ccae0d5900e923c13936274369f754d8e28e9Logan Chienvoid ELFSectionRelTable<Bitwidth>::print() const {
38b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  using namespace llvm;
39b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
40b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  out() << '\n' << fillformat('=', 79) << '\n';
41b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  out().changeColor(raw_ostream::WHITE, true);
42b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  out() << "Relocation Table" << '\n';
43b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  out().resetColor();
44b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
45b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  for (size_t i = 0; i < this->size(); ++i) {
46b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    (*this)[i]->print();
47b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  }
48b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
49b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  out() << fillformat('=', 79) << '\n';
50b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien}
51b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
52b27ccae0d5900e923c13936274369f754d8e28e9Logan Chientemplate <unsigned Bitwidth>
53b27ccae0d5900e923c13936274369f754d8e28e9Logan Chientemplate <typename Archiver>
54b27ccae0d5900e923c13936274369f754d8e28e9Logan ChienELFSectionRelTable<Bitwidth> *
55b27ccae0d5900e923c13936274369f754d8e28e9Logan ChienELFSectionRelTable<Bitwidth>::read(Archiver &AR,
5658611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien                                   ELFSectionHeaderTy const *sh) {
57b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
58c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa  rsl_assert(sh->getType() == SHT_REL || sh->getType() == SHT_RELA);
59b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
60b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  llvm::OwningPtr<ELFSectionRelTable> rt(new ELFSectionRelTable());
61b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
62b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  // Seek to the start of the table
63b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  AR.seek(sh->getOffset(), true);
64b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
65b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  // Count the relocation entries
66b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  size_t size = sh->getSize() / sh->getEntrySize();
67b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
68b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  // Read every relocation entries
69b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  if (sh->getType() == SHT_REL) {
70c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa    rsl_assert(sh->getEntrySize() == TypeTraits<ELFRelocRelTy>::size);
71b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    for (size_t i = 0; i < size; ++i) {
7258611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien      rt->table.push_back(ELFRelocTy::readRel(AR, i));
73b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    }
74b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
75b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  } else {
76c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa    rsl_assert(sh->getEntrySize() == TypeTraits<ELFRelocRelaTy>::size);
77b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    for (size_t i = 0; i < size; ++i) {
7858611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien      rt->table.push_back(ELFRelocTy::readRela(AR, i));
79b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    }
80b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  }
81b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
82b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  if (!AR) {
83b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    // Unable to read the table.
84b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien    return 0;
85b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  }
86b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
87b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien  return rt.take();
88b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien}
89b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien
907cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chientemplate <unsigned Bitwidth>
917cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chiensize_t ELFSectionRelTable<Bitwidth>::
927cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan ChiengetMaxNumStubs(ELFObjectTy const *obj) const {
937cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  switch (obj->getHeader()->getMachine()) {
947cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  case EM_ARM:
957cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien    {
960a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu      std::set<uint32_t> sym_index_set;
977cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
987cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien      for (size_t i = 0; i < size(); ++i) {
997cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien        ELFRelocTy *rel = table[i];
1007cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
1012a7f249060179fdcb49f240bdf349c4e7b896084Shih-wei Liao        if (rel->getType() == R_ARM_CALL ||
1022a7f249060179fdcb49f240bdf349c4e7b896084Shih-wei Liao            rel->getType() == R_ARM_THM_CALL) {
1037cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien          sym_index_set.insert(rel->getSymTabIndex());
1047cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien        }
1057cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien      }
1067cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
1077cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien      return sym_index_set.size();
1087cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien    }
1097cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
1100a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu  case EM_MIPS:
1110a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu    {
1120a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu      std::set<uint32_t> sym_index_set;
1130a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu
1140a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu      for (size_t i = 0; i < size(); ++i) {
1150a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu        ELFRelocTy *rel = table[i];
1160a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu
1170a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu        if (rel->getType() == R_MIPS_26) {
1180a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu          sym_index_set.insert(rel->getSymTabIndex());
1190a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu        }
1200a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu      }
1210a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu
1220a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu      return sym_index_set.size();
1230a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu    }
1240a2be45c942a83bb70a7cf1b7355db73cd30f9b9Chao-ying Fu
1257cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  case EM_386:
1267cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  case EM_X86_64:
1277cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien    return 0;
1287cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
1297cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  default:
1307cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien    rsl_assert(0 && "Only support ARM, MIPS, X86, and X86_64 relocation.");
1317cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien    return 0;
1327cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien  }
1337cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien}
1347cea0a041b87afe2c5ad5f26e6a89494d0819bd1Logan Chien
135b27ccae0d5900e923c13936274369f754d8e28e9Logan Chien#endif // ELF_SECTION_REL_TABLE_HXX
136