2 * Copyright 2007, François Revol, revol@free.fr.
3 * Distributed under the terms of the MIT License.
5 * Copyright 2005, Ingo Weinhold <bonefish@cs.tu-berlin.de>.
6 * All rights reserved. Distributed under the terms of the MIT License.
9 * Copyright 2002, Travis Geiselbrecht. All rights reserved.
10 * Distributed under the terms of the NewOS License.
14 #include <boot/arch.h>
17 #include <KernelExport.h>
23 //#define TRACE_ARCH_ELF
25 # define TRACE(x) dprintf x
34 static const char *kRelocations
[] = {
36 "R_68K_32", /* Direct 32 bit */
37 "R_68K_16", /* Direct 16 bit */
38 "R_68K_8", /* Direct 8 bit */
39 "R_68K_PC32", /* PC relative 32 bit */
40 "R_68K_PC16", /* PC relative 16 bit */
41 "R_68K_PC8", /* PC relative 8 bit */
42 "R_68K_GOT32", /* 32 bit PC relative GOT entry */
43 "R_68K_GOT16", /* 16 bit PC relative GOT entry */
44 "R_68K_GOT8", /* 8 bit PC relative GOT entry */
45 "R_68K_GOT32O", /* 32 bit GOT offset */
46 "R_68K_GOT16O", /* 16 bit GOT offset */
47 "R_68K_GOT8O", /* 8 bit GOT offset */
48 "R_68K_PLT32", /* 32 bit PC relative PLT address */
49 "R_68K_PLT16", /* 16 bit PC relative PLT address */
50 "R_68K_PLT8", /* 8 bit PC relative PLT address */
51 "R_68K_PLT32O", /* 32 bit PLT offset */
52 "R_68K_PLT16O", /* 16 bit PLT offset */
53 "R_68K_PLT8O", /* 8 bit PLT offset */
54 "R_68K_COPY", /* Copy symbol at runtime */
55 "R_68K_GLOB_DAT", /* Create GOT entry */
56 "R_68K_JMP_SLOT", /* Create PLT entry */
57 "R_68K_RELATIVE", /* Adjust by program base */
58 /* These are GNU extensions to enable C++ vtable garbage collection. */
59 "R_68K_GNU_VTINHERIT",
63 "R_386_32", /* add symbol value */
64 "R_386_PC32", /* add PC relative symbol value */
65 "R_386_GOT32", /* add PC relative GOT offset */
66 "R_386_PLT32", /* add PC relative PLT offset */
67 "R_386_COPY", /* copy data from shared object */
68 "R_386_GLOB_DAT", /* set GOT entry to data address */
69 "R_386_JMP_SLOT", /* set GOT entry to code address */
70 "R_386_RELATIVE", /* add load address of shared object */
71 "R_386_GOTOFF", /* add GOT relative symbol address */
72 "R_386_GOTPC", /* add PC relative GOT table address */
79 boot_arch_elf_relocate_rel(struct preloaded_elf32_image
*image
, Elf32_Rel
*rel
,
83 arch_elf_relocate_rel(struct elf_image_info
*image
,
84 struct elf_image_info
*resolve_image
, Elf32_Rel
*rel
, int rel_len
)
87 // there are no rel entries in M68K elf
93 write_32(addr_t P
, Elf32_Word value
)
95 *(Elf32_Word
*)P
= value
;
100 write_16(addr_t P
, Elf32_Word value
)
103 *(Elf32_Half
*)P
= (Elf32_Half
)value
;
108 write_16_check(addr_t P
, Elf32_Word value
)
111 if ((value
& 0xffff0000) && (~value
& 0xffff8000))
113 *(Elf32_Half
*)P
= (Elf32_Half
)value
;
119 write_8(addr_t P
, Elf32_Word value
)
122 *(uint8
*)P
= (uint8
)value
;
128 write_8_check(addr_t P
, Elf32_Word value
)
131 if ((value
& 0xffffff00) && (~value
& 0xffffff80))
133 *(uint8
*)P
= (uint8
)value
;
140 boot_arch_elf_relocate_rela(struct preloaded_elf32_image
*image
,
141 Elf32_Rela
*rel
, int rel_len
)
144 arch_elf_relocate_rela(struct elf_image_info
*image
,
145 struct elf_image_info
*resolve_image
, Elf32_Rela
*rel
, int rel_len
)
151 addr_t S
= 0; // symbol address
152 addr_t R
= 0; // section relative symbol address
154 addr_t G
= 0; // GOT address
155 addr_t L
= 0; // PLT address
157 #define P ((addr_t)(image->text_region.delta + rel[i].r_offset))
158 #define A ((addr_t)rel[i].r_addend)
159 #define B (image->text_region.delta)
161 // TODO: Get the GOT address!
162 #define REQUIRE_GOT \
164 dprintf("arch_elf_relocate_rela(): Failed to get GOT address!\n"); \
168 // TODO: Get the PLT address!
169 #define REQUIRE_PLT \
171 dprintf("arch_elf_relocate_rela(): Failed to get PLT address!\n"); \
175 for (i
= 0; i
* (int)sizeof(Elf32_Rela
) < rel_len
; i
++) {
177 dprintf("looking at rel type %d, offset 0x%lx, sym 0x%lx, addend 0x%lx\n",
178 ELF32_R_TYPE(rel
[i
].r_info
), rel
[i
].r_offset
, ELF32_R_SYM(rel
[i
].r_info
), rel
[i
].r_addend
);
180 switch (ELF32_R_TYPE(rel
[i
].r_info
)) {
189 sym
= SYMBOL(image
, ELF32_R_SYM(rel
[i
].r_info
));
192 vlErr
= boot_elf_resolve_symbol(image
, sym
, &S
);
194 vlErr
= elf_resolve_symbol(image
, sym
, resolve_image
, &S
);
197 dprintf("%s(): Failed to relocate "
198 "entry index %d, rel type %d, offset 0x%lx, sym 0x%lx, "
199 "addend 0x%lx\n", __FUNCTION__
, i
, ELF32_R_TYPE(rel
[i
].r_info
),
200 rel
[i
].r_offset
, ELF32_R_SYM(rel
[i
].r_info
),
207 switch (ELF32_R_TYPE(rel
[i
].r_info
)) {
213 dprintf("arch_elf_relocate_rela(): R_68K_COPY not yet "
223 if (write_16_check(P
, S
+ A
))
225 dprintf("R_68K_16 overflow\n");
229 if (write_8_check(P
, S
+ A
))
231 dprintf("R_68K_8 overflow\n");
235 write_32(P
, (S
+ A
- P
));
239 if (write_16_check(P
, (S
+ A
- P
)))
241 dprintf("R_68K_PC16 overflow\n");
245 if (write_8(P
, (S
+ A
- P
)))
247 dprintf("R_68K_PC8 overflow\n");
252 write_32(P
, (G
+ A
- P
));
257 if (write_16_check(P
, (G
+ A
- P
)))
259 dprintf("R_68K_GOT16 overflow\n");
264 if (write_8_check(P
, (G
+ A
- P
)))
266 dprintf("R_68K_GOT8 overflow\n");
271 write_32(P
, (G
+ A
));
276 if (write_16_check(P
, (G
+ A
)))
278 dprintf("R_68K_GOT16 overflow\n");
283 if (write_8_check(P
, (G
+ A
)))
285 dprintf("R_68K_GOT8 overflow\n");
289 write_32(P
, (G
+ A
));
298 write_32(P
, (L
+ A
- P
));
303 if (write_16_check(P
, (L
+ A
- P
)))
305 dprintf("R_68K_PLT16 overflow\n");
310 if (write_8_check(P
, (L
+ A
- P
)))
312 dprintf("R_68K_PLT8 overflow\n");
317 write_32(P
, (L
+ A
));
322 if (write_16_check(P
, (L
+ A
)))
324 dprintf("R_68K_PLT16O overflow\n");
329 if (write_8_check(P
, (L
+ A
)))
331 dprintf("R_68K_PLT8O overflow\n");
335 dprintf("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel
[i
].r_info
));