1e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao/*
2e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Copyright 2011, The Android Open Source Project
3e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
4e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * you may not use this file except in compliance with the License.
6e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * You may obtain a copy of the License at
7e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
8e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao *
10e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * Unless required by applicable law or agreed to in writing, software
11e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * See the License for the specific language governing permissions and
14e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao * limitations under the License.
15e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao */
16e2cdbc6710aa43475f17e73aba143ceb786e968cShih-wei Liao
176c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien#ifndef ELF_RELOC_H
186c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien#define ELF_RELOC_H
1903eafa401a9387395625023857981d4691ceea22TDYa
2003eafa401a9387395625023857981d4691ceea22TDYa#include "ELFTypes.h"
21c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa#include "utils/rsl_assert.h"
2203eafa401a9387395625023857981d4691ceea22TDYa
231944d79ae67fa5801d3baee09abcf51e9b22c08fTDYa#include <llvm/ADT/OwningPtr.h>
24355c46527467526e566944fa393896009bdd0136Logan Chien#include <string>
2503eafa401a9387395625023857981d4691ceea22TDYa#include <stdint.h>
2603eafa401a9387395625023857981d4691ceea22TDYa
27a9ab5889e842a49ff16d06594efe96b0210fe1f7Logan Chientemplate <unsigned Bitwidth>
286c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chienclass ELFReloc_CRTP {
2903eafa401a9387395625023857981d4691ceea22TDYapublic:
3003eafa401a9387395625023857981d4691ceea22TDYa  ELF_TYPE_INTRO_TO_TEMPLATE_SCOPE(Bitwidth);
3103eafa401a9387395625023857981d4691ceea22TDYa
3203eafa401a9387395625023857981d4691ceea22TDYaprotected:
3303eafa401a9387395625023857981d4691ceea22TDYa  size_t index;
34974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
35974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  addr_t    r_offset;
36974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  relinfo_t r_info;
37974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  addend_t  r_addend;
3803eafa401a9387395625023857981d4691ceea22TDYa
3903eafa401a9387395625023857981d4691ceea22TDYaprotected:
406c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  ELFReloc_CRTP() : index(0), r_offset(0), r_addend(0) { }
416c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  ~ELFReloc_CRTP() { }
4203eafa401a9387395625023857981d4691ceea22TDYa
4303eafa401a9387395625023857981d4691ceea22TDYapublic:
4403eafa401a9387395625023857981d4691ceea22TDYa  size_t getIndex() const {
4503eafa401a9387395625023857981d4691ceea22TDYa    return index;
4603eafa401a9387395625023857981d4691ceea22TDYa  }
4703eafa401a9387395625023857981d4691ceea22TDYa
4803eafa401a9387395625023857981d4691ceea22TDYa  addr_t getOffset() const {
49974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    return r_offset;
50974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  }
51974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
52974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  addend_t getAddend() const {
53974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    return r_addend;
5403eafa401a9387395625023857981d4691ceea22TDYa  }
5503eafa401a9387395625023857981d4691ceea22TDYa
5603eafa401a9387395625023857981d4691ceea22TDYa  bool isValid() const {
575961b6281295af6b8cca7f3fdf892864ed2318feLogan Chien    // FIXME: Should check the correctness of the relocation entite.
5803eafa401a9387395625023857981d4691ceea22TDYa    return true;
5903eafa401a9387395625023857981d4691ceea22TDYa  }
6003eafa401a9387395625023857981d4691ceea22TDYa
6103eafa401a9387395625023857981d4691ceea22TDYa  template <typename Archiver>
6258611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  static ELFRelocTy *readRel(Archiver &AR, size_t index);
63974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
64974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  template <typename Archiver>
6558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  static ELFRelocTy *readRela(Archiver &AR, size_t index);
6603eafa401a9387395625023857981d4691ceea22TDYa
6703eafa401a9387395625023857981d4691ceea22TDYa  void print(bool shouldPrintHeader = false) const;
6803eafa401a9387395625023857981d4691ceea22TDYa
6903eafa401a9387395625023857981d4691ceea22TDYaprivate:
7058611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFRelocTy *concrete() {
7158611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFRelocTy *>(this);
7203eafa401a9387395625023857981d4691ceea22TDYa  }
7303eafa401a9387395625023857981d4691ceea22TDYa
7458611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  ELFRelocTy const *concrete() const {
7558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    return static_cast<ELFRelocTy const *>(this);
7603eafa401a9387395625023857981d4691ceea22TDYa  }
77974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
78974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  template <typename Archiver>
79974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  bool serializeRel(Archiver &AR) {
80c40d8a8b26547ab9c51792d9d9b3aca13fb5cdf9TDYa    rsl_assert(r_addend == 0 && "r_addend should be zero before serialization.");
81974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
8258611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    AR.prologue(TypeTraits<ELFRelocRelTy>::size);
83974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
84974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    AR & r_offset;
85974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    AR & r_info;
86974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
8758611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    AR.epilogue(TypeTraits<ELFRelocRelTy>::size);
88974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    return AR;
89974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  }
90974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
91974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  template <typename Archiver>
92974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  bool serializeRela(Archiver &AR) {
9358611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    AR.prologue(TypeTraits<ELFRelocRelaTy>::size);
94974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
95974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    AR & r_offset;
96974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    AR & r_info;
97974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    AR & r_addend;
98974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
9958611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien    AR.epilogue(TypeTraits<ELFRelocRelaTy>::size);
100974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien    return AR;
101974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien  }
102974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chien
10303eafa401a9387395625023857981d4691ceea22TDYa};
10403eafa401a9387395625023857981d4691ceea22TDYa
10503eafa401a9387395625023857981d4691ceea22TDYatemplate <>
1066c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chienclass ELFReloc<32> : public ELFReloc_CRTP<32> {
1076c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  friend class ELFReloc_CRTP<32>;
10803eafa401a9387395625023857981d4691ceea22TDYa
109974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chienprivate:
1106c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  ELFReloc() {
11103eafa401a9387395625023857981d4691ceea22TDYa  }
11203eafa401a9387395625023857981d4691ceea22TDYa
1135fc55f722ac22b3022f6fc17c39a536267e89dfcTDYapublic:
1149ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  word_t getSymTabIndex() const {
115404833ada8caa7027105bd52bd36ab7822030369TDYa#define ELF32_R_SYM(i)  ((i)>>8)
11603eafa401a9387395625023857981d4691ceea22TDYa    return ELF32_R_SYM(this->r_info);
117404833ada8caa7027105bd52bd36ab7822030369TDYa#undef ELF32_R_SYM
11803eafa401a9387395625023857981d4691ceea22TDYa  }
11903eafa401a9387395625023857981d4691ceea22TDYa
1209ac06bd8363c8c7e4e612eb041e921dcd81cf9d7Logan Chien  word_t getType() const {
121404833ada8caa7027105bd52bd36ab7822030369TDYa#define ELF32_R_TYPE(i)   ((unsigned char)(i))
12203eafa401a9387395625023857981d4691ceea22TDYa    return ELF32_R_TYPE(this->r_info);
123404833ada8caa7027105bd52bd36ab7822030369TDYa#undef ELF32_R_TYPE
12403eafa401a9387395625023857981d4691ceea22TDYa  }
12503eafa401a9387395625023857981d4691ceea22TDYa
12603eafa401a9387395625023857981d4691ceea22TDYa};
12703eafa401a9387395625023857981d4691ceea22TDYa
12803eafa401a9387395625023857981d4691ceea22TDYatemplate <>
1296c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chienclass ELFReloc<64> : public ELFReloc_CRTP<64> {
1306c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  friend class ELFReloc_CRTP<64>;
13103eafa401a9387395625023857981d4691ceea22TDYa
132974c82871ee2205c0f7728cc43a5ff02487a50e0Logan Chienprivate:
1336c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien  ELFReloc() {
13403eafa401a9387395625023857981d4691ceea22TDYa  }
13503eafa401a9387395625023857981d4691ceea22TDYa
1365fc55f722ac22b3022f6fc17c39a536267e89dfcTDYapublic:
13703eafa401a9387395625023857981d4691ceea22TDYa  xword_t getSymTabIndex() const {
138404833ada8caa7027105bd52bd36ab7822030369TDYa#define ELF64_R_SYM(i)    ((i)>>32)
13903eafa401a9387395625023857981d4691ceea22TDYa    return ELF64_R_SYM(this->r_info);
140404833ada8caa7027105bd52bd36ab7822030369TDYa#undef ELF64_R_SYM
14103eafa401a9387395625023857981d4691ceea22TDYa  }
14203eafa401a9387395625023857981d4691ceea22TDYa
14303eafa401a9387395625023857981d4691ceea22TDYa  xword_t getType() const {
144404833ada8caa7027105bd52bd36ab7822030369TDYa#define ELF64_R_TYPE(i)   ((i)&0xffffffffL)
14503eafa401a9387395625023857981d4691ceea22TDYa    return ELF64_R_TYPE(this->r_info);
146404833ada8caa7027105bd52bd36ab7822030369TDYa#undef ELF64_R_TYPE
14703eafa401a9387395625023857981d4691ceea22TDYa  }
14803eafa401a9387395625023857981d4691ceea22TDYa};
14903eafa401a9387395625023857981d4691ceea22TDYa
150355c46527467526e566944fa393896009bdd0136Logan Chien#include "impl/ELFReloc.hxx"
15103eafa401a9387395625023857981d4691ceea22TDYa
1526c3b04f735d1b0ba9d1e569e0cfd36aab821e11bLogan Chien#endif // ELF_RELOC_H
153