• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef CRAZY_LINKER_ELF_RELOCATIONS_H
6 #define CRAZY_LINKER_ELF_RELOCATIONS_H
7 
8 #include <string.h>
9 
10 #include "elf_traits.h"
11 
12 namespace crazy {
13 
14 class ElfSymbols;
15 class ElfView;
16 class Error;
17 
18 // An ElfRelocations instance holds information about relocations in a mapped
19 // ELF binary.
20 class ElfRelocations {
21  public:
ElfRelocations()22   ElfRelocations() { ::memset(this, 0, sizeof(*this)); }
~ElfRelocations()23   ~ElfRelocations() {}
24 
25   bool Init(const ElfView* view, Error* error);
26 
27   // Abstract class used to resolve symbol names into addresses.
28   // Callers of ::ApplyAll() should pass the address of a derived class
29   // that properly implements the Lookup() method.
30   class SymbolResolver {
31    public:
SymbolResolver()32     SymbolResolver() {}
~SymbolResolver()33     ~SymbolResolver() {}
34     virtual void* Lookup(const char* symbol_name) = 0;
35   };
36 
37   // Apply all relocations to the target mapped ELF binary. Must be called
38   // after Init().
39   // |symbols| maps to the symbol entries for the target library only.
40   // |resolver| can resolve symbols out of the current library.
41   // On error, return false and set |error| message.
42   bool ApplyAll(const ElfSymbols* symbols,
43                 SymbolResolver* resolver,
44                 Error* error);
45 
46   // This function is used to adjust relocated addresses in a copy of an
47   // existing section of an ELF binary. I.e. |src_addr|...|src_addr + size|
48   // must be inside the mapped ELF binary, this function will first copy its
49   // content into |dst_addr|...|dst_addr + size|, then adjust all relocated
50   // addresses inside the destination section as if it was loaded/mapped
51   // at |map_addr|...|map_addr + size|. Only relative relocations are processed,
52   // symbolic ones are ignored.
53   void CopyAndRelocate(size_t src_addr,
54                        size_t dst_addr,
55                        size_t map_addr,
56                        size_t size);
57 
58  private:
59   bool ResolveSymbol(unsigned rel_type,
60                      unsigned rel_symbol,
61                      const ElfSymbols* symbols,
62                      SymbolResolver* resolver,
63                      ELF::Addr reloc,
64                      ELF::Addr* sym_addr,
65                      Error* error);
66   bool ApplyRelaReloc(const ELF::Rela* rela,
67                       ELF::Addr sym_addr,
68                       bool resolved,
69                       Error* error);
70   bool ApplyRelReloc(const ELF::Rel* rel,
71                      ELF::Addr sym_addr,
72                      bool resolved,
73                      Error* error);
74   bool ApplyRelaRelocs(const ELF::Rela* relocs,
75                        size_t relocs_count,
76                        const ElfSymbols* symbols,
77                        SymbolResolver* resolver,
78                        Error* error);
79   bool ApplyRelRelocs(const ELF::Rel* relocs,
80                       size_t relocs_count,
81                       const ElfSymbols* symbols,
82                       SymbolResolver* resolver,
83                       Error* error);
84   void AdjustRelocation(ELF::Word rel_type,
85                         ELF::Addr src_reloc,
86                         size_t dst_delta,
87                         size_t map_delta);
88   void RelocateRela(size_t src_addr,
89                     size_t dst_addr,
90                     size_t map_addr,
91                     size_t size);
92   void RelocateRel(size_t src_addr,
93                    size_t dst_addr,
94                    size_t map_addr,
95                    size_t size);
96 
97 #if defined(__mips__)
98   bool RelocateMipsGot(const ElfSymbols* symbols,
99                        SymbolResolver* resolver,
100                        Error* error);
101 #endif
102 
103   const ELF::Phdr* phdr_;
104   size_t phdr_count_;
105   size_t load_bias_;
106 
107   ELF::Addr relocations_type_;
108   ELF::Addr plt_relocations_;
109   size_t plt_relocations_size_;
110   ELF::Addr* plt_got_;
111 
112   ELF::Addr relocations_;
113   size_t relocations_size_;
114 
115 #if defined(__mips__)
116   // MIPS-specific relocation fields.
117   ELF::Word mips_symtab_count_;
118   ELF::Word mips_local_got_count_;
119   ELF::Word mips_gotsym_;
120 #endif
121 
122   bool has_text_relocations_;
123   bool has_symbolic_;
124 };
125 
126 }  // namespace crazy
127 
128 #endif  // CRAZY_LINKER_ELF_RELOCATIONS_H
129