| /* |
| * Copyright 2011, The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #ifndef ELF_RELOC_H |
| #define ELF_RELOC_H |
| |
| #include "ELFTypes.h" |
| #include "utils/rsl_assert.h" |
| |
| #include <llvm/ADT/OwningPtr.h> |
| #include <string> |
| #include <stdint.h> |
| |
| template <unsigned Bitwidth> |
| class ELFReloc_CRTP { |
| public: |
| ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth); |
| |
| protected: |
| size_t index; |
| |
| addr_t r_offset; |
| relinfo_t r_info; |
| addend_t r_addend; |
| |
| protected: |
| ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { } |
| ~ELFReloc_CRTP() { } |
| |
| public: |
| size_t getIndex() const { |
| return index; |
| } |
| |
| addr_t getOffset() const { |
| return r_offset; |
| } |
| |
| addend_t getAddend() const { |
| return r_addend; |
| } |
| |
| bool isValid() const { |
| // FIXME: Should check the correctness of the relocation entite. |
| return true; |
| } |
| |
| template <typename Archiver> |
| static ELFRelocTy *readRel(Archiver &AR, size_t index); |
| |
| template <typename Archiver> |
| static ELFRelocTy *readRela(Archiver &AR, size_t index); |
| |
| void print(bool shouldPrintHeader = false) const; |
| |
| private: |
| ELFRelocTy *concrete() { |
| return static_cast<ELFRelocTy *>(this); |
| } |
| |
| ELFRelocTy const *concrete() const { |
| return static_cast<ELFRelocTy const *>(this); |
| } |
| |
| template <typename Archiver> |
| bool serializeRel(Archiver &AR) { |
| rsl_assert(r_addend == 0 && "r_addend should be zero before serialization."); |
| |
| AR.prologue(TypeTraits<ELFRelocRelTy>::size); |
| |
| AR & r_offset; |
| AR & r_info; |
| |
| AR.epilogue(TypeTraits<ELFRelocRelTy>::size); |
| return AR; |
| } |
| |
| template <typename Archiver> |
| bool serializeRela(Archiver &AR) { |
| AR.prologue(TypeTraits<ELFRelocRelaTy>::size); |
| |
| AR & r_offset; |
| AR & r_info; |
| AR & r_addend; |
| |
| AR.epilogue(TypeTraits<ELFRelocRelaTy>::size); |
| return AR; |
| } |
| |
| }; |
| |
| template <> |
| class ELFReloc<32> : public ELFReloc_CRTP<32> { |
| friend class ELFReloc_CRTP<32>; |
| |
| private: |
| ELFReloc() { |
| } |
| |
| public: |
| word_t getSymTabIndex() const { |
| #define ELF32_R_SYM(i) ((i)>>8) |
| return ELF32_R_SYM(this->r_info); |
| #undef ELF32_R_SYM |
| } |
| |
| word_t getType() const { |
| #define ELF32_R_TYPE(i) ((unsigned char)(i)) |
| return ELF32_R_TYPE(this->r_info); |
| #undef ELF32_R_TYPE |
| } |
| |
| }; |
| |
| template <> |
| class ELFReloc<64> : public ELFReloc_CRTP<64> { |
| friend class ELFReloc_CRTP<64>; |
| |
| private: |
| ELFReloc() { |
| } |
| |
| public: |
| xword_t getSymTabIndex() const { |
| #define ELF64_R_SYM(i) ((i)>>32) |
| return ELF64_R_SYM(this->r_info); |
| #undef ELF64_R_SYM |
| } |
| |
| xword_t getType() const { |
| #define ELF64_R_TYPE(i) ((i)&0xffffffffL) |
| return ELF64_R_TYPE(this->r_info); |
| #undef ELF64_R_TYPE |
| } |
| }; |
| |
| #include "impl/ELFReloc.hxx" |
| |
| #endif // ELF_RELOC_H |