1 /* 2 * Copyright 2011, The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef ELF_OBJECT_H 18 #define ELF_OBJECT_H 19 20 #include "ELFTypes.h" 21 #include "MemChunk.h" 22 23 #include "utils/rsl_assert.h" 24 25 #include <llvm/ADT/OwningPtr.h> 26 27 #include <string> 28 #include <vector> 29 30 template <unsigned Bitwidth> 31 class ELFObject { 32 public: 33 ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); 34 35 private: 36 llvm::OwningPtr<ELFHeaderTy> header; 37 llvm::OwningPtr<ELFSectionHeaderTableTy> shtab; 38 std::vector<ELFSectionTy *> stab; 39 40 MemChunk SHNCommonData; 41 unsigned char *SHNCommonDataPtr; 42 size_t SHNCommonDataFreeSize; 43 44 bool missingSymbols; 45 46 // TODO: Need refactor! initSHNCommonDataSize(size_t SHNCommonDataSize)47 bool initSHNCommonDataSize(size_t SHNCommonDataSize) { 48 rsl_assert(!SHNCommonDataPtr && "Can't init twice."); 49 if (!SHNCommonData.allocate(SHNCommonDataSize)) { 50 return false; 51 } 52 53 SHNCommonDataPtr = SHNCommonData.getBuffer(); 54 SHNCommonDataFreeSize = SHNCommonDataSize; 55 return true; 56 } 57 58 private: ELFObject()59 ELFObject() : SHNCommonDataPtr(NULL), missingSymbols(false) { } 60 61 public: 62 template <typename Archiver> 63 static ELFObject *read(Archiver &AR); 64 getHeader()65 ELFHeaderTy const *getHeader() const { 66 return header.get(); 67 } 68 getSectionHeaderTable()69 ELFSectionHeaderTableTy const *getSectionHeaderTable() const { 70 return shtab.get(); 71 } 72 73 char const *getSectionName(size_t i) const; 74 ELFSectionTy const *getSectionByIndex(size_t i) const; 75 ELFSectionTy *getSectionByIndex(size_t i); 76 ELFSectionTy const *getSectionByName(std::string const &str) const; 77 ELFSectionTy *getSectionByName(std::string const &str); 78 getMissingSymbols()79 inline bool getMissingSymbols() const { 80 return missingSymbols; 81 } 82 83 void *allocateSHNCommonData(size_t size, size_t align = 1) { 84 rsl_assert(size > 0 && align != 0); 85 86 rsl_assert(SHNCommonDataPtr && "Must init common data size before use!"); 87 88 // Ensure alignment 89 size_t rem = ((uintptr_t)SHNCommonDataPtr) % align; 90 if (rem != 0) { 91 SHNCommonDataPtr += align - rem; 92 SHNCommonDataFreeSize -= align - rem; 93 } 94 95 // Ensure the free size is sufficient 96 if (SHNCommonDataFreeSize < size) { 97 return NULL; 98 } 99 100 // Allcoate 101 void *result = SHNCommonDataPtr; 102 SHNCommonDataPtr += size; 103 SHNCommonDataFreeSize -= size; 104 105 return result; 106 } 107 108 void relocate(void *(*find_sym)(void *context, char const *name), 109 void *context); 110 111 void print() const; 112 ~ELFObject()113 ~ELFObject() { 114 for (size_t i = 0; i < stab.size(); ++i) { 115 // Delete will check the pointer is nullptr or not by himself. 116 delete stab[i]; 117 } 118 } 119 120 private: 121 void relocateARM(void *(*find_sym)(void *context, char const *name), 122 void *context, 123 ELFSectionRelTableTy *reltab, 124 ELFSectionProgBitsTy *text); 125 126 void relocateX86_32(void *(*find_sym)(void *context, char const *name), 127 void *context, 128 ELFSectionRelTableTy *reltab, 129 ELFSectionProgBitsTy *text); 130 131 void relocateX86_64(void *(*find_sym)(void *context, char const *name), 132 void *context, 133 ELFSectionRelTableTy *reltab, 134 ELFSectionProgBitsTy *text); 135 136 void relocateMIPS(void *(*find_sym)(void *context, char const *name), 137 void *context, 138 ELFSectionRelTableTy *reltab, 139 ELFSectionProgBitsTy *text); 140 }; 141 142 #include "impl/ELFObject.hxx" 143 144 #endif // ELF_OBJECT_H 145