diff options
author | Eric Andersen <andersen@codepoet.org> | 2003-08-13 19:56:33 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2003-08-13 19:56:33 +0000 |
commit | bf83355dda609db2d028ecb740e1daa5cfbe15aa (patch) | |
tree | d7d26bee7bf6151cf291453a13acabcf958f1d02 | |
parent | 4456f25e8fa584fa0a72e0a64961e384e5de587f (diff) | |
download | busybox-w32-bf83355dda609db2d028ecb740e1daa5cfbe15aa.tar.gz busybox-w32-bf83355dda609db2d028ecb740e1daa5cfbe15aa.tar.bz2 busybox-w32-bf83355dda609db2d028ecb740e1daa5cfbe15aa.zip |
Patch from Paul Mundt (lethal) adding sh64 insmod support for busybox
-rw-r--r-- | modutils/insmod.c | 82 |
1 files changed, 72 insertions, 10 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index 84617fa48..c5cab1997 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -2,7 +2,7 @@ | |||
2 | /* | 2 | /* |
3 | * Mini insmod implementation for busybox | 3 | * Mini insmod implementation for busybox |
4 | * | 4 | * |
5 | * This version of insmod supports x86, ARM, SH3/4, powerpc, m68k, | 5 | * This version of insmod supports x86, ARM, SH3/4/5, powerpc, m68k, |
6 | * MIPS, and v850e. | 6 | * MIPS, and v850e. |
7 | * | 7 | * |
8 | * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen | 8 | * Copyright (C) 1999,2000 by Lineo, inc. and Erik Andersen |
@@ -19,6 +19,11 @@ | |||
19 | * very minor changes required to also work with StrongArm and presumably | 19 | * very minor changes required to also work with StrongArm and presumably |
20 | * all ARM based systems. | 20 | * all ARM based systems. |
21 | * | 21 | * |
22 | * Paul Mundt <lethal@linux-sh.org> 08-Aug-2003. | ||
23 | * Integrated support for sh64 (SH-5), from preliminary modutils | ||
24 | * patches from Benedict Gaster <benedict.gaster@superh.com>. | ||
25 | * Currently limited to support for 32bit ABI. | ||
26 | * | ||
22 | * Magnus Damm <damm@opensource.se> 22-May-2002. | 27 | * Magnus Damm <damm@opensource.se> 22-May-2002. |
23 | * The plt and got code are now using the same structs. | 28 | * The plt and got code are now using the same structs. |
24 | * Added generic linked list code to fully support PowerPC. | 29 | * Added generic linked list code to fully support PowerPC. |
@@ -182,17 +187,18 @@ | |||
182 | #define Elf32_RelM Elf32_Rela | 187 | #define Elf32_RelM Elf32_Rela |
183 | #define ELFCLASSM ELFCLASS32 | 188 | #define ELFCLASSM ELFCLASS32 |
184 | 189 | ||
185 | /* the SH changes have only been tested on the SH4 in =little endian= mode */ | 190 | /* the SH changes have only been tested in =little endian= mode */ |
186 | /* I'm not sure about big endian, so let's warn: */ | 191 | /* I'm not sure about big endian, so let's warn: */ |
187 | 192 | ||
188 | #if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__) | 193 | #if defined(__sh__) && defined(__BIG_ENDIAN__) |
189 | #error insmod.c may require changes for use on big endian SH4/SH3 | 194 | #error insmod.c may require changes for use on big endian SH |
190 | #endif | 195 | #endif |
191 | 196 | ||
192 | /* it may or may not work on the SH1/SH2... So let's error on those | 197 | /* it may or may not work on the SH1/SH2... So let's error on those |
193 | also */ | 198 | also */ |
194 | #if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__)))) | 199 | #if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && \ |
195 | #error insmod.c may require changes for non-SH3/SH4 use | 200 | (defined(__sh__)) |
201 | #error insmod.c may require changes for SH1 or SH2 use | ||
196 | #endif | 202 | #endif |
197 | #endif | 203 | #endif |
198 | 204 | ||
@@ -247,7 +253,7 @@ | |||
247 | #ifndef MODUTILS_MODULE_H | 253 | #ifndef MODUTILS_MODULE_H |
248 | static const int MODUTILS_MODULE_H = 1; | 254 | static const int MODUTILS_MODULE_H = 1; |
249 | 255 | ||
250 | #ident "$Id: insmod.c,v 1.99 2003/07/22 08:56:50 andersen Exp $" | 256 | #ident "$Id: insmod.c,v 1.100 2003/08/13 19:56:33 andersen Exp $" |
251 | 257 | ||
252 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | 258 | /* This file contains the structures used by the 2.0 and 2.1 kernels. |
253 | We do not use the kernel headers directly because we do not wish | 259 | We do not use the kernel headers directly because we do not wish |
@@ -468,7 +474,7 @@ int delete_module(const char *); | |||
468 | #ifndef MODUTILS_OBJ_H | 474 | #ifndef MODUTILS_OBJ_H |
469 | static const int MODUTILS_OBJ_H = 1; | 475 | static const int MODUTILS_OBJ_H = 1; |
470 | 476 | ||
471 | #ident "$Id: insmod.c,v 1.99 2003/07/22 08:56:50 andersen Exp $" | 477 | #ident "$Id: insmod.c,v 1.100 2003/08/13 19:56:33 andersen Exp $" |
472 | 478 | ||
473 | /* The relocatable object is manipulated using elfin types. */ | 479 | /* The relocatable object is manipulated using elfin types. */ |
474 | 480 | ||
@@ -1201,7 +1207,51 @@ arch_apply_relocation(struct obj_file *f, | |||
1201 | *loc = v - got; | 1207 | *loc = v - got; |
1202 | break; | 1208 | break; |
1203 | 1209 | ||
1204 | #endif | 1210 | #if defined(__SH5__) |
1211 | case R_SH_IMM_MEDLOW16: | ||
1212 | case R_SH_IMM_LOW16: | ||
1213 | { | ||
1214 | Elf32_Addr word; | ||
1215 | |||
1216 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16) | ||
1217 | v >>= 16; | ||
1218 | |||
1219 | /* | ||
1220 | * movi and shori have the format: | ||
1221 | * | ||
1222 | * | op | imm | reg | reserved | | ||
1223 | * 31..26 25..10 9.. 4 3 .. 0 | ||
1224 | * | ||
1225 | * so we simply mask and or in imm. | ||
1226 | */ | ||
1227 | word = *loc & ~0x3fffc00; | ||
1228 | word |= (v & 0xffff) << 10; | ||
1229 | |||
1230 | *loc = word; | ||
1231 | |||
1232 | break; | ||
1233 | } | ||
1234 | |||
1235 | case R_SH_IMM_MEDLOW16_PCREL: | ||
1236 | case R_SH_IMM_LOW16_PCREL: | ||
1237 | { | ||
1238 | Elf32_Addr word; | ||
1239 | |||
1240 | word = *loc & ~0x3fffc00; | ||
1241 | |||
1242 | v -= dot; | ||
1243 | |||
1244 | if (ELF32_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL) | ||
1245 | v >>= 16; | ||
1246 | |||
1247 | word |= (v & 0xffff) << 10; | ||
1248 | |||
1249 | *loc = word; | ||
1250 | |||
1251 | break; | ||
1252 | } | ||
1253 | #endif /* __SH5__ */ | ||
1254 | #endif /* __sh__ */ | ||
1205 | 1255 | ||
1206 | default: | 1256 | default: |
1207 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); | 1257 | printf("Warning: unhandled reloc %d\n",(int)ELF32_R_TYPE(rel->r_info)); |
@@ -3470,14 +3520,26 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
3470 | 3520 | ||
3471 | /* Insert all symbols into the hash table. */ | 3521 | /* Insert all symbols into the hash table. */ |
3472 | for (j = 1, ++sym; j < nsym; ++j, ++sym) { | 3522 | for (j = 1, ++sym; j < nsym; ++j, ++sym) { |
3523 | ElfW(Addr) val = sym->st_value; | ||
3473 | const char *name; | 3524 | const char *name; |
3474 | if (sym->st_name) | 3525 | if (sym->st_name) |
3475 | name = strtab + sym->st_name; | 3526 | name = strtab + sym->st_name; |
3476 | else | 3527 | else |
3477 | name = f->sections[sym->st_shndx]->name; | 3528 | name = f->sections[sym->st_shndx]->name; |
3478 | 3529 | ||
3530 | #if defined(__SH5__) | ||
3531 | /* | ||
3532 | * For sh64 it is possible that the target of a branch | ||
3533 | * requires a mode switch (32 to 16 and back again). | ||
3534 | * | ||
3535 | * This is implied by the lsb being set in the target | ||
3536 | * address for SHmedia mode and clear for SHcompact. | ||
3537 | */ | ||
3538 | val |= sym->st_other & 4; | ||
3539 | #endif | ||
3540 | |||
3479 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, | 3541 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, |
3480 | sym->st_value, sym->st_size); | 3542 | val, sym->st_size); |
3481 | } | 3543 | } |
3482 | } | 3544 | } |
3483 | break; | 3545 | break; |