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_RELOC_H 18 #define ELF_RELOC_H 19 20 #include "ELFTypes.h" 21 #include "utils/rsl_assert.h" 22 23 #include <string> 24 #include <stdint.h> 25 26 template <unsigned Bitwidth> 27 class ELFReloc_CRTP { 28 public: 29 ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); 30 31 protected: 32 size_t index; 33 34 addr_t r_offset; 35 relinfo_t r_info; 36 addend_t r_addend; 37 38 protected: 39 ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { } 40 ~ELFReloc_CRTP() { } 41 42 public: 43 size_t getIndex() const { 44 return index; 45 } 46 47 addr_t getOffset() const { 48 return r_offset; 49 } 50 51 addend_t getAddend() const { 52 return r_addend; 53 } 54 55 bool isValid() const { 56 // FIXME: Should check the correctness of the relocation entite. 57 return true; 58 } 59 60 template <typename Archiver> 61 static ELFRelocTy *readRel(Archiver &AR, size_t index); 62 63 template <typename Archiver> 64 static ELFRelocTy *readRela(Archiver &AR, size_t index); 65 66 void print(bool shouldPrintHeader = false) const; 67 68 private: 69 ELFRelocTy *concrete() { 70 return static_cast<ELFRelocTy *>(this); 71 } 72 73 ELFRelocTy const *concrete() const { 74 return static_cast<ELFRelocTy const *>(this); 75 } 76 77 template <typename Archiver> 78 bool serializeRel(Archiver &AR) { 79 rsl_assert(r_addend == 0 && "r_addend should be zero before serialization."); 80 81 AR.prologue(TypeTraits<ELFRelocRelTy>::size); 82 83 AR & r_offset; 84 AR & r_info; 85 86 AR.epilogue(TypeTraits<ELFRelocRelTy>::size); 87 return AR; 88 } 89 90 template <typename Archiver> 91 bool serializeRela(Archiver &AR) { 92 AR.prologue(TypeTraits<ELFRelocRelaTy>::size); 93 94 AR & r_offset; 95 AR & r_info; 96 AR & r_addend; 97 98 AR.epilogue(TypeTraits<ELFRelocRelaTy>::size); 99 return AR; 100 } 101 102 }; 103 104 template <> 105 class ELFReloc<32> : public ELFReloc_CRTP<32> { 106 friend class ELFReloc_CRTP<32>; 107 108 private: 109 ELFReloc() { 110 } 111 112 public: 113 word_t getSymTabIndex() const { 114 #define ELF32_R_SYM(i) ((i)>>8) 115 return ELF32_R_SYM(this->r_info); 116 #undef ELF32_R_SYM 117 } 118 119 word_t getType() const { 120 #define ELF32_R_TYPE(i) ((unsigned char)(i)) 121 return ELF32_R_TYPE(this->r_info); 122 #undef ELF32_R_TYPE 123 } 124 125 }; 126 127 template <> 128 class ELFReloc<64> : public ELFReloc_CRTP<64> { 129 friend class ELFReloc_CRTP<64>; 130 131 private: 132 ELFReloc() { 133 } 134 135 public: 136 xword_t getSymTabIndex() const { 137 #define ELF64_R_SYM(i) ((i)>>32) 138 return ELF64_R_SYM(this->r_info); 139 #undef ELF64_R_SYM 140 } 141 142 xword_t getType() const { 143 #define ELF64_R_TYPE(i) ((i)&0xffffffffL) 144 return ELF64_R_TYPE(this->r_info); 145 #undef ELF64_R_TYPE 146 } 147 }; 148 149 #include "impl/ELFReloc.hxx" 150 151 #endif // ELF_RELOC_H 152