aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-09-24 03:44:29 +0000
committerEric Andersen <andersen@codepoet.org>2000-09-24 03:44:29 +0000
commitfe4208fe93523a464dbc3094a914a2923e66bd3e (patch)
tree56e4ec25687b69b34f6f97901fbf7d11773df30e
parent488aac2e2aac229bceb8655ff7c302cda59f1382 (diff)
downloadbusybox-w32-fe4208fe93523a464dbc3094a914a2923e66bd3e.tar.gz
busybox-w32-fe4208fe93523a464dbc3094a914a2923e66bd3e.tar.bz2
busybox-w32-fe4208fe93523a464dbc3094a914a2923e66bd3e.zip
modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
-rw-r--r--insmod.c165
-rw-r--r--modutils/insmod.c165
2 files changed, 298 insertions, 32 deletions
diff --git a/insmod.c b/insmod.c
index b0e797af7..136f9f062 100644
--- a/insmod.c
+++ b/insmod.c
@@ -6,6 +6,13 @@
6 * Written by Erik Andersen <andersen@lineo.com> 6 * Written by Erik Andersen <andersen@lineo.com>
7 * and Ron Alder <alder@lineo.com> 7 * and Ron Alder <alder@lineo.com>
8 * 8 *
9 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10 * and (theoretically) SH3. Note that there is still no true
11 * multiple architecture support. You just get SH3|SH4|i386, despite
12 * the mention of ARM and m68k--which may or may not work (but
13 * almost certainly do not, due to at least MATCH_MACHINE). I have
14 * only tested SH4 in little endian mode.
15 *
9 * Based almost entirely on the Linux modutils-2.3.11 implementation. 16 * Based almost entirely on the Linux modutils-2.3.11 implementation.
10 * Copyright 1996, 1997 Linux International. 17 * Copyright 1996, 1997 Linux International.
11 * New implementation contributed by Richard Henderson <rth@tamu.edu> 18 * New implementation contributed by Richard Henderson <rth@tamu.edu>
@@ -70,7 +77,7 @@
70#ifndef MODUTILS_MODULE_H 77#ifndef MODUTILS_MODULE_H
71#define MODUTILS_MODULE_H 1 78#define MODUTILS_MODULE_H 1
72 79
73#ident "$Id: insmod.c,v 1.23 2000/09/22 00:38:07 andersen Exp $" 80#ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
74 81
75/* This file contains the structures used by the 2.0 and 2.1 kernels. 82/* This file contains the structures used by the 2.0 and 2.1 kernels.
76 We do not use the kernel headers directly because we do not wish 83 We do not use the kernel headers directly because we do not wish
@@ -276,7 +283,7 @@ int delete_module(const char *);
276#ifndef MODUTILS_OBJ_H 283#ifndef MODUTILS_OBJ_H
277#define MODUTILS_OBJ_H 1 284#define MODUTILS_OBJ_H 1
278 285
279#ident "$Id: insmod.c,v 1.23 2000/09/22 00:38:07 andersen Exp $" 286#ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
280 287
281/* The relocatable object is manipulated using elfin types. */ 288/* The relocatable object is manipulated using elfin types. */
282 289
@@ -286,14 +293,41 @@ int delete_module(const char *);
286 293
287/* Machine-specific elf macros for i386 et al. */ 294/* Machine-specific elf macros for i386 et al. */
288 295
296/* the SH changes have only been tested on the SH4 in =little endian= mode */
297/* I'm not sure about big endian, so let's warn: */
298
299#if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
300#error insmod.c may require changes for use on big endian SH4/SH3
301#endif
302
303/* it may or may not work on the SH1/SH2... So let's error on those
304 also */
305#if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
306#error insmod.c may require changes for non-SH3/SH4 use
307#endif
308
289#define ELFCLASSM ELFCLASS32 309#define ELFCLASSM ELFCLASS32
290#define ELFDATAM ELFDATA2LSB 310#define ELFDATAM ELFDATA2LSB
291 311
292#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
293 312
313
314#if defined(__sh__)
315
316#define MATCH_MACHINE(x) (x == EM_SH)
317#define SHT_RELM SHT_RELA
318#define Elf32_RelM Elf32_Rela
319
320#else
321
322/* presumably we can use these for anything but the SH */
323/* this is the previous behavior, but it does result in
324 insmod.c being broken on anything except i386 */
325
326#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
294#define SHT_RELM SHT_REL 327#define SHT_RELM SHT_REL
295#define Elf32_RelM Elf32_Rel 328#define Elf32_RelM Elf32_Rel
296 329
330#endif
297 331
298#ifndef ElfW 332#ifndef ElfW
299# if ELFCLASSM == ELFCLASS32 333# if ELFCLASSM == ELFCLASS32
@@ -486,24 +520,29 @@ int flag_export = 1;
486 520
487/*======================================================================*/ 521/*======================================================================*/
488 522
489struct i386_got_entry { 523/* previously, these were named i386_* but since we could be
524 compiling for the sh, I've renamed them to the more general
525 arch_* These structures are the same between the x86 and SH,
526 and we can't support anything else right now anyway. In the
527 future maybe they should be #if defined'd */
528
529struct arch_got_entry {
490 int offset; 530 int offset;
491 unsigned offset_done:1; 531 unsigned offset_done:1;
492 unsigned reloc_done:1; 532 unsigned reloc_done:1;
493}; 533};
494 534
495struct i386_file { 535struct arch_file {
496 struct obj_file root; 536 struct obj_file root;
497 struct obj_section *got; 537 struct obj_section *got;
498}; 538};
499 539
500struct i386_symbol { 540struct arch_symbol {
501 struct obj_symbol root; 541 struct obj_symbol root;
502 struct i386_got_entry gotent; 542 struct arch_got_entry gotent;
503}; 543};
504 544
505 545
506
507struct external_module { 546struct external_module {
508 const char *name; 547 const char *name;
509 ElfW(Addr) addr; 548 ElfW(Addr) addr;
@@ -535,6 +574,17 @@ _syscall1(int, delete_module, const char *, name)
535extern int delete_module(const char *); 574extern int delete_module(const char *);
536#endif 575#endif
537 576
577/* This is kind of troublesome. See, we don't actually support
578 the m68k or the arm the same way we support i386 and (now)
579 sh. In doing my SH patch, I just assumed that whatever works
580 for i386 also works for m68k and arm since currently insmod.c
581 does nothing special for them. If this isn't true, the below
582 line is rather misleading IMHO, and someone should either
583 change it or add more proper architecture-dependent support
584 for these boys.
585
586 -- Bryan Rittmeyer <bryan@ixiacom.com> */
587
538#if defined(__i386__) || defined(__m68k__) || defined(__arm__) 588#if defined(__i386__) || defined(__m68k__) || defined(__arm__)
539/* Jump through hoops to fixup error return codes */ 589/* Jump through hoops to fixup error return codes */
540#define __NR__create_module __NR_create_module 590#define __NR__create_module __NR_create_module
@@ -588,7 +638,7 @@ static int findNamedModule(const char *fileName, struct stat *statbuf,
588 638
589struct obj_file *arch_new_file(void) 639struct obj_file *arch_new_file(void)
590{ 640{
591 struct i386_file *f; 641 struct arch_file *f;
592 f = xmalloc(sizeof(*f)); 642 f = xmalloc(sizeof(*f));
593 f->got = NULL; 643 f->got = NULL;
594 return &f->root; 644 return &f->root;
@@ -601,20 +651,25 @@ struct obj_section *arch_new_section(void)
601 651
602struct obj_symbol *arch_new_symbol(void) 652struct obj_symbol *arch_new_symbol(void)
603{ 653{
604 struct i386_symbol *sym; 654 struct arch_symbol *sym;
605 sym = xmalloc(sizeof(*sym)); 655 sym = xmalloc(sizeof(*sym));
606 memset(&sym->gotent, 0, sizeof(sym->gotent)); 656 memset(&sym->gotent, 0, sizeof(sym->gotent));
607 return &sym->root; 657 return &sym->root;
608} 658}
659
609enum obj_reloc 660enum obj_reloc
610arch_apply_relocation(struct obj_file *f, 661arch_apply_relocation(struct obj_file *f,
611 struct obj_section *targsec, 662 struct obj_section *targsec,
612 struct obj_section *symsec, 663 struct obj_section *symsec,
613 struct obj_symbol *sym, 664 struct obj_symbol *sym,
665#if defined(__sh__)
666 Elf32_Rela * rel, Elf32_Addr v)
667#else
614 Elf32_Rel * rel, Elf32_Addr v) 668 Elf32_Rel * rel, Elf32_Addr v)
669#endif
615{ 670{
616 struct i386_file *ifile = (struct i386_file *) f; 671 struct arch_file *ifile = (struct arch_file *) f;
617 struct i386_symbol *isym = (struct i386_symbol *) sym; 672 struct arch_symbol *isym = (struct arch_symbol *) sym;
618 673
619 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset); 674 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset);
620 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; 675 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
@@ -623,32 +678,86 @@ arch_apply_relocation(struct obj_file *f,
623 enum obj_reloc ret = obj_reloc_ok; 678 enum obj_reloc ret = obj_reloc_ok;
624 679
625 switch (ELF32_R_TYPE(rel->r_info)) { 680 switch (ELF32_R_TYPE(rel->r_info)) {
681
682/* even though these constants seem to be the same for
683 the i386 and the sh, we "#if define" them for clarity
684 and in case that ever changes */
685#if defined(__sh__)
686 case R_SH_NONE:
687#else
626 case R_386_NONE: 688 case R_386_NONE:
689#endif
627 break; 690 break;
628 691
692#if defined(__sh__)
693 case R_SH_DIR32:
694#else
629 case R_386_32: 695 case R_386_32:
696#endif
630 *loc += v; 697 *loc += v;
631 break; 698 break;
632 699
700#if defined(__sh__)
701 case R_SH_REL32:
702#else
633 case R_386_PLT32: 703 case R_386_PLT32:
634 case R_386_PC32: 704 case R_386_PC32:
705#endif
635 *loc += v - dot; 706 *loc += v - dot;
636 break; 707 break;
637 708
709#if defined(__sh__)
710 case R_SH_PLT32:
711 *loc = v - dot;
712 break;
713#endif
714
715
716#if defined(__sh__)
717 case R_SH_GLOB_DAT:
718 case R_SH_JMP_SLOT:
719 *loc = v;
720 break;
721#else
638 case R_386_GLOB_DAT: 722 case R_386_GLOB_DAT:
639 case R_386_JMP_SLOT: 723 case R_386_JMP_SLOT:
640 *loc = v; 724 *loc = v;
641 break; 725 break;
726#endif
642 727
643 case R_386_RELATIVE: 728#if defined(__sh__)
729 case R_SH_RELATIVE:
730 *loc += f->baseaddr + rel->r_addend;
731 break;
732#else
733 case R_386_RELATIVE:
644 *loc += f->baseaddr; 734 *loc += f->baseaddr;
645 break; 735 break;
736#endif
646 737
738#if defined(__sh__)
739 case R_SH_GOTPC:
740 assert(got != 0);
741 *loc += got - dot + rel->r_addend;;
742 break;
743#else
647 case R_386_GOTPC: 744 case R_386_GOTPC:
648 assert(got != 0); 745 assert(got != 0);
649 *loc += got - dot; 746 *loc += got - dot;
650 break; 747 break;
748#endif
651 749
750#if defined(__sh__)
751 case R_SH_GOT32:
752 assert(isym != NULL);
753 if (!isym->gotent.reloc_done) {
754 isym->gotent.reloc_done = 1;
755 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
756 v;
757 }
758 *loc += isym->gotent.offset + rel->r_addend;
759 break;
760#else
652 case R_386_GOT32: 761 case R_386_GOT32:
653 assert(isym != NULL); 762 assert(isym != NULL);
654 if (!isym->gotent.reloc_done) { 763 if (!isym->gotent.reloc_done) {
@@ -658,8 +767,13 @@ arch_apply_relocation(struct obj_file *f,
658 } 767 }
659 *loc += isym->gotent.offset; 768 *loc += isym->gotent.offset;
660 break; 769 break;
770#endif
661 771
772#if defined(__sh__)
773 case R_SH_GOTOFF:
774#else
662 case R_386_GOTOFF: 775 case R_386_GOTOFF:
776#endif
663 assert(got != 0); 777 assert(got != 0);
664 *loc += v - got; 778 *loc += v - got;
665 break; 779 break;
@@ -674,13 +788,17 @@ arch_apply_relocation(struct obj_file *f,
674 788
675int arch_create_got(struct obj_file *f) 789int arch_create_got(struct obj_file *f)
676{ 790{
677 struct i386_file *ifile = (struct i386_file *) f; 791 struct arch_file *ifile = (struct arch_file *) f;
678 int i, n, offset = 0, gotneeded = 0; 792 int i, n, offset = 0, gotneeded = 0;
679 793
680 n = ifile->root.header.e_shnum; 794 n = ifile->root.header.e_shnum;
681 for (i = 0; i < n; ++i) { 795 for (i = 0; i < n; ++i) {
682 struct obj_section *relsec, *symsec, *strsec; 796 struct obj_section *relsec, *symsec, *strsec;
797#if defined(__sh__)
798 Elf32_Rela *rel, *relend;
799#else
683 Elf32_Rel *rel, *relend; 800 Elf32_Rel *rel, *relend;
801#endif
684 Elf32_Sym *symtab; 802 Elf32_Sym *symtab;
685 const char *strtab; 803 const char *strtab;
686 804
@@ -691,24 +809,39 @@ int arch_create_got(struct obj_file *f)
691 symsec = ifile->root.sections[relsec->header.sh_link]; 809 symsec = ifile->root.sections[relsec->header.sh_link];
692 strsec = ifile->root.sections[symsec->header.sh_link]; 810 strsec = ifile->root.sections[symsec->header.sh_link];
693 811
812
813#if defined(__sh__)
814 rel = (Elf32_Rela *) relsec->contents;
815 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela));
816#else
694 rel = (Elf32_Rel *) relsec->contents; 817 rel = (Elf32_Rel *) relsec->contents;
695 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); 818 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
819#endif
696 symtab = (Elf32_Sym *) symsec->contents; 820 symtab = (Elf32_Sym *) symsec->contents;
697 strtab = (const char *) strsec->contents; 821 strtab = (const char *) strsec->contents;
698 822
699 for (; rel < relend; ++rel) { 823 for (; rel < relend; ++rel) {
700 Elf32_Sym *extsym; 824 Elf32_Sym *extsym;
701 struct i386_symbol *intsym; 825 struct arch_symbol *intsym;
702 const char *name; 826 const char *name;
703 827
704 switch (ELF32_R_TYPE(rel->r_info)) { 828 switch (ELF32_R_TYPE(rel->r_info)) {
829#if defined(__sh__)
830 case R_SH_GOTPC:
831 case R_SH_GOTOFF:
832#else
705 case R_386_GOTPC: 833 case R_386_GOTPC:
706 case R_386_GOTOFF: 834 case R_386_GOTOFF:
835#endif
707 gotneeded = 1; 836 gotneeded = 1;
708 default: 837 default:
709 continue; 838 continue;
710 839
840#if defined(__sh__)
841 case R_SH_GOT32:
842#else
711 case R_386_GOT32: 843 case R_386_GOT32:
844#endif
712 break; 845 break;
713 } 846 }
714 847
@@ -718,7 +851,7 @@ int arch_create_got(struct obj_file *f)
718 else 851 else
719 name = f->sections[extsym->st_shndx]->name; 852 name = f->sections[extsym->st_shndx]->name;
720 intsym = 853 intsym =
721 (struct i386_symbol *) obj_find_symbol(&ifile->root, name); 854 (struct arch_symbol *) obj_find_symbol(&ifile->root, name);
722 855
723 if (!intsym->gotent.offset_done) { 856 if (!intsym->gotent.offset_done) {
724 intsym->gotent.offset_done = 1; 857 intsym->gotent.offset_done = 1;
diff --git a/modutils/insmod.c b/modutils/insmod.c
index b0e797af7..136f9f062 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -6,6 +6,13 @@
6 * Written by Erik Andersen <andersen@lineo.com> 6 * Written by Erik Andersen <andersen@lineo.com>
7 * and Ron Alder <alder@lineo.com> 7 * and Ron Alder <alder@lineo.com>
8 * 8 *
9 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10 * and (theoretically) SH3. Note that there is still no true
11 * multiple architecture support. You just get SH3|SH4|i386, despite
12 * the mention of ARM and m68k--which may or may not work (but
13 * almost certainly do not, due to at least MATCH_MACHINE). I have
14 * only tested SH4 in little endian mode.
15 *
9 * Based almost entirely on the Linux modutils-2.3.11 implementation. 16 * Based almost entirely on the Linux modutils-2.3.11 implementation.
10 * Copyright 1996, 1997 Linux International. 17 * Copyright 1996, 1997 Linux International.
11 * New implementation contributed by Richard Henderson <rth@tamu.edu> 18 * New implementation contributed by Richard Henderson <rth@tamu.edu>
@@ -70,7 +77,7 @@
70#ifndef MODUTILS_MODULE_H 77#ifndef MODUTILS_MODULE_H
71#define MODUTILS_MODULE_H 1 78#define MODUTILS_MODULE_H 1
72 79
73#ident "$Id: insmod.c,v 1.23 2000/09/22 00:38:07 andersen Exp $" 80#ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
74 81
75/* This file contains the structures used by the 2.0 and 2.1 kernels. 82/* This file contains the structures used by the 2.0 and 2.1 kernels.
76 We do not use the kernel headers directly because we do not wish 83 We do not use the kernel headers directly because we do not wish
@@ -276,7 +283,7 @@ int delete_module(const char *);
276#ifndef MODUTILS_OBJ_H 283#ifndef MODUTILS_OBJ_H
277#define MODUTILS_OBJ_H 1 284#define MODUTILS_OBJ_H 1
278 285
279#ident "$Id: insmod.c,v 1.23 2000/09/22 00:38:07 andersen Exp $" 286#ident "$Id: insmod.c,v 1.24 2000/09/24 03:44:29 andersen Exp $"
280 287
281/* The relocatable object is manipulated using elfin types. */ 288/* The relocatable object is manipulated using elfin types. */
282 289
@@ -286,14 +293,41 @@ int delete_module(const char *);
286 293
287/* Machine-specific elf macros for i386 et al. */ 294/* Machine-specific elf macros for i386 et al. */
288 295
296/* the SH changes have only been tested on the SH4 in =little endian= mode */
297/* I'm not sure about big endian, so let's warn: */
298
299#if (defined(__SH4__) || defined(__SH3__)) && defined(__BIG_ENDIAN__)
300#error insmod.c may require changes for use on big endian SH4/SH3
301#endif
302
303/* it may or may not work on the SH1/SH2... So let's error on those
304 also */
305#if (defined(__sh__) && (!(defined(__SH3__) || defined(__SH4__))))
306#error insmod.c may require changes for non-SH3/SH4 use
307#endif
308
289#define ELFCLASSM ELFCLASS32 309#define ELFCLASSM ELFCLASS32
290#define ELFDATAM ELFDATA2LSB 310#define ELFDATAM ELFDATA2LSB
291 311
292#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
293 312
313
314#if defined(__sh__)
315
316#define MATCH_MACHINE(x) (x == EM_SH)
317#define SHT_RELM SHT_RELA
318#define Elf32_RelM Elf32_Rela
319
320#else
321
322/* presumably we can use these for anything but the SH */
323/* this is the previous behavior, but it does result in
324 insmod.c being broken on anything except i386 */
325
326#define MATCH_MACHINE(x) (x == EM_386 || x == EM_486)
294#define SHT_RELM SHT_REL 327#define SHT_RELM SHT_REL
295#define Elf32_RelM Elf32_Rel 328#define Elf32_RelM Elf32_Rel
296 329
330#endif
297 331
298#ifndef ElfW 332#ifndef ElfW
299# if ELFCLASSM == ELFCLASS32 333# if ELFCLASSM == ELFCLASS32
@@ -486,24 +520,29 @@ int flag_export = 1;
486 520
487/*======================================================================*/ 521/*======================================================================*/
488 522
489struct i386_got_entry { 523/* previously, these were named i386_* but since we could be
524 compiling for the sh, I've renamed them to the more general
525 arch_* These structures are the same between the x86 and SH,
526 and we can't support anything else right now anyway. In the
527 future maybe they should be #if defined'd */
528
529struct arch_got_entry {
490 int offset; 530 int offset;
491 unsigned offset_done:1; 531 unsigned offset_done:1;
492 unsigned reloc_done:1; 532 unsigned reloc_done:1;
493}; 533};
494 534
495struct i386_file { 535struct arch_file {
496 struct obj_file root; 536 struct obj_file root;
497 struct obj_section *got; 537 struct obj_section *got;
498}; 538};
499 539
500struct i386_symbol { 540struct arch_symbol {
501 struct obj_symbol root; 541 struct obj_symbol root;
502 struct i386_got_entry gotent; 542 struct arch_got_entry gotent;
503}; 543};
504 544
505 545
506
507struct external_module { 546struct external_module {
508 const char *name; 547 const char *name;
509 ElfW(Addr) addr; 548 ElfW(Addr) addr;
@@ -535,6 +574,17 @@ _syscall1(int, delete_module, const char *, name)
535extern int delete_module(const char *); 574extern int delete_module(const char *);
536#endif 575#endif
537 576
577/* This is kind of troublesome. See, we don't actually support
578 the m68k or the arm the same way we support i386 and (now)
579 sh. In doing my SH patch, I just assumed that whatever works
580 for i386 also works for m68k and arm since currently insmod.c
581 does nothing special for them. If this isn't true, the below
582 line is rather misleading IMHO, and someone should either
583 change it or add more proper architecture-dependent support
584 for these boys.
585
586 -- Bryan Rittmeyer <bryan@ixiacom.com> */
587
538#if defined(__i386__) || defined(__m68k__) || defined(__arm__) 588#if defined(__i386__) || defined(__m68k__) || defined(__arm__)
539/* Jump through hoops to fixup error return codes */ 589/* Jump through hoops to fixup error return codes */
540#define __NR__create_module __NR_create_module 590#define __NR__create_module __NR_create_module
@@ -588,7 +638,7 @@ static int findNamedModule(const char *fileName, struct stat *statbuf,
588 638
589struct obj_file *arch_new_file(void) 639struct obj_file *arch_new_file(void)
590{ 640{
591 struct i386_file *f; 641 struct arch_file *f;
592 f = xmalloc(sizeof(*f)); 642 f = xmalloc(sizeof(*f));
593 f->got = NULL; 643 f->got = NULL;
594 return &f->root; 644 return &f->root;
@@ -601,20 +651,25 @@ struct obj_section *arch_new_section(void)
601 651
602struct obj_symbol *arch_new_symbol(void) 652struct obj_symbol *arch_new_symbol(void)
603{ 653{
604 struct i386_symbol *sym; 654 struct arch_symbol *sym;
605 sym = xmalloc(sizeof(*sym)); 655 sym = xmalloc(sizeof(*sym));
606 memset(&sym->gotent, 0, sizeof(sym->gotent)); 656 memset(&sym->gotent, 0, sizeof(sym->gotent));
607 return &sym->root; 657 return &sym->root;
608} 658}
659
609enum obj_reloc 660enum obj_reloc
610arch_apply_relocation(struct obj_file *f, 661arch_apply_relocation(struct obj_file *f,
611 struct obj_section *targsec, 662 struct obj_section *targsec,
612 struct obj_section *symsec, 663 struct obj_section *symsec,
613 struct obj_symbol *sym, 664 struct obj_symbol *sym,
665#if defined(__sh__)
666 Elf32_Rela * rel, Elf32_Addr v)
667#else
614 Elf32_Rel * rel, Elf32_Addr v) 668 Elf32_Rel * rel, Elf32_Addr v)
669#endif
615{ 670{
616 struct i386_file *ifile = (struct i386_file *) f; 671 struct arch_file *ifile = (struct arch_file *) f;
617 struct i386_symbol *isym = (struct i386_symbol *) sym; 672 struct arch_symbol *isym = (struct arch_symbol *) sym;
618 673
619 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset); 674 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset);
620 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; 675 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
@@ -623,32 +678,86 @@ arch_apply_relocation(struct obj_file *f,
623 enum obj_reloc ret = obj_reloc_ok; 678 enum obj_reloc ret = obj_reloc_ok;
624 679
625 switch (ELF32_R_TYPE(rel->r_info)) { 680 switch (ELF32_R_TYPE(rel->r_info)) {
681
682/* even though these constants seem to be the same for
683 the i386 and the sh, we "#if define" them for clarity
684 and in case that ever changes */
685#if defined(__sh__)
686 case R_SH_NONE:
687#else
626 case R_386_NONE: 688 case R_386_NONE:
689#endif
627 break; 690 break;
628 691
692#if defined(__sh__)
693 case R_SH_DIR32:
694#else
629 case R_386_32: 695 case R_386_32:
696#endif
630 *loc += v; 697 *loc += v;
631 break; 698 break;
632 699
700#if defined(__sh__)
701 case R_SH_REL32:
702#else
633 case R_386_PLT32: 703 case R_386_PLT32:
634 case R_386_PC32: 704 case R_386_PC32:
705#endif
635 *loc += v - dot; 706 *loc += v - dot;
636 break; 707 break;
637 708
709#if defined(__sh__)
710 case R_SH_PLT32:
711 *loc = v - dot;
712 break;
713#endif
714
715
716#if defined(__sh__)
717 case R_SH_GLOB_DAT:
718 case R_SH_JMP_SLOT:
719 *loc = v;
720 break;
721#else
638 case R_386_GLOB_DAT: 722 case R_386_GLOB_DAT:
639 case R_386_JMP_SLOT: 723 case R_386_JMP_SLOT:
640 *loc = v; 724 *loc = v;
641 break; 725 break;
726#endif
642 727
643 case R_386_RELATIVE: 728#if defined(__sh__)
729 case R_SH_RELATIVE:
730 *loc += f->baseaddr + rel->r_addend;
731 break;
732#else
733 case R_386_RELATIVE:
644 *loc += f->baseaddr; 734 *loc += f->baseaddr;
645 break; 735 break;
736#endif
646 737
738#if defined(__sh__)
739 case R_SH_GOTPC:
740 assert(got != 0);
741 *loc += got - dot + rel->r_addend;;
742 break;
743#else
647 case R_386_GOTPC: 744 case R_386_GOTPC:
648 assert(got != 0); 745 assert(got != 0);
649 *loc += got - dot; 746 *loc += got - dot;
650 break; 747 break;
748#endif
651 749
750#if defined(__sh__)
751 case R_SH_GOT32:
752 assert(isym != NULL);
753 if (!isym->gotent.reloc_done) {
754 isym->gotent.reloc_done = 1;
755 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
756 v;
757 }
758 *loc += isym->gotent.offset + rel->r_addend;
759 break;
760#else
652 case R_386_GOT32: 761 case R_386_GOT32:
653 assert(isym != NULL); 762 assert(isym != NULL);
654 if (!isym->gotent.reloc_done) { 763 if (!isym->gotent.reloc_done) {
@@ -658,8 +767,13 @@ arch_apply_relocation(struct obj_file *f,
658 } 767 }
659 *loc += isym->gotent.offset; 768 *loc += isym->gotent.offset;
660 break; 769 break;
770#endif
661 771
772#if defined(__sh__)
773 case R_SH_GOTOFF:
774#else
662 case R_386_GOTOFF: 775 case R_386_GOTOFF:
776#endif
663 assert(got != 0); 777 assert(got != 0);
664 *loc += v - got; 778 *loc += v - got;
665 break; 779 break;
@@ -674,13 +788,17 @@ arch_apply_relocation(struct obj_file *f,
674 788
675int arch_create_got(struct obj_file *f) 789int arch_create_got(struct obj_file *f)
676{ 790{
677 struct i386_file *ifile = (struct i386_file *) f; 791 struct arch_file *ifile = (struct arch_file *) f;
678 int i, n, offset = 0, gotneeded = 0; 792 int i, n, offset = 0, gotneeded = 0;
679 793
680 n = ifile->root.header.e_shnum; 794 n = ifile->root.header.e_shnum;
681 for (i = 0; i < n; ++i) { 795 for (i = 0; i < n; ++i) {
682 struct obj_section *relsec, *symsec, *strsec; 796 struct obj_section *relsec, *symsec, *strsec;
797#if defined(__sh__)
798 Elf32_Rela *rel, *relend;
799#else
683 Elf32_Rel *rel, *relend; 800 Elf32_Rel *rel, *relend;
801#endif
684 Elf32_Sym *symtab; 802 Elf32_Sym *symtab;
685 const char *strtab; 803 const char *strtab;
686 804
@@ -691,24 +809,39 @@ int arch_create_got(struct obj_file *f)
691 symsec = ifile->root.sections[relsec->header.sh_link]; 809 symsec = ifile->root.sections[relsec->header.sh_link];
692 strsec = ifile->root.sections[symsec->header.sh_link]; 810 strsec = ifile->root.sections[symsec->header.sh_link];
693 811
812
813#if defined(__sh__)
814 rel = (Elf32_Rela *) relsec->contents;
815 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela));
816#else
694 rel = (Elf32_Rel *) relsec->contents; 817 rel = (Elf32_Rel *) relsec->contents;
695 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel)); 818 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
819#endif
696 symtab = (Elf32_Sym *) symsec->contents; 820 symtab = (Elf32_Sym *) symsec->contents;
697 strtab = (const char *) strsec->contents; 821 strtab = (const char *) strsec->contents;
698 822
699 for (; rel < relend; ++rel) { 823 for (; rel < relend; ++rel) {
700 Elf32_Sym *extsym; 824 Elf32_Sym *extsym;
701 struct i386_symbol *intsym; 825 struct arch_symbol *intsym;
702 const char *name; 826 const char *name;
703 827
704 switch (ELF32_R_TYPE(rel->r_info)) { 828 switch (ELF32_R_TYPE(rel->r_info)) {
829#if defined(__sh__)
830 case R_SH_GOTPC:
831 case R_SH_GOTOFF:
832#else
705 case R_386_GOTPC: 833 case R_386_GOTPC:
706 case R_386_GOTOFF: 834 case R_386_GOTOFF:
835#endif
707 gotneeded = 1; 836 gotneeded = 1;
708 default: 837 default:
709 continue; 838 continue;
710 839
840#if defined(__sh__)
841 case R_SH_GOT32:
842#else
711 case R_386_GOT32: 843 case R_386_GOT32:
844#endif
712 break; 845 break;
713 } 846 }
714 847
@@ -718,7 +851,7 @@ int arch_create_got(struct obj_file *f)
718 else 851 else
719 name = f->sections[extsym->st_shndx]->name; 852 name = f->sections[extsym->st_shndx]->name;
720 intsym = 853 intsym =
721 (struct i386_symbol *) obj_find_symbol(&ifile->root, name); 854 (struct arch_symbol *) obj_find_symbol(&ifile->root, name);
722 855
723 if (!intsym->gotent.offset_done) { 856 if (!intsym->gotent.offset_done) {
724 intsym->gotent.offset_done = 1; 857 intsym->gotent.offset_done = 1;