1ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao/*
2ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Copyright 2011, The Android Open Source Project
3ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
4ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
5ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * you may not use this file except in compliance with the License.
6ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * You may obtain a copy of the License at
7ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
8ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
9ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao *
10ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * Unless required by applicable law or agreed to in writing, software
11ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
12ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * See the License for the specific language governing permissions and
14ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao * limitations under the License.
15ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao */
16ee6cdb95525abc8c7766798148302306a100b774Shih-wei Liao
17355c46527467526e566944fa393896009bdd0136Logan Chien#ifndef ELF_RELOC_HXX
18355c46527467526e566944fa393896009bdd0136Logan Chien#define ELF_RELOC_HXX
19355c46527467526e566944fa393896009bdd0136Logan Chien
20355c46527467526e566944fa393896009bdd0136Logan Chien#include "utils/raw_ostream.h"
21355c46527467526e566944fa393896009bdd0136Logan Chien
22355c46527467526e566944fa393896009bdd0136Logan Chien#include <llvm/Support/Format.h>
23355c46527467526e566944fa393896009bdd0136Logan Chien#include <llvm/Support/raw_ostream.h>
24355c46527467526e566944fa393896009bdd0136Logan Chien
25355c46527467526e566944fa393896009bdd0136Logan Chientemplate <unsigned Bitwidth>
26355c46527467526e566944fa393896009bdd0136Logan Chientemplate <typename Archiver>
27355c46527467526e566944fa393896009bdd0136Logan Chieninline ELFReloc<Bitwidth> *
28355c46527467526e566944fa393896009bdd0136Logan ChienELFReloc_CRTP<Bitwidth>::readRela(Archiver &AR, size_t index) {
29355c46527467526e566944fa393896009bdd0136Logan Chien  if (!AR) {
30355c46527467526e566944fa393896009bdd0136Logan Chien    // Archiver is in bad state before calling read function.
31355c46527467526e566944fa393896009bdd0136Logan Chien    // Return NULL and do nothing.
32355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
33355c46527467526e566944fa393896009bdd0136Logan Chien  }
34355c46527467526e566944fa393896009bdd0136Logan Chien
3558611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  llvm::OwningPtr<ELFRelocTy> sh(new ELFRelocTy());
36355c46527467526e566944fa393896009bdd0136Logan Chien
37355c46527467526e566944fa393896009bdd0136Logan Chien  if (!sh->serializeRela(AR)) {
38355c46527467526e566944fa393896009bdd0136Logan Chien    // Unable to read the structure.  Return NULL.
39355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
40355c46527467526e566944fa393896009bdd0136Logan Chien  }
41355c46527467526e566944fa393896009bdd0136Logan Chien
42355c46527467526e566944fa393896009bdd0136Logan Chien  if (!sh->isValid()) {
43355c46527467526e566944fa393896009bdd0136Logan Chien    // Rel read from archiver is not valid.  Return NULL.
44355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
45355c46527467526e566944fa393896009bdd0136Logan Chien  }
46355c46527467526e566944fa393896009bdd0136Logan Chien
47355c46527467526e566944fa393896009bdd0136Logan Chien  // Set the section header index
48355c46527467526e566944fa393896009bdd0136Logan Chien  sh->index = index;
49355c46527467526e566944fa393896009bdd0136Logan Chien
50355c46527467526e566944fa393896009bdd0136Logan Chien  return sh.take();
51355c46527467526e566944fa393896009bdd0136Logan Chien}
52355c46527467526e566944fa393896009bdd0136Logan Chien
53355c46527467526e566944fa393896009bdd0136Logan Chientemplate <unsigned Bitwidth>
54355c46527467526e566944fa393896009bdd0136Logan Chientemplate <typename Archiver>
55355c46527467526e566944fa393896009bdd0136Logan Chieninline ELFReloc<Bitwidth> *
56355c46527467526e566944fa393896009bdd0136Logan ChienELFReloc_CRTP<Bitwidth>::readRel(Archiver &AR, size_t index) {
57355c46527467526e566944fa393896009bdd0136Logan Chien  if (!AR) {
58355c46527467526e566944fa393896009bdd0136Logan Chien    // Archiver is in bad state before calling read function.
59355c46527467526e566944fa393896009bdd0136Logan Chien    // Return NULL and do nothing.
60355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
61355c46527467526e566944fa393896009bdd0136Logan Chien  }
62355c46527467526e566944fa393896009bdd0136Logan Chien
6358611fc8193e7386698178f167a2e0cbdd6a4f6fLogan Chien  llvm::OwningPtr<ELFRelocTy> sh(new ELFRelocTy());
64355c46527467526e566944fa393896009bdd0136Logan Chien
65355c46527467526e566944fa393896009bdd0136Logan Chien  sh->r_addend = 0;
66355c46527467526e566944fa393896009bdd0136Logan Chien  if (!sh->serializeRel(AR)) {
67355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
68355c46527467526e566944fa393896009bdd0136Logan Chien  }
69355c46527467526e566944fa393896009bdd0136Logan Chien
70355c46527467526e566944fa393896009bdd0136Logan Chien  if (!sh->isValid()) {
71355c46527467526e566944fa393896009bdd0136Logan Chien    // Rel read from archiver is not valid.  Return NULL.
72355c46527467526e566944fa393896009bdd0136Logan Chien    return 0;
73355c46527467526e566944fa393896009bdd0136Logan Chien  }
74355c46527467526e566944fa393896009bdd0136Logan Chien
75355c46527467526e566944fa393896009bdd0136Logan Chien  // Set the section header index
76355c46527467526e566944fa393896009bdd0136Logan Chien  sh->index = index;
77355c46527467526e566944fa393896009bdd0136Logan Chien
78355c46527467526e566944fa393896009bdd0136Logan Chien  return sh.take();
79355c46527467526e566944fa393896009bdd0136Logan Chien}
80355c46527467526e566944fa393896009bdd0136Logan Chien
81355c46527467526e566944fa393896009bdd0136Logan Chientemplate <unsigned Bitwidth>
82355c46527467526e566944fa393896009bdd0136Logan Chieninline void ELFReloc_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
83355c46527467526e566944fa393896009bdd0136Logan Chien  using namespace llvm;
84355c46527467526e566944fa393896009bdd0136Logan Chien  if (shouldPrintHeader) {
85355c46527467526e566944fa393896009bdd0136Logan Chien    out() << '\n' << fillformat('=', 79) << '\n';
86355c46527467526e566944fa393896009bdd0136Logan Chien    out().changeColor(raw_ostream::WHITE, true);
87355c46527467526e566944fa393896009bdd0136Logan Chien    out() << "ELF Relaocation Table Entry "
88355c46527467526e566944fa393896009bdd0136Logan Chien          << this->getIndex() << '\n';
89355c46527467526e566944fa393896009bdd0136Logan Chien    out().resetColor();
90355c46527467526e566944fa393896009bdd0136Logan Chien    out() << fillformat('-', 79) << '\n';
91355c46527467526e566944fa393896009bdd0136Logan Chien  } else {
92355c46527467526e566944fa393896009bdd0136Logan Chien    out() << fillformat('-', 79) << '\n';
93355c46527467526e566944fa393896009bdd0136Logan Chien    out().changeColor(raw_ostream::YELLOW, true);
94355c46527467526e566944fa393896009bdd0136Logan Chien    out() << "ELF Relaocation Table Entry "
95355c46527467526e566944fa393896009bdd0136Logan Chien          << this->getIndex() << " : " << '\n';
96355c46527467526e566944fa393896009bdd0136Logan Chien    out().resetColor();
97355c46527467526e566944fa393896009bdd0136Logan Chien  }
98355c46527467526e566944fa393896009bdd0136Logan Chien
99355c46527467526e566944fa393896009bdd0136Logan Chien#define PRINT_LINT(title, value) \
100355c46527467526e566944fa393896009bdd0136Logan Chien  out() << format("  %-13s : ", (char const *)(title)) << (value) << '\n'
101355c46527467526e566944fa393896009bdd0136Logan Chien  PRINT_LINT("Offset",       concrete()->getOffset()       );
102355c46527467526e566944fa393896009bdd0136Logan Chien  PRINT_LINT("SymTab Index", concrete()->getSymTabIndex()  );
103355c46527467526e566944fa393896009bdd0136Logan Chien  PRINT_LINT("Type",         concrete()->getType()         );
104355c46527467526e566944fa393896009bdd0136Logan Chien  PRINT_LINT("Addend",       concrete()->getAddend()       );
105355c46527467526e566944fa393896009bdd0136Logan Chien#undef PRINT_LINT
106355c46527467526e566944fa393896009bdd0136Logan Chien}
107355c46527467526e566944fa393896009bdd0136Logan Chien
108355c46527467526e566944fa393896009bdd0136Logan Chien#endif // ELF_RELOC_HXX
109