The Pedigree Project  0.1
kernel/core/processor/arm_926e/Elf32.cc
1 /*
2  * Copyright (c) 2008-2014, Pedigree Developers
3  *
4  * Please see the CONTRIB file in the root of the source tree for a full
5  * list of contributors.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include "pedigree/kernel/Log.h"
21 #include "pedigree/kernel/linker/Elf.h"
22 #include "pedigree/kernel/linker/KernelElf.h"
23 
24 // http://www.caldera.com/developers/devspecs/abi386-4.pdf
25 
26 #define R_386_NONE 0
27 #define R_386_32 1
28 #define R_386_PC32 2
29 #define R_386_GOT32 3
30 #define R_386_PLT32 4
31 #define R_386_COPY 5
32 #define R_386_GLOB_DAT 6
33 #define R_386_JMP_SLOT 7
34 #define R_386_RELATIVE 8
35 #define R_386_GOTOFF 9
36 #define R_386_GOTPC 10
37 
39  ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab,
40  uintptr_t loadBase, SymbolTable::Policy policy)
41 {
42  // Section not loaded?
43  if (pSh && pSh->addr == 0)
44  return true; // Not a fatal error.
45 
46  // Get the address of the unit to be relocated.
47  uint32_t address = ((pSh) ? pSh->addr : loadBase) + rel.offset;
48 
49  // Addend is the value currently at the given address.
50  uint32_t A = *reinterpret_cast<uint32_t *>(address);
51 
52  // 'Place' is the address.
53  uint32_t P = address;
54 
55  // Symbol location.
56  uint32_t S = 0;
57  ElfSymbol_t *pSymbols = 0;
58  if (!m_pDynamicSymbolTable)
59  pSymbols = reinterpret_cast<ElfSymbol_t *>(m_pSymbolTable);
60  else
61  pSymbols = m_pDynamicSymbolTable;
62 
63  const char *pStringTable = 0;
64  if (!m_pDynamicStringTable)
65  pStringTable = reinterpret_cast<const char *>(m_pStringTable);
66  else
67  pStringTable = m_pDynamicStringTable;
68 
69  // If this is a section header, patch straight to it.
70  if (pSymbols && ST_TYPE(pSymbols[R_SYM(rel.info)].info) == 3)
71  {
72  // Section type - the name will be the name of the section header it
73  // refers to.
74  int shndx = pSymbols[R_SYM(rel.info)].shndx;
75  ElfSectionHeader_t *pSh = &m_pSectionHeaders[shndx];
76  S = pSh->addr;
77  }
78  else if (R_TYPE(rel.info) != R_386_RELATIVE) // Relative doesn't need a
79  // symbol!
80  {
81  const char *pStr = pStringTable + pSymbols[R_SYM(rel.info)].name;
82 
83  if (pSymtab == 0)
84  pSymtab = KernelElf::instance().getSymbolTable();
85 
86  if (R_TYPE(rel.info) == R_386_COPY)
87  {
89  }
90  S = pSymtab->lookup(String(pStr), this, policy);
91 
92  if (S == 0 && StringLength(pStr))
93  WARNING(
94  "Relocation failed for symbol \""
95  << pStr << "\" (relocation=" << R_TYPE(rel.info) << ")");
96  // This is a weak relocation, but it was undefined.
97  else if (S == ~0UL)
98  WARNING("Weak relocation == 0 [undefined] for \"" << pStr << "\".");
99  }
100 
101  if (S == 0 && (R_TYPE(rel.info) != R_386_RELATIVE))
102  return false;
103  if (S == ~0UL)
104  S = 0; // undefined
105 
106  // Base address
107  uint32_t B = loadBase;
108 
109  uint32_t result = A; // Currently the result is the addend.
110  switch (R_TYPE(rel.info))
111  {
112  case R_386_NONE:
113  break;
114  case R_386_32:
115  result = S + A;
116  break;
117  case R_386_PC32:
118  result = S + A - P;
119  break;
120  case R_386_JMP_SLOT:
121  case R_386_GLOB_DAT:
122  result = S;
123  break;
124  case R_386_COPY:
125  result = *reinterpret_cast<uintptr_t *>(S);
126  break;
127  case R_386_RELATIVE:
128  result = B + A;
129  break;
130  default:
131  ERROR("Relocation not supported: " << Dec << R_TYPE(rel.info));
132  }
133 
134  // Write back the result.
135  uint32_t *pResult = reinterpret_cast<uint32_t *>(address);
136  *pResult = result;
137  return true;
138 }
139 
141  ElfRela_t rela, ElfSectionHeader_t *pSh, SymbolTable *pSymtab,
142  uintptr_t loadBase, SymbolTable::Policy policy)
143 {
144  ERROR("The ARM architecture does not use RELA entries!");
145  return false;
146 }
uintptr_t EXPORTED_PUBLIC lookup(const HashedStringView &name, Elf *pElf, Policy policy=LocalFirst, Binding *pBinding=0)
Definition: SymbolTable.cc:126
Definition: String.h:49
static KernelElf & instance()
Definition: KernelElf.h:129
#define WARNING(text)
Definition: Log.h:78
bool applyRelocation(ElfRel_t rel, ElfSectionHeader_t *pSh, SymbolTable *pSymtab=0, uintptr_t loadBase=0, SymbolTable::Policy policy=SymbolTable::LocalFirst)
#define ERROR(text)
Definition: Log.h:82
Definition: Log.h:138