aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2001-02-24 20:01:53 +0000
committerEric Andersen <andersen@codepoet.org>2001-02-24 20:01:53 +0000
commit2bf658d5cd4460a0e0a8a8f3c8dc3b71be05d1ba (patch)
tree197b3919ea1f13ac6595f6ddb57b105be4c21333
parentafeb96547fabc8c63e883f7c24aab5638cafbd50 (diff)
downloadbusybox-w32-2bf658d5cd4460a0e0a8a8f3c8dc3b71be05d1ba.tar.gz
busybox-w32-2bf658d5cd4460a0e0a8a8f3c8dc3b71be05d1ba.tar.bz2
busybox-w32-2bf658d5cd4460a0e0a8a8f3c8dc3b71be05d1ba.zip
This patch, from Quinn Jensen <jensenq@lineo.com>, adds MIPS support
to busybox insmod. Thanks Quinn!!! -Erik
-rw-r--r--insmod.c131
-rw-r--r--modutils/insmod.c131
2 files changed, 254 insertions, 8 deletions
diff --git a/insmod.c b/insmod.c
index 7af135902..50f272edb 100644
--- a/insmod.c
+++ b/insmod.c
@@ -20,6 +20,12 @@
20 * I've only tested the code on mpc8xx platforms in big-endian mode. 20 * I've only tested the code on mpc8xx platforms in big-endian mode.
21 * Did some cleanup and added BB_USE_xxx_ENTRIES... 21 * Did some cleanup and added BB_USE_xxx_ENTRIES...
22 * 22 *
23 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
24 * based on modutils-2.4.2
25 * MIPS specific support for Elf loading and relocation.
26 * Copyright 1996, 1997 Linux International.
27 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
28 *
23 * Based almost entirely on the Linux modutils-2.3.11 implementation. 29 * Based almost entirely on the Linux modutils-2.3.11 implementation.
24 * Copyright 1996, 1997 Linux International. 30 * Copyright 1996, 1997 Linux International.
25 * New implementation contributed by Richard Henderson <rth@tamu.edu> 31 * New implementation contributed by Richard Henderson <rth@tamu.edu>
@@ -80,6 +86,10 @@
80#define BB_GOT_ENTRY_SIZE 4 86#define BB_GOT_ENTRY_SIZE 4
81#endif 87#endif
82 88
89#if defined(__mips__)
90// neither used
91#endif
92
83//---------------------------------------------------------------------------- 93//----------------------------------------------------------------------------
84//--------modutils module.h, lines 45-242 94//--------modutils module.h, lines 45-242
85//---------------------------------------------------------------------------- 95//----------------------------------------------------------------------------
@@ -109,7 +119,7 @@
109#ifndef MODUTILS_MODULE_H 119#ifndef MODUTILS_MODULE_H
110static const int MODUTILS_MODULE_H = 1; 120static const int MODUTILS_MODULE_H = 1;
111 121
112#ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" 122#ident "$Id: insmod.c,v 1.50 2001/02/24 20:01:53 andersen Exp $"
113 123
114/* This file contains the structures used by the 2.0 and 2.1 kernels. 124/* This file contains the structures used by the 2.0 and 2.1 kernels.
115 We do not use the kernel headers directly because we do not wish 125 We do not use the kernel headers directly because we do not wish
@@ -315,7 +325,7 @@ int delete_module(const char *);
315#ifndef MODUTILS_OBJ_H 325#ifndef MODUTILS_OBJ_H
316static const int MODUTILS_OBJ_H = 1; 326static const int MODUTILS_OBJ_H = 1;
317 327
318#ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" 328#ident "$Id: insmod.c,v 1.50 2001/02/24 20:01:53 andersen Exp $"
319 329
320/* The relocatable object is manipulated using elfin types. */ 330/* The relocatable object is manipulated using elfin types. */
321 331
@@ -361,6 +371,18 @@ static const int MODUTILS_OBJ_H = 1;
361#define Elf32_RelM Elf32_Rela 371#define Elf32_RelM Elf32_Rela
362#define ELFDATAM ELFDATA2MSB 372#define ELFDATAM ELFDATA2MSB
363 373
374#elif defined(__mips__)
375
376#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
377#define SHT_RELM SHT_REL
378#define Elf32_RelM Elf32_Rel
379#ifdef __MIPSEB__
380#define ELFDATAM ELFDATA2MSB
381#endif
382#ifdef __MIPSEL__
383#define ELFDATAM ELFDATA2LSB
384#endif
385
364#elif defined(__i386__) 386#elif defined(__i386__)
365 387
366/* presumably we can use these for anything but the SH and ARM*/ 388/* presumably we can use these for anything but the SH and ARM*/
@@ -594,6 +616,15 @@ struct arch_got_entry {
594}; 616};
595#endif 617#endif
596 618
619#if defined(__mips__)
620struct mips_hi16
621{
622 struct mips_hi16 *next;
623 Elf32_Addr *addr;
624 Elf32_Addr value;
625};
626#endif
627
597struct arch_file { 628struct arch_file {
598 struct obj_file root; 629 struct obj_file root;
599#if defined(BB_USE_PLT_ENTRIES) 630#if defined(BB_USE_PLT_ENTRIES)
@@ -602,6 +633,9 @@ struct arch_file {
602#if defined(BB_USE_GOT_ENTRIES) 633#if defined(BB_USE_GOT_ENTRIES)
603 struct obj_section *got; 634 struct obj_section *got;
604#endif 635#endif
636#if defined(__mips__)
637 struct mips_hi16 *mips_hi16_list;
638#endif
605}; 639};
606 640
607struct arch_symbol { 641struct arch_symbol {
@@ -724,6 +758,9 @@ struct obj_file *arch_new_file(void)
724#if defined(BB_USE_GOT_ENTRIES) 758#if defined(BB_USE_GOT_ENTRIES)
725 f->got = NULL; 759 f->got = NULL;
726#endif 760#endif
761#if defined(__mips__)
762 f->mips_hi16_list = NULL;
763#endif
727 764
728 return &f->root; 765 return &f->root;
729} 766}
@@ -783,6 +820,8 @@ arch_apply_relocation(struct obj_file *f,
783 case R_386_NONE: 820 case R_386_NONE:
784#elif defined(__powerpc__) 821#elif defined(__powerpc__)
785 case R_PPC_NONE: 822 case R_PPC_NONE:
823#elif defined(__mips__)
824 case R_MIPS_NONE:
786#endif 825#endif
787 break; 826 break;
788 827
@@ -794,6 +833,8 @@ arch_apply_relocation(struct obj_file *f,
794 case R_386_32: 833 case R_386_32:
795#elif defined(__powerpc__) 834#elif defined(__powerpc__)
796 case R_PPC_ADDR32: 835 case R_PPC_ADDR32:
836#elif defined(__mips__)
837 case R_MIPS_32:
797#endif 838#endif
798 *loc += v; 839 *loc += v;
799 break; 840 break;
@@ -812,6 +853,86 @@ arch_apply_relocation(struct obj_file *f,
812 break; 853 break;
813#endif 854#endif
814 855
856#if defined(__mips__)
857 case R_MIPS_26:
858 if (v % 4)
859 ret = obj_reloc_dangerous;
860 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
861 ret = obj_reloc_overflow;
862 *loc =
863 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
864 0x03ffffff);
865 break;
866
867 case R_MIPS_HI16:
868 {
869 struct mips_hi16 *n;
870
871 /* We cannot relocate this one now because we don't know the value
872 of the carry we need to add. Save the information, and let LO16
873 do the actual relocation. */
874 n = (struct mips_hi16 *) xmalloc(sizeof *n);
875 n->addr = loc;
876 n->value = v;
877 n->next = ifile->mips_hi16_list;
878 ifile->mips_hi16_list = n;
879 break;
880 }
881
882 case R_MIPS_LO16:
883 {
884 unsigned long insnlo = *loc;
885 Elf32_Addr val, vallo;
886
887 /* Sign extend the addend we extract from the lo insn. */
888 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
889
890 if (ifile->mips_hi16_list != NULL) {
891 struct mips_hi16 *l;
892
893 l = ifile->mips_hi16_list;
894 while (l != NULL) {
895 struct mips_hi16 *next;
896 unsigned long insn;
897
898 /* The value for the HI16 had best be the same. */
899 assert(v == l->value);
900
901 /* Do the HI16 relocation. Note that we actually don't
902 need to know anything about the LO16 itself, except where
903 to find the low 16 bits of the addend needed by the LO16. */
904 insn = *l->addr;
905 val =
906 ((insn & 0xffff) << 16) +
907 vallo;
908 val += v;
909
910 /* Account for the sign extension that will happen in the
911 low bits. */
912 val =
913 ((val >> 16) +
914 ((val & 0x8000) !=
915 0)) & 0xffff;
916
917 insn = (insn & ~0xffff) | val;
918 *l->addr = insn;
919
920 next = l->next;
921 free(l);
922 l = next;
923 }
924
925 ifile->mips_hi16_list = NULL;
926 }
927
928 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
929 val = v + vallo;
930 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
931 *loc = insnlo;
932 break;
933 }
934#endif
935
815#if defined(__arm__) 936#if defined(__arm__)
816#elif defined(__sh__) 937#elif defined(__sh__)
817 case R_SH_REL32: 938 case R_SH_REL32:
@@ -977,6 +1098,7 @@ arch_apply_relocation(struct obj_file *f,
977 1098
978int arch_create_got(struct obj_file *f) 1099int arch_create_got(struct obj_file *f)
979{ 1100{
1101#if defined(BB_USE_GOT_ENTRIES) || defined(BB_USE_PLT_ENTRIES)
980 struct arch_file *ifile = (struct arch_file *) f; 1102 struct arch_file *ifile = (struct arch_file *) f;
981 int i; 1103 int i;
982#if defined(BB_USE_GOT_ENTRIES) 1104#if defined(BB_USE_GOT_ENTRIES)
@@ -1098,6 +1220,7 @@ int arch_create_got(struct obj_file *f)
1098 BB_PLT_ENTRY_SIZE, 1220 BB_PLT_ENTRY_SIZE,
1099 plt_offset); 1221 plt_offset);
1100#endif 1222#endif
1223#endif
1101 return 1; 1224 return 1;
1102} 1225}
1103 1226
@@ -2772,7 +2895,7 @@ int obj_create_image(struct obj_file *f, char *image)
2772 for (sec = f->load_order; sec; sec = sec->load_next) { 2895 for (sec = f->load_order; sec; sec = sec->load_next) {
2773 char *secimg; 2896 char *secimg;
2774 2897
2775 if (sec->header.sh_size == 0) 2898 if (sec->contents == 0 || sec->header.sh_size == 0)
2776 continue; 2899 continue;
2777 2900
2778 secimg = image + (sec->header.sh_addr - base); 2901 secimg = image + (sec->header.sh_addr - base);
@@ -2857,7 +2980,7 @@ struct obj_file *obj_load(FILE * fp)
2857 sec->header = section_headers[i]; 2980 sec->header = section_headers[i];
2858 sec->idx = i; 2981 sec->idx = i;
2859 2982
2860 switch (sec->header.sh_type) { 2983 if(sec->header.sh_size) switch (sec->header.sh_type) {
2861 case SHT_NULL: 2984 case SHT_NULL:
2862 case SHT_NOTE: 2985 case SHT_NOTE:
2863 case SHT_NOBITS: 2986 case SHT_NOBITS:
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 7af135902..50f272edb 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -20,6 +20,12 @@
20 * I've only tested the code on mpc8xx platforms in big-endian mode. 20 * I've only tested the code on mpc8xx platforms in big-endian mode.
21 * Did some cleanup and added BB_USE_xxx_ENTRIES... 21 * Did some cleanup and added BB_USE_xxx_ENTRIES...
22 * 22 *
23 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001.
24 * based on modutils-2.4.2
25 * MIPS specific support for Elf loading and relocation.
26 * Copyright 1996, 1997 Linux International.
27 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu>
28 *
23 * Based almost entirely on the Linux modutils-2.3.11 implementation. 29 * Based almost entirely on the Linux modutils-2.3.11 implementation.
24 * Copyright 1996, 1997 Linux International. 30 * Copyright 1996, 1997 Linux International.
25 * New implementation contributed by Richard Henderson <rth@tamu.edu> 31 * New implementation contributed by Richard Henderson <rth@tamu.edu>
@@ -80,6 +86,10 @@
80#define BB_GOT_ENTRY_SIZE 4 86#define BB_GOT_ENTRY_SIZE 4
81#endif 87#endif
82 88
89#if defined(__mips__)
90// neither used
91#endif
92
83//---------------------------------------------------------------------------- 93//----------------------------------------------------------------------------
84//--------modutils module.h, lines 45-242 94//--------modutils module.h, lines 45-242
85//---------------------------------------------------------------------------- 95//----------------------------------------------------------------------------
@@ -109,7 +119,7 @@
109#ifndef MODUTILS_MODULE_H 119#ifndef MODUTILS_MODULE_H
110static const int MODUTILS_MODULE_H = 1; 120static const int MODUTILS_MODULE_H = 1;
111 121
112#ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" 122#ident "$Id: insmod.c,v 1.50 2001/02/24 20:01:53 andersen Exp $"
113 123
114/* This file contains the structures used by the 2.0 and 2.1 kernels. 124/* This file contains the structures used by the 2.0 and 2.1 kernels.
115 We do not use the kernel headers directly because we do not wish 125 We do not use the kernel headers directly because we do not wish
@@ -315,7 +325,7 @@ int delete_module(const char *);
315#ifndef MODUTILS_OBJ_H 325#ifndef MODUTILS_OBJ_H
316static const int MODUTILS_OBJ_H = 1; 326static const int MODUTILS_OBJ_H = 1;
317 327
318#ident "$Id: insmod.c,v 1.49 2001/02/20 20:47:08 andersen Exp $" 328#ident "$Id: insmod.c,v 1.50 2001/02/24 20:01:53 andersen Exp $"
319 329
320/* The relocatable object is manipulated using elfin types. */ 330/* The relocatable object is manipulated using elfin types. */
321 331
@@ -361,6 +371,18 @@ static const int MODUTILS_OBJ_H = 1;
361#define Elf32_RelM Elf32_Rela 371#define Elf32_RelM Elf32_Rela
362#define ELFDATAM ELFDATA2MSB 372#define ELFDATAM ELFDATA2MSB
363 373
374#elif defined(__mips__)
375
376#define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE)
377#define SHT_RELM SHT_REL
378#define Elf32_RelM Elf32_Rel
379#ifdef __MIPSEB__
380#define ELFDATAM ELFDATA2MSB
381#endif
382#ifdef __MIPSEL__
383#define ELFDATAM ELFDATA2LSB
384#endif
385
364#elif defined(__i386__) 386#elif defined(__i386__)
365 387
366/* presumably we can use these for anything but the SH and ARM*/ 388/* presumably we can use these for anything but the SH and ARM*/
@@ -594,6 +616,15 @@ struct arch_got_entry {
594}; 616};
595#endif 617#endif
596 618
619#if defined(__mips__)
620struct mips_hi16
621{
622 struct mips_hi16 *next;
623 Elf32_Addr *addr;
624 Elf32_Addr value;
625};
626#endif
627
597struct arch_file { 628struct arch_file {
598 struct obj_file root; 629 struct obj_file root;
599#if defined(BB_USE_PLT_ENTRIES) 630#if defined(BB_USE_PLT_ENTRIES)
@@ -602,6 +633,9 @@ struct arch_file {
602#if defined(BB_USE_GOT_ENTRIES) 633#if defined(BB_USE_GOT_ENTRIES)
603 struct obj_section *got; 634 struct obj_section *got;
604#endif 635#endif
636#if defined(__mips__)
637 struct mips_hi16 *mips_hi16_list;
638#endif
605}; 639};
606 640
607struct arch_symbol { 641struct arch_symbol {
@@ -724,6 +758,9 @@ struct obj_file *arch_new_file(void)
724#if defined(BB_USE_GOT_ENTRIES) 758#if defined(BB_USE_GOT_ENTRIES)
725 f->got = NULL; 759 f->got = NULL;
726#endif 760#endif
761#if defined(__mips__)
762 f->mips_hi16_list = NULL;
763#endif
727 764
728 return &f->root; 765 return &f->root;
729} 766}
@@ -783,6 +820,8 @@ arch_apply_relocation(struct obj_file *f,
783 case R_386_NONE: 820 case R_386_NONE:
784#elif defined(__powerpc__) 821#elif defined(__powerpc__)
785 case R_PPC_NONE: 822 case R_PPC_NONE:
823#elif defined(__mips__)
824 case R_MIPS_NONE:
786#endif 825#endif
787 break; 826 break;
788 827
@@ -794,6 +833,8 @@ arch_apply_relocation(struct obj_file *f,
794 case R_386_32: 833 case R_386_32:
795#elif defined(__powerpc__) 834#elif defined(__powerpc__)
796 case R_PPC_ADDR32: 835 case R_PPC_ADDR32:
836#elif defined(__mips__)
837 case R_MIPS_32:
797#endif 838#endif
798 *loc += v; 839 *loc += v;
799 break; 840 break;
@@ -812,6 +853,86 @@ arch_apply_relocation(struct obj_file *f,
812 break; 853 break;
813#endif 854#endif
814 855
856#if defined(__mips__)
857 case R_MIPS_26:
858 if (v % 4)
859 ret = obj_reloc_dangerous;
860 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))
861 ret = obj_reloc_overflow;
862 *loc =
863 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &
864 0x03ffffff);
865 break;
866
867 case R_MIPS_HI16:
868 {
869 struct mips_hi16 *n;
870
871 /* We cannot relocate this one now because we don't know the value
872 of the carry we need to add. Save the information, and let LO16
873 do the actual relocation. */
874 n = (struct mips_hi16 *) xmalloc(sizeof *n);
875 n->addr = loc;
876 n->value = v;
877 n->next = ifile->mips_hi16_list;
878 ifile->mips_hi16_list = n;
879 break;
880 }
881
882 case R_MIPS_LO16:
883 {
884 unsigned long insnlo = *loc;
885 Elf32_Addr val, vallo;
886
887 /* Sign extend the addend we extract from the lo insn. */
888 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;
889
890 if (ifile->mips_hi16_list != NULL) {
891 struct mips_hi16 *l;
892
893 l = ifile->mips_hi16_list;
894 while (l != NULL) {
895 struct mips_hi16 *next;
896 unsigned long insn;
897
898 /* The value for the HI16 had best be the same. */
899 assert(v == l->value);
900
901 /* Do the HI16 relocation. Note that we actually don't
902 need to know anything about the LO16 itself, except where
903 to find the low 16 bits of the addend needed by the LO16. */
904 insn = *l->addr;
905 val =
906 ((insn & 0xffff) << 16) +
907 vallo;
908 val += v;
909
910 /* Account for the sign extension that will happen in the
911 low bits. */
912 val =
913 ((val >> 16) +
914 ((val & 0x8000) !=
915 0)) & 0xffff;
916
917 insn = (insn & ~0xffff) | val;
918 *l->addr = insn;
919
920 next = l->next;
921 free(l);
922 l = next;
923 }
924
925 ifile->mips_hi16_list = NULL;
926 }
927
928 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */
929 val = v + vallo;
930 insnlo = (insnlo & ~0xffff) | (val & 0xffff);
931 *loc = insnlo;
932 break;
933 }
934#endif
935
815#if defined(__arm__) 936#if defined(__arm__)
816#elif defined(__sh__) 937#elif defined(__sh__)
817 case R_SH_REL32: 938 case R_SH_REL32:
@@ -977,6 +1098,7 @@ arch_apply_relocation(struct obj_file *f,
977 1098
978int arch_create_got(struct obj_file *f) 1099int arch_create_got(struct obj_file *f)
979{ 1100{
1101#if defined(BB_USE_GOT_ENTRIES) || defined(BB_USE_PLT_ENTRIES)
980 struct arch_file *ifile = (struct arch_file *) f; 1102 struct arch_file *ifile = (struct arch_file *) f;
981 int i; 1103 int i;
982#if defined(BB_USE_GOT_ENTRIES) 1104#if defined(BB_USE_GOT_ENTRIES)
@@ -1098,6 +1220,7 @@ int arch_create_got(struct obj_file *f)
1098 BB_PLT_ENTRY_SIZE, 1220 BB_PLT_ENTRY_SIZE,
1099 plt_offset); 1221 plt_offset);
1100#endif 1222#endif
1223#endif
1101 return 1; 1224 return 1;
1102} 1225}
1103 1226
@@ -2772,7 +2895,7 @@ int obj_create_image(struct obj_file *f, char *image)
2772 for (sec = f->load_order; sec; sec = sec->load_next) { 2895 for (sec = f->load_order; sec; sec = sec->load_next) {
2773 char *secimg; 2896 char *secimg;
2774 2897
2775 if (sec->header.sh_size == 0) 2898 if (sec->contents == 0 || sec->header.sh_size == 0)
2776 continue; 2899 continue;
2777 2900
2778 secimg = image + (sec->header.sh_addr - base); 2901 secimg = image + (sec->header.sh_addr - base);
@@ -2857,7 +2980,7 @@ struct obj_file *obj_load(FILE * fp)
2857 sec->header = section_headers[i]; 2980 sec->header = section_headers[i];
2858 sec->idx = i; 2981 sec->idx = i;
2859 2982
2860 switch (sec->header.sh_type) { 2983 if(sec->header.sh_size) switch (sec->header.sh_type) {
2861 case SHT_NULL: 2984 case SHT_NULL:
2862 case SHT_NOTE: 2985 case SHT_NOTE:
2863 case SHT_NOBITS: 2986 case SHT_NOBITS: