Home | History | Annotate | Download | only in include
      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