Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / android_crazy_linker / src / src / crazy_linker_elf_relocations.h
1 // Copyright 2014 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 #include <unistd.h>
10
11 #include "elf_traits.h"
12
13 namespace crazy {
14
15 class ElfSymbols;
16 class ElfView;
17 class Error;
18
19 // An ElfRelocations instance holds information about relocations in a mapped
20 // ELF binary.
21 class ElfRelocations {
22  public:
23   ElfRelocations() { ::memset(this, 0, sizeof(*this)); }
24   ~ElfRelocations() {}
25
26   bool Init(const ElfView* view, Error* error);
27
28   // Abstract class used to resolve symbol names into addresses.
29   // Callers of ::ApplyAll() should pass the address of a derived class
30   // that properly implements the Lookup() method.
31   class SymbolResolver {
32    public:
33     SymbolResolver() {}
34     ~SymbolResolver() {}
35     virtual void* Lookup(const char* symbol_name) = 0;
36   };
37
38   // Apply all relocations to the target mapped ELF binary. Must be called
39   // after Init().
40   // |symbols| maps to the symbol entries for the target library only.
41   // |resolver| can resolve symbols out of the current library.
42   // On error, return false and set |error| message.
43   bool ApplyAll(const ElfSymbols* symbols,
44                 SymbolResolver* resolver,
45                 Error* error);
46
47 #ifdef __arm__
48   // Register ARM packed relocations to apply.
49   // |arm_packed_relocs| is a pointer to packed relocations data.
50   void RegisterArmPackedRelocs(uint8_t* arm_packed_relocs);
51 #endif
52
53   // This function is used to adjust relocated addresses in a copy of an
54   // existing section of an ELF binary. I.e. |src_addr|...|src_addr + size|
55   // must be inside the mapped ELF binary, this function will first copy its
56   // content into |dst_addr|...|dst_addr + size|, then adjust all relocated
57   // addresses inside the destination section as if it was loaded/mapped
58   // at |map_addr|...|map_addr + size|. Only relative relocations are processed,
59   // symbolic ones are ignored.
60   void CopyAndRelocate(size_t src_addr,
61                        size_t dst_addr,
62                        size_t map_addr,
63                        size_t size);
64
65  private:
66   bool ResolveSymbol(unsigned rel_type,
67                      unsigned rel_symbol,
68                      const ElfSymbols* symbols,
69                      SymbolResolver* resolver,
70                      ELF::Addr reloc,
71                      ELF::Addr* sym_addr,
72                      Error* error);
73   bool ApplyRelaReloc(const ELF::Rela* rela,
74                       ELF::Addr sym_addr,
75                       bool resolved,
76                       Error* error);
77   bool ApplyRelReloc(const ELF::Rel* rel,
78                      ELF::Addr sym_addr,
79                      bool resolved,
80                      Error* error);
81   bool ApplyRelaRelocs(const ELF::Rela* relocs,
82                        size_t relocs_count,
83                        const ElfSymbols* symbols,
84                        SymbolResolver* resolver,
85                        Error* error);
86   bool ApplyRelRelocs(const ELF::Rel* relocs,
87                       size_t relocs_count,
88                       const ElfSymbols* symbols,
89                       SymbolResolver* resolver,
90                       Error* error);
91   void AdjustRelocation(ELF::Word rel_type,
92                         ELF::Addr src_reloc,
93                         size_t dst_delta,
94                         size_t map_delta);
95   void RelocateRela(size_t src_addr,
96                     size_t dst_addr,
97                     size_t map_addr,
98                     size_t size);
99   void RelocateRel(size_t src_addr,
100                    size_t dst_addr,
101                    size_t map_addr,
102                    size_t size);
103
104 #ifdef __arm__
105   // Apply ARM packed relocations.
106   // On error, return false and set |error| message.  No-op if no packed
107   // relocations were registered.
108   bool ApplyArmPackedRelocs(Error* error);
109 #endif
110
111 #if defined(__mips__)
112   bool RelocateMipsGot(const ElfSymbols* symbols,
113                        SymbolResolver* resolver,
114                        Error* error);
115 #endif
116
117   const ELF::Phdr* phdr_;
118   size_t phdr_count_;
119   size_t load_bias_;
120
121   ELF::Addr relocations_type_;
122   ELF::Addr plt_relocations_;
123   size_t plt_relocations_size_;
124   ELF::Addr* plt_got_;
125
126   ELF::Addr relocations_;
127   size_t relocations_size_;
128
129 #if defined(__mips__)
130   // MIPS-specific relocation fields.
131   ELF::Word mips_symtab_count_;
132   ELF::Word mips_local_got_count_;
133   ELF::Word mips_gotsym_;
134 #endif
135
136 #if defined(__arm__)
137   uint8_t* arm_packed_relocs_;
138 #endif
139
140   bool has_text_relocations_;
141   bool has_symbolic_;
142 };
143
144 }  // namespace crazy
145
146 #endif  // CRAZY_LINKER_ELF_RELOCATIONS_H