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:
ELFReloc_CRTP()39   ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { }
~ELFReloc_CRTP()40   ~ELFReloc_CRTP() { }
41 
42 public:
getIndex()43   size_t getIndex() const {
44     return index;
45   }
46 
getOffset()47   addr_t getOffset() const {
48     return r_offset;
49   }
50 
getAddend()51   addend_t getAddend() const {
52     return r_addend;
53   }
54 
isValid()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:
concrete()69   ELFRelocTy *concrete() {
70     return static_cast<ELFRelocTy *>(this);
71   }
72 
concrete()73   ELFRelocTy const *concrete() const {
74     return static_cast<ELFRelocTy const *>(this);
75   }
76 
77   template <typename Archiver>
serializeRel(Archiver & AR)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>
serializeRela(Archiver & AR)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:
ELFReloc()109   ELFReloc() {
110   }
111 
112 public:
getSymTabIndex()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 
getType()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:
ELFReloc()132   ELFReloc() {
133   }
134 
135 public:
getSymTabIndex()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 
getType()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