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_HXX
18b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define ELF_RELOC_HXX
19b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
20b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include "utils/raw_ostream.h"
21b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
22b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/Support/Format.h>
23b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#include <llvm/Support/raw_ostream.h>
24b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
25b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
26b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <typename Archiver>
27b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFReloc<Bitwidth> *
28b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFReloc_CRTP<Bitwidth>::readRela(Archiver &AR, size_t index) {
29b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!AR) {
30b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Archiver is in bad state before calling read function.
31b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Return NULL and do nothing.
32b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
33b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
34b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
35d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  std::unique_ptr<ELFRelocTy> sh(new ELFRelocTy());
36b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
37b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->serializeRela(AR)) {
38b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Unable to read the structure.  Return NULL.
39b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
40b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
41b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
42b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->isValid()) {
43b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Rel read from archiver is not valid.  Return NULL.
44b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
45b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
46b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
47b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  // Set the section header index
48b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  sh->index = index;
49b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
50d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  return sh.release();
51b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
52b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
53b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
54b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <typename Archiver>
55b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline ELFReloc<Bitwidth> *
56b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen HinesELFReloc_CRTP<Bitwidth>::readRel(Archiver &AR, size_t index) {
57b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!AR) {
58b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Archiver is in bad state before calling read function.
59b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Return NULL and do nothing.
60b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
61b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
62b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
63d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  std::unique_ptr<ELFRelocTy> sh(new ELFRelocTy());
64b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
65b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  sh->r_addend = 0;
66b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->serializeRel(AR)) {
67b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
68b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
69b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
70b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (!sh->isValid()) {
71b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    // Rel read from archiver is not valid.  Return NULL.
72b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    return 0;
73b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
74b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
75b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  // Set the section header index
76b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  sh->index = index;
77b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
78d282991c78d1fd79a222c5f114e623da255ba8a0Stephen Hines  return sh.release();
79b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
80b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
81b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinestemplate <unsigned Bitwidth>
82b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hinesinline void ELFReloc_CRTP<Bitwidth>::print(bool shouldPrintHeader) const {
83b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  using namespace llvm;
84b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  if (shouldPrintHeader) {
85b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << '\n' << fillformat('=', 79) << '\n';
86b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().changeColor(raw_ostream::WHITE, true);
87b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << "ELF Relaocation Table Entry "
88b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          << this->getIndex() << '\n';
89b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().resetColor();
90b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << fillformat('-', 79) << '\n';
91b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  } else {
92b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << fillformat('-', 79) << '\n';
93b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().changeColor(raw_ostream::YELLOW, true);
94b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out() << "ELF Relaocation Table Entry "
95b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines          << this->getIndex() << " : " << '\n';
96b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines    out().resetColor();
97b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  }
98b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
99b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#define PRINT_LINT(title, value) \
100b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  out() << format("  %-13s : ", (char const *)(title)) << (value) << '\n'
101b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Offset",       concrete()->getOffset()       );
102b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("SymTab Index", concrete()->getSymTabIndex()  );
103b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Type",         concrete()->getType()         );
104b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines  PRINT_LINT("Addend",       concrete()->getAddend()       );
105b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#undef PRINT_LINT
106b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines}
107b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines
108b53c8a59e6f21ed36a0c3d9d4ce5834d4cc3c298Stephen Hines#endif // ELF_RELOC_HXX
109