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