ELFReloc.h revision b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298
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 27template <unsigned Bitwidth> 28class ELFReloc_CRTP { 29public: 30 ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); 31 32protected: 33 size_t index; 34 35 addr_t r_offset; 36 relinfo_t r_info; 37 addend_t r_addend; 38 39protected: 40 ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { } 41 ~ELFReloc_CRTP() { } 42 43public: 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 69private: 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 105template <> 106class ELFReloc<32> : public ELFReloc_CRTP<32> { 107 friend class ELFReloc_CRTP<32>; 108 109private: 110 ELFReloc() { 111 } 112 113public: 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 128template <> 129class ELFReloc<64> : public ELFReloc_CRTP<64> { 130 friend class ELFReloc_CRTP<64>; 131 132private: 133 ELFReloc() { 134 } 135 136public: 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