2 * Copyright 2003-2006, Axel Dörfler, axeld@pinc-software.de
3 * Distributed under the terms of the MIT License.
5 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
6 * Copyright 2002, Manuel J. Petit. All rights reserved.
7 * Distributed under the terms of the NewOS License.
11 #include "runtime_loader_private.h"
13 #include <runtime_loader.h>
22 # define TRACE(x) dprintf x
29 write_32(addr_t
*P
, Elf32_Word value
)
31 *(Elf32_Word
*)P
= value
;
36 write_16(addr_t
*P
, Elf32_Word value
)
39 *(Elf32_Half
*)P
= (Elf32_Half
)value
;
44 write_16_check(addr_t
*P
, Elf32_Word value
)
47 if ((value
& 0xffff0000) && (~value
& 0xffff8000))
49 *(Elf32_Half
*)P
= (Elf32_Half
)value
;
55 write_8(addr_t
*P
, Elf32_Word value
)
58 *(uint8
*)P
= (uint8
)value
;
64 write_8_check(addr_t
*P
, Elf32_Word value
)
67 if ((value
& 0xffffff00) && (~value
& 0xffffff80))
69 *(uint8
*)P
= (uint8
)value
;
75 relocate_rela(image_t
*rootImage
, image_t
*image
, Elf32_Rela
*rel
, int rel_len
,
76 SymbolLookupCache
* cache
)
82 # define P ((addr_t *)(image->regions[0].delta + rel[i].r_offset))
84 #define A ((addr_t)rel[i].r_addend)
85 # define B (image->regions[0].delta)
87 for (i
= 0; i
* (int)sizeof(Elf32_Rel
) < rel_len
; i
++) {
88 unsigned type
= ELF32_R_TYPE(rel
[i
].r_info
);
102 sym
= SYMBOL(image
, ELF32_R_SYM(rel
[i
].r_info
));
104 status
= resolve_symbol(rootImage
, image
, sym
, cache
, &S
);
106 TRACE(("resolve symbol \"%s\" returned: %ld\n",
107 SYMNAME(image
, sym
), status
));
108 printf("resolve symbol \"%s\" returned: %ld\n",
109 SYMNAME(image
, sym
), status
);
121 if (write_16_check(P
, S
+ A
))
123 TRACE(("R_68K_16 overflow\n"));
127 if (write_8_check(P
, S
+ A
))
129 TRACE(("R_68K_8 overflow\n"));
133 write_32(P
, (S
+ A
- (addr_t
)P
));
138 if (write_16_check(P
, (S
+ A
- P
)))
140 TRACE(("R_68K_PC16 overflow\n"));
144 if (write_8(P
, (S
+ A
- P
)))
146 TRACE(("R_68K_PC8 overflow\n"));
151 write_32(P
, (G
+ A
- P
));
156 if (write_16_check(P
, (G
+ A
- P
)))
158 TRACE(("R_68K_GOT16 overflow\n"));
163 if (write_8_check(P
, (G
+ A
- P
)))
165 TRACE(("R_68K_GOT8 overflow\n"));
170 write_32(P
, (G
+ A
));
175 if (write_16_check(P
, (G
+ A
)))
177 TRACE(("R_68K_GOT16 overflow\n"));
182 if (write_8_check(P
, (G
+ A
)))
184 TRACE(("R_68K_GOT8 overflow\n"));
189 write_32(P
, (L
+ A
- P
));
194 if (write_16_check(P
, (L
+ A
- P
)))
196 TRACE(("R_68K_PLT16 overflow\n"));
201 if (write_8_check(P
, (L
+ A
- P
)))
203 TRACE(("R_68K_PLT8 overflow\n"));
208 write_32(P
, (L
+ A
));
213 if (write_16_check(P
, (L
+ A
)))
215 TRACE(("R_68K_PLT16O overflow\n"));
220 if (write_8_check(P
, (L
+ A
)))
222 TRACE(("R_68K_PLT8O overflow\n"));
228 final_val
= L
+ A
- (addr_t
)P
;
235 write_32(P
, S
/* + A*/);
238 //XXX ? write_32(P, (G + A));
252 final_val
= S
+ A
- GOT
;
255 final_val
= GOT
+ A
- P
;
259 TRACE(("unhandled relocation type %d\n", ELF32_R_TYPE(rel
[i
].r_info
)));
260 return B_NOT_ALLOWED
;
275 arch_relocate_image(image_t
*rootImage
, image_t
*image
,
276 SymbolLookupCache
* cache
)
280 // deal with the rels first
282 TRACE(("RELA relocations not supported\n"));
287 TRACE(("RELA relocations not supported\n"));
290 status
= relocate_rel(rootImage
, image
, image
->pltrel
,
298 status
= relocate_rela(rootImage
, image
, image
->rela
, image
->rela_len
,
303 //TRACE(("RELA relocations not supported\n"));
306 //for (i = 1; i * (int)sizeof(Elf32_Rela) < image->rela_len; i++) {
307 // printf("rela: type %d\n", ELF32_R_TYPE(image->rela[i].r_info));
312 if (image
->pltrela
) {
313 status
= relocate_rela(rootImage
, image
, image
->pltrela
,