ppc build now builds, but is for sure broken
[newos.git] / kernel / arch / ppc / arch_elf.c
blobb2baea33f878fe9c440e1661db80837aa2bfb513
1 /*
2 ** Copyright 2002-2004, Travis Geiselbrecht. All rights reserved.
3 ** Distributed under the terms of the NewOS License.
4 */
5 #include <kernel/kernel.h>
6 #include <kernel/debug.h>
7 #include <kernel/elf.h>
8 #include <newos/elf32.h>
9 #include <kernel/arch/elf.h>
11 #define CHATTY 0
13 int arch_elf_relocate_rel(struct elf_image_info *image, const char *sym_prepend,
14 struct elf_image_info *resolve_image, struct Elf32_Rel *rel, int rel_len)
16 // there are no rel entries in PPC elf
17 return NO_ERROR;
20 int arch_elf_relocate_rela(struct elf_image_info *image, const char *sym_prepend,
21 struct elf_image_info *resolve_image, struct Elf32_Rela *rel, int rel_len)
23 int i;
24 struct Elf32_Sym *sym;
25 int vlErr;
26 addr_t S = 0;
27 addr_t final_val;
29 #define P ((addr_t)(image->regions[0].delta + rel[i].r_offset))
30 #define A ((addr_t)rel[i].r_addend)
31 #define B (image->regions[0].delta)
33 for(i = 0; i * (int)sizeof(struct Elf32_Rela) < rel_len; i++) {
34 #if CHATTY
35 dprintf("looking at rel type %d, offset 0x%x, sym 0x%x, addend 0x%x\n",
36 ELF32_R_TYPE(rel[i].r_info), rel[i].r_offset, ELF32_R_SYM(rel[i].r_info), rel[i].r_addend);
37 #endif
38 switch(ELF32_R_TYPE(rel[i].r_info)) {
39 case R_PPC_ADDR32:
40 case R_PPC_ADDR24:
41 case R_PPC_ADDR16:
42 case R_PPC_ADDR16_LO:
43 case R_PPC_ADDR16_HI:
44 case R_PPC_ADDR16_HA:
45 case R_PPC_REL24:
46 sym = SYMBOL(image, ELF32_R_SYM(rel[i].r_info));
48 vlErr = elf_resolve_symbol(image, sym, resolve_image, sym_prepend, &S);
49 if(vlErr<0)
50 return vlErr;
51 break;
54 switch(ELF32_R_TYPE(rel[i].r_info)) {
55 case R_PPC_NONE:
56 continue;
58 case R_PPC_ADDR32:
59 final_val = S + A;
60 break;
62 case R_PPC_ADDR16:
63 *(Elf32_Half*)P = S;
64 continue;
66 case R_PPC_ADDR16_LO:
67 *(Elf32_Half*)P = S & 0xffff;
68 continue;
70 case R_PPC_ADDR16_HI:
71 *(Elf32_Half*)P = (S >> 16) & 0xffff;
72 continue;
74 case R_PPC_ADDR16_HA:
75 *(Elf32_Half*)P = ((S >> 16) + ((S & 0x8000) ? 1 : 0)) & 0xFFFF;
76 continue;
78 case R_PPC_REL24:
79 final_val = (*(Elf32_Word *)P & 0xff000003) | ((S + A - P) & 0x3fffffc);
80 break;
82 case R_PPC_RELATIVE:
83 final_val = B + A;
84 break;
86 default:
87 panic("arch_elf_relocate_rela: unhandled relocation type %d\n", ELF32_R_TYPE(rel[i].r_info));
88 continue;
90 #if CHATTY
91 dprintf("going to put 0x%x at 0x%x\n", final_val, P);
92 #endif
93 *(addr_t *)P = final_val;
96 return NO_ERROR;