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 <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