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