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_SECTION_HEADER_TABLE_HXX 18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_SECTION_HEADER_TABLE_HXX 19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFHeader.h" 21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFObject.h" 22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFSectionHeader.h" 23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/rsl_assert.h" 25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFSectionHeaderTable<Bitwidth>::~ELFSectionHeaderTable() { 28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < table.size(); ++i) { 29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines delete table[i]; 30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <typename Archiver> 35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFSectionHeaderTable<Bitwidth> * 36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFSectionHeaderTable<Bitwidth>::read(Archiver &AR, ELFObjectTy *owner) { 37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!AR) { 38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Archiver is in bad state before calling read function. 39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Return NULL and do nothing. 40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Allocate a new section header table and assign the owner. 44d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines std::unique_ptr<ELFSectionHeaderTable> tab(new ELFSectionHeaderTable()); 45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Get ELF header 47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFHeaderTy const *header = owner->getHeader(); 48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines rsl_assert(header->getSectionHeaderEntrySize() == 50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines TypeTraits<ELFSectionHeaderTy>::size); 51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Seek to the address of section header 53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines AR.seek(header->getSectionHeaderTableOffset(), true); 54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < header->getSectionHeaderNum(); ++i) { 56d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines std::unique_ptr<ELFSectionHeaderTy> sh( 57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionHeaderTy::read(AR, owner, i)); 58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (!sh) { 60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Something wrong while reading the section header. 61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return 0; 62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 64d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines tab->table.push_back(sh.release()); 65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 67d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines return tab.release(); 68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline void ELFSectionHeaderTable<Bitwidth>::print() const { 72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines using namespace llvm; 73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out() << '\n' << fillformat('=', 79) << '\n'; 75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out().changeColor(raw_ostream::WHITE, true); 76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out() << "ELF Section Header Table" << '\n'; 77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out().resetColor(); 78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < table.size(); ++i) { 80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines (*this)[i]->print(); 81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines out() << fillformat('=', 79) << '\n'; 84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline void ELFSectionHeaderTable<Bitwidth>::buildNameMap() { 88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines for (size_t i = 0; i < table.size(); ++i) { 89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionHeaderTy *sh = table[i]; 90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if ( sh ) { 91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines name_map[sh->getName()] = sh; 92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFSectionHeader<Bitwidth> const * 98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFSectionHeaderTable<Bitwidth>::getByName(const std::string &name) const { 99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines typename llvm::StringMap<ELFSectionHeaderTy *>::const_iterator sh = 100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines name_map.find(name); 101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines if (sh == name_map.end()) { 102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Return SHN_UNDEF section header; 103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return table[0]; 104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines } 105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return sh->getValue(); 106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth> 109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFSectionHeader<Bitwidth> * 110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFSectionHeaderTable<Bitwidth>::getByName(const std::string &name) { 111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionHeaderTableTy const *const_this = this; 112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines ELFSectionHeaderTy const *shptr = const_this->getByName(name); 113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines // Const cast for the same API's const and non-const versions. 114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines return const_cast<ELFSectionHeaderTy *>(shptr); 115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines} 116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines 117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_SECTION_HEADER_TABLE_HXX 118