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 /modutils | |
| 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
Diffstat (limited to 'modutils')
| -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; |
