1b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines/*
2b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Copyright 2011, The Android Open Source Project
3b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
4b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Licensed under the Apache License, Version 2.0 (the "License");
5b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * you may not use this file except in compliance with the License.
6b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * You may obtain a copy of the License at
7b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
8b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *     http://www.apache.org/licenses/LICENSE-2.0
9b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines *
10b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * Unless required by applicable law or agreed to in writing, software
11b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * distributed under the License is distributed on an "AS IS" BASIS,
12b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * See the License for the specific language governing permissions and
14b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines * limitations under the License.
15b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines */
16b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
17b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#ifndef ELF_RELOC_H
18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_RELOC_H
19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "ELFTypes.h"
21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/rsl_assert.h"
22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/ADT/OwningPtr.h>
24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <string>
25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <stdint.h>
26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFReloc_CRTP {
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t index;
34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
35b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t    r_offset;
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  relinfo_t r_info;
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addend_t  r_addend;
38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprotected:
40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { }
41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ~ELFReloc_CRTP() { }
42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  size_t getIndex() const {
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return index;
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addr_t getOffset() const {
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return r_offset;
50b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  addend_t getAddend() const {
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return r_addend;
54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool isValid() const {
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // FIXME: Should check the correctness of the relocation entite.
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return true;
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static ELFRelocTy *readRel(Archiver &AR, size_t index);
63b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  static ELFRelocTy *readRela(Archiver &AR, size_t index);
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  void print(bool shouldPrintHeader = false) const;
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFRelocTy *concrete() {
71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return static_cast<ELFRelocTy *>(this);
72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFRelocTy const *concrete() const {
75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return static_cast<ELFRelocTy const *>(this);
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
78b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool serializeRel(Archiver &AR) {
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    rsl_assert(r_addend == 0 && "r_addend should be zero before serialization.");
81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.prologue(TypeTraits<ELFRelocRelTy>::size);
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & r_offset;
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & r_info;
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.epilogue(TypeTraits<ELFRelocRelTy>::size);
88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return AR;
89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  template <typename Archiver>
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  bool serializeRela(Archiver &AR) {
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.prologue(TypeTraits<ELFRelocRelaTy>::size);
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & r_offset;
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & r_info;
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR & r_addend;
98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    AR.epilogue(TypeTraits<ELFRelocRelaTy>::size);
100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return AR;
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <>
106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFReloc<32> : public ELFReloc_CRTP<32> {
107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  friend class ELFReloc_CRTP<32>;
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
109b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
110b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFReloc() {
111b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
112b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
113b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
114b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t getSymTabIndex() const {
115b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF32_R_SYM(i)  ((i)>>8)
116b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF32_R_SYM(this->r_info);
117b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF32_R_SYM
118b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
119b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
120b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  word_t getType() const {
121b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF32_R_TYPE(i)   ((unsigned char)(i))
122b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF32_R_TYPE(this->r_info);
123b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF32_R_TYPE
124b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
125b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
126b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
127b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
128b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <>
129b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesclass ELFReloc<64> : public ELFReloc_CRTP<64> {
130b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  friend class ELFReloc_CRTP<64>;
131b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
132b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesprivate:
133b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  ELFReloc() {
134b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
135b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
136b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinespublic:
137b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  xword_t getSymTabIndex() const {
138b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF64_R_SYM(i)    ((i)>>32)
139b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF64_R_SYM(this->r_info);
140b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF64_R_SYM
141b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
142b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
143b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  xword_t getType() const {
144b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF64_R_TYPE(i)   ((i)&0xffffffffL)
145b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return ELF64_R_TYPE(this->r_info);
146b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef ELF64_R_TYPE
147b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
148b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines};
149b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
150b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "impl/ELFReloc.hxx"
151b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
152b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_RELOC_H
153