aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2000-12-06 18:18:26 +0000
committerEric Andersen <andersen@codepoet.org>2000-12-06 18:18:26 +0000
commit21adca750a9a1ae47da2bd058574795089406f25 (patch)
tree6157527825001c910fa9bd2b2ce519ac212e9e50
parente884970c87b921542fb9351b7a907796a0a4de23 (diff)
downloadbusybox-w32-21adca750a9a1ae47da2bd058574795089406f25.tar.gz
busybox-w32-21adca750a9a1ae47da2bd058574795089406f25.tar.bz2
busybox-w32-21adca750a9a1ae47da2bd058574795089406f25.zip
Added insmod support for ARM, and lsmod support for older kernels,
thanks to Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and Nicolas Ferre <nicolas.ferre@alcove.fr>. -Erik
-rw-r--r--Changelog5
-rw-r--r--Config.h6
-rw-r--r--insmod.c301
-rw-r--r--lsmod.c38
-rw-r--r--modutils/insmod.c301
-rw-r--r--modutils/lsmod.c38
6 files changed, 498 insertions, 191 deletions
diff --git a/Changelog b/Changelog
index 2bcdce8a0..e1d5288dd 100644
--- a/Changelog
+++ b/Changelog
@@ -3,9 +3,12 @@
3 * Matt Kraai -- fix all usage of TRUE and FALSE so all apps now 3 * Matt Kraai -- fix all usage of TRUE and FALSE so all apps now
4 return EXIT_SUCCESS or EXIT_FAILURE to the system. 4 return EXIT_SUCCESS or EXIT_FAILURE to the system.
5 Now TRUE and FALSE are set to the C standard where TRUE=1. 5 Now TRUE and FALSE are set to the C standard where TRUE=1.
6 * Fixed uname problem causing the kernel version to be 6 * me -- Fixed uname problem causing the kernel version to be
7 mis-detected (causing problems with poweroff, init, 7 mis-detected (causing problems with poweroff, init,
8 and other things). 8 and other things).
9 * Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
10 Nicolas Ferre <nicolas.ferre@alcove.fr> -- insmod support on ARM
11 and StrongArm, and suport for lsmod on older 2.0.x kernels.
9 * Kent Robotti -- Renamed unrpm to original rpmunpack, so you can use 12 * Kent Robotti -- Renamed unrpm to original rpmunpack, so you can use
10 an included shell script called unrpm as a front end to it. There's 13 an included shell script called unrpm as a front end to it. There's
11 also a shell script called undeb included for debian packages. 14 also a shell script called undeb included for debian packages.
diff --git a/Config.h b/Config.h
index e07044690..827ff1ed0 100644
--- a/Config.h
+++ b/Config.h
@@ -260,6 +260,12 @@
260// Support installing modules from kernel versions after 2.1.18 260// Support installing modules from kernel versions after 2.1.18
261#define BB_FEATURE_INSMOD_NEW_KERNEL 261#define BB_FEATURE_INSMOD_NEW_KERNEL
262// 262//
263// You must enable one or both of these features
264// Support modules status from pre 2.1 kernels
265//#define BB_FEATURE_LSMOD_OLD_KERNEL
266// Support modules status from kernel versions after 2.1.18
267#define BB_FEATURE_LSMOD_NEW_KERNEL
268//
263// Support module version checking 269// Support module version checking
264//#define BB_FEATURE_INSMOD_VERSION_CHECKING 270//#define BB_FEATURE_INSMOD_VERSION_CHECKING
265// 271//
diff --git a/insmod.c b/insmod.c
index 6386b9407..0963225fa 100644
--- a/insmod.c
+++ b/insmod.c
@@ -7,11 +7,12 @@
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 9 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10 * and (theoretically) SH3. Note that there is still no true 10 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
11 * multiple architecture support. You just get SH3|SH4|i386, despite 11 *
12 * the mention of ARM and m68k--which may or may not work (but 12 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
13 * almost certainly do not, due to at least MATCH_MACHINE). I have 13 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
14 * only tested SH4 in little endian mode. 14 * very minor changes required to also work with StrongArm and presumably
15 * all ARM based systems.
15 * 16 *
16 * Based almost entirely on the Linux modutils-2.3.11 implementation. 17 * Based almost entirely on the Linux modutils-2.3.11 implementation.
17 * Copyright 1996, 1997 Linux International. 18 * Copyright 1996, 1997 Linux International.
@@ -77,7 +78,7 @@
77#ifndef MODUTILS_MODULE_H 78#ifndef MODUTILS_MODULE_H
78#define MODUTILS_MODULE_H 1 79#define MODUTILS_MODULE_H 1
79 80
80#ident "$Id: insmod.c,v 1.29 2000/12/01 02:55:13 kraai Exp $" 81#ident "$Id: insmod.c,v 1.30 2000/12/06 18:18:26 andersen Exp $"
81 82
82/* This file contains the structures used by the 2.0 and 2.1 kernels. 83/* This file contains the structures used by the 2.0 and 2.1 kernels.
83 We do not use the kernel headers directly because we do not wish 84 We do not use the kernel headers directly because we do not wish
@@ -283,7 +284,7 @@ int delete_module(const char *);
283#ifndef MODUTILS_OBJ_H 284#ifndef MODUTILS_OBJ_H
284#define MODUTILS_OBJ_H 1 285#define MODUTILS_OBJ_H 1
285 286
286#ident "$Id: insmod.c,v 1.29 2000/12/01 02:55:13 kraai Exp $" 287#ident "$Id: insmod.c,v 1.30 2000/12/06 18:18:26 andersen Exp $"
287 288
288/* The relocatable object is manipulated using elfin types. */ 289/* The relocatable object is manipulated using elfin types. */
289 290
@@ -317,12 +318,17 @@ int delete_module(const char *);
317#define SHT_RELM SHT_RELA 318#define SHT_RELM SHT_RELA
318#define Elf32_RelM Elf32_Rela 319#define Elf32_RelM Elf32_Rela
319 320
320#else 321#elif defined(__arm__)
321 322
322/* presumably we can use these for anything but the SH */ 323#define MATCH_MACHINE(x) (x == EM_ARM)
324#define SHT_RELM SHT_REL
325#define Elf32_RelM Elf32_Rel
326
327#elif defined(__i386__)
328
329/* presumably we can use these for anything but the SH and ARM*/
323/* this is the previous behavior, but it does result in 330/* this is the previous behavior, but it does result in
324 insmod.c being broken on anything except i386 */ 331 insmod.c being broken on anything except i386 */
325
326#ifndef EM_486 332#ifndef EM_486
327#define MATCH_MACHINE(x) (x == EM_386) 333#define MATCH_MACHINE(x) (x == EM_386)
328#else 334#else
@@ -332,6 +338,8 @@ int delete_module(const char *);
332#define SHT_RELM SHT_REL 338#define SHT_RELM SHT_REL
333#define Elf32_RelM Elf32_Rel 339#define Elf32_RelM Elf32_Rel
334 340
341#else
342#error insmod.c no platform specified
335#endif 343#endif
336 344
337#ifndef ElfW 345#ifndef ElfW
@@ -531,6 +539,17 @@ int flag_export = 1;
531 and we can't support anything else right now anyway. In the 539 and we can't support anything else right now anyway. In the
532 future maybe they should be #if defined'd */ 540 future maybe they should be #if defined'd */
533 541
542/* Done ;-) */
543
544#if defined(__arm__)
545struct arm_plt_entry
546{
547 int offset;
548 int allocated:1;
549 int inited:1; /* has been set up */
550};
551#endif
552
534struct arch_got_entry { 553struct arch_got_entry {
535 int offset; 554 int offset;
536 unsigned offset_done:1; 555 unsigned offset_done:1;
@@ -539,11 +558,17 @@ struct arch_got_entry {
539 558
540struct arch_file { 559struct arch_file {
541 struct obj_file root; 560 struct obj_file root;
561#if defined(__arm__)
562 struct obj_section *plt;
563#endif
542 struct obj_section *got; 564 struct obj_section *got;
543}; 565};
544 566
545struct arch_symbol { 567struct arch_symbol {
546 struct obj_symbol root; 568 struct obj_symbol root;
569#if defined(__arm__)
570 struct arm_plt_entry pltent;
571#endif
547 struct arch_got_entry gotent; 572 struct arch_got_entry gotent;
548}; 573};
549 574
@@ -590,6 +615,10 @@ extern int delete_module(const char *);
590 615
591 -- Bryan Rittmeyer <bryan@ixiacom.com> */ 616 -- Bryan Rittmeyer <bryan@ixiacom.com> */
592 617
618#ifdef BB_FEATURE_INSMOD_OLD_KERNEL
619_syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks)
620#endif
621
593#if defined(__i386__) || defined(__m68k__) || defined(__arm__) 622#if defined(__i386__) || defined(__m68k__) || defined(__arm__)
594/* Jump through hoops to fixup error return codes */ 623/* Jump through hoops to fixup error return codes */
595#define __NR__create_module __NR_create_module 624#define __NR__create_module __NR_create_module
@@ -623,7 +652,7 @@ static int findNamedModule(const char *fileName, struct stat *statbuf,
623 if (fullName[0] == '\0') 652 if (fullName[0] == '\0')
624 return (FALSE); 653 return (FALSE);
625 else { 654 else {
626 char *tmp = strrchr(fileName, '/'); 655 char *tmp = strrchr((char *) fileName, '/');
627 656
628 if (tmp == NULL) 657 if (tmp == NULL)
629 tmp = (char *) fileName; 658 tmp = (char *) fileName;
@@ -667,18 +696,20 @@ arch_apply_relocation(struct obj_file *f,
667 struct obj_section *targsec, 696 struct obj_section *targsec,
668 struct obj_section *symsec, 697 struct obj_section *symsec,
669 struct obj_symbol *sym, 698 struct obj_symbol *sym,
670#if defined(__sh__) 699 ElfW(RelM) *rel, ElfW(Addr) v)
671 Elf32_Rela * rel, Elf32_Addr v)
672#else
673 Elf32_Rel * rel, Elf32_Addr v)
674#endif
675{ 700{
676 struct arch_file *ifile = (struct arch_file *) f; 701 struct arch_file *ifile = (struct arch_file *) f;
677 struct arch_symbol *isym = (struct arch_symbol *) sym; 702 struct arch_symbol *isym = (struct arch_symbol *) sym;
678 703
679 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset); 704 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
680 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; 705 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
681 Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0; 706 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
707#if defined(__arm__)
708 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
709
710 struct arm_plt_entry *pe;
711 unsigned long *ip;
712#endif
682 713
683 enum obj_reloc ret = obj_reloc_ok; 714 enum obj_reloc ret = obj_reloc_ok;
684 715
@@ -689,52 +720,91 @@ arch_apply_relocation(struct obj_file *f,
689 and in case that ever changes */ 720 and in case that ever changes */
690#if defined(__sh__) 721#if defined(__sh__)
691 case R_SH_NONE: 722 case R_SH_NONE:
692#else 723#elif defined(__arm__)
724 case R_ARM_NONE:
725#elif defined(__i386__)
693 case R_386_NONE: 726 case R_386_NONE:
694#endif 727#endif
695 break; 728 break;
696 729
697#if defined(__sh__) 730#if defined(__sh__)
698 case R_SH_DIR32: 731 case R_SH_DIR32:
699#else 732#elif defined(__arm__)
733 case R_ARM_ABS32:
734#elif defined(__i386__)
700 case R_386_32: 735 case R_386_32:
701#endif 736#endif
702 *loc += v; 737 *loc += v;
703 break; 738 break;
704 739
705#if defined(__sh__) 740#if defined(__arm__)
741#elif defined(__sh__)
706 case R_SH_REL32: 742 case R_SH_REL32:
707#else 743 *loc += v - dot;
744 break;
745#elif defined(__i386__)
708 case R_386_PLT32: 746 case R_386_PLT32:
709 case R_386_PC32: 747 case R_386_PC32:
710#endif
711 *loc += v - dot; 748 *loc += v - dot;
712 break; 749 break;
750#endif
713 751
714#if defined(__sh__) 752#if defined(__sh__)
715 case R_SH_PLT32: 753 case R_SH_PLT32:
716 *loc = v - dot; 754 *loc = v - dot;
717 break; 755 break;
756#elif defined(__arm__)
757 case R_ARM_PC24:
758 case R_ARM_PLT32:
759 /* find the plt entry and initialize it if necessary */
760 assert(isym != NULL);
761 pe = (struct arm_plt_entry*) &isym->pltent;
762 if (! pe->inited) {
763 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
764 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
765 ip[1] = v; /* sym@ */
766 pe->inited = 1;
767 }
768
769 /* relative distance to target */
770 v -= dot;
771 /* if the target is too far away.... */
772 if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
773 /* go via the plt */
774 v = plt + pe->offset - dot;
775 }
776 if (v & 3)
777 ret = obj_reloc_dangerous;
778
779 /* Convert to words. */
780 v >>= 2;
781
782 /* merge the offset into the instruction. */
783 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
784 break;
785#elif defined(__i386__)
718#endif 786#endif
719 787
720 788
721#if defined(__sh__) 789#if defined(__arm__)
790#elif defined(__sh__)
722 case R_SH_GLOB_DAT: 791 case R_SH_GLOB_DAT:
723 case R_SH_JMP_SLOT: 792 case R_SH_JMP_SLOT:
724 *loc = v; 793 *loc = v;
725 break; 794 break;
726#else 795#elif defined(__i386__)
727 case R_386_GLOB_DAT: 796 case R_386_GLOB_DAT:
728 case R_386_JMP_SLOT: 797 case R_386_JMP_SLOT:
729 *loc = v; 798 *loc = v;
730 break; 799 break;
731#endif 800#endif
732 801
733#if defined(__sh__) 802#if defined(__arm__)
803#elif defined(__sh__)
734 case R_SH_RELATIVE: 804 case R_SH_RELATIVE:
735 *loc += f->baseaddr + rel->r_addend; 805 *loc += f->baseaddr + rel->r_addend;
736 break; 806 break;
737#else 807#elif defined(__i386__)
738 case R_386_RELATIVE: 808 case R_386_RELATIVE:
739 *loc += f->baseaddr; 809 *loc += f->baseaddr;
740 break; 810 break;
@@ -742,41 +812,46 @@ arch_apply_relocation(struct obj_file *f,
742 812
743#if defined(__sh__) 813#if defined(__sh__)
744 case R_SH_GOTPC: 814 case R_SH_GOTPC:
745 assert(got != 0); 815#elif defined(__arm__)
746 *loc += got - dot + rel->r_addend;; 816 case R_ARM_GOTPC:
747 break; 817#elif defined(__i386__)
748#else
749 case R_386_GOTPC: 818 case R_386_GOTPC:
819#endif
750 assert(got != 0); 820 assert(got != 0);
821#if defined(__sh__)
822 *loc += got - dot + rel->r_addend;;
823#elif defined(__i386__) || defined(__arm__)
751 *loc += got - dot; 824 *loc += got - dot;
752 break;
753#endif 825#endif
826 break;
754 827
755#if defined(__sh__) 828#if defined(__sh__)
756 case R_SH_GOT32: 829 case R_SH_GOT32:
757 assert(isym != NULL); 830#elif defined(__arm__)
758 if (!isym->gotent.reloc_done) { 831 case R_ARM_GOT32:
759 isym->gotent.reloc_done = 1; 832#elif defined(__i386__)
760 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
761 v;
762 }
763 *loc += isym->gotent.offset + rel->r_addend;
764 break;
765#else
766 case R_386_GOT32: 833 case R_386_GOT32:
834#endif
767 assert(isym != NULL); 835 assert(isym != NULL);
836 /* needs an entry in the .got: set it, once */
768 if (!isym->gotent.reloc_done) { 837 if (!isym->gotent.reloc_done) {
769 isym->gotent.reloc_done = 1; 838 isym->gotent.reloc_done = 1;
770 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) = 839 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
771 v;
772 } 840 }
841 /* make the reloc with_respect_to_.got */
842#if defined(__sh__)
843 *loc += isym->gotent.offset + rel->r_addend;
844#elif defined(__i386__) || defined(__arm__)
773 *loc += isym->gotent.offset; 845 *loc += isym->gotent.offset;
774 break;
775#endif 846#endif
847 break;
776 848
849 /* address relative to the got */
777#if defined(__sh__) 850#if defined(__sh__)
778 case R_SH_GOTOFF: 851 case R_SH_GOTOFF:
779#else 852#elif defined(__arm__)
853 case R_ARM_GOTOFF:
854#elif defined(__i386__)
780 case R_386_GOTOFF: 855 case R_386_GOTOFF:
781#endif 856#endif
782 assert(got != 0); 857 assert(got != 0);
@@ -784,6 +859,7 @@ arch_apply_relocation(struct obj_file *f,
784 break; 859 break;
785 860
786 default: 861 default:
862 printf("Warning: unhandled reloc %d\n",ELF32_R_TYPE(rel->r_info));
787 ret = obj_reloc_unhandled; 863 ret = obj_reloc_unhandled;
788 break; 864 break;
789 } 865 }
@@ -794,81 +870,111 @@ arch_apply_relocation(struct obj_file *f,
794int arch_create_got(struct obj_file *f) 870int arch_create_got(struct obj_file *f)
795{ 871{
796 struct arch_file *ifile = (struct arch_file *) f; 872 struct arch_file *ifile = (struct arch_file *) f;
797 int i, n, offset = 0, gotneeded = 0; 873 int i, got_offset = 0, gotneeded = 0;
798 874#if defined(__arm__)
799 n = ifile->root.header.e_shnum; 875 int plt_offset = 0, pltneeded = 0;
800 for (i = 0; i < n; ++i) {
801 struct obj_section *relsec, *symsec, *strsec;
802#if defined(__sh__)
803 Elf32_Rela *rel, *relend;
804#else
805 Elf32_Rel *rel, *relend;
806#endif 876#endif
807 Elf32_Sym *symtab; 877 struct obj_section *relsec, *symsec, *strsec;
808 const char *strtab; 878 ElfW(RelM) *rel, *relend;
879 ElfW(Sym) *symtab, *extsym;
880 const char *strtab, *name;
881 struct arch_symbol *intsym;
809 882
810 relsec = ifile->root.sections[i]; 883 for (i = 0; i < f->header.e_shnum; ++i) {
811 if (relsec->header.sh_type != SHT_REL) 884 relsec = f->sections[i];
885 if (relsec->header.sh_type != SHT_RELM)
812 continue; 886 continue;
813 887
814 symsec = ifile->root.sections[relsec->header.sh_link]; 888 symsec = f->sections[relsec->header.sh_link];
815 strsec = ifile->root.sections[symsec->header.sh_link]; 889 strsec = f->sections[symsec->header.sh_link];
816
817 890
818#if defined(__sh__) 891 rel = (ElfW(RelM) *) relsec->contents;
819 rel = (Elf32_Rela *) relsec->contents; 892 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
820 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela)); 893 symtab = (ElfW(Sym) *) symsec->contents;
821#else
822 rel = (Elf32_Rel *) relsec->contents;
823 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
824#endif
825 symtab = (Elf32_Sym *) symsec->contents;
826 strtab = (const char *) strsec->contents; 894 strtab = (const char *) strsec->contents;
827 895
828 for (; rel < relend; ++rel) { 896 for (; rel < relend; ++rel) {
829 Elf32_Sym *extsym; 897 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
830 struct arch_symbol *intsym;
831 const char *name;
832 898
833 switch (ELF32_R_TYPE(rel->r_info)) { 899 switch (ELF32_R_TYPE(rel->r_info)) {
834#if defined(__sh__) 900#if defined(__arm__)
901 case R_ARM_GOT32:
902#elif defined(__sh__)
903 case R_SH_GOT32:
904#elif defined(__i386__)
905 case R_386_GOT32:
906#endif
907 break;
908
909#if defined(__arm__)
910 case R_ARM_PC24:
911 case R_ARM_PLT32:
912 pltneeded = 1;
913 break;
914
915 case R_ARM_GOTPC:
916 case R_ARM_GOTOFF:
917 gotneeded = 1;
918 if (got_offset == 0)
919 got_offset = 4;
920#elif defined(__sh__)
835 case R_SH_GOTPC: 921 case R_SH_GOTPC:
836 case R_SH_GOTOFF: 922 case R_SH_GOTOFF:
837#else 923 gotneeded = 1;
924#elif defined(__i386__)
838 case R_386_GOTPC: 925 case R_386_GOTPC:
839 case R_386_GOTOFF: 926 case R_386_GOTOFF:
840#endif
841 gotneeded = 1; 927 gotneeded = 1;
928#endif
929
842 default: 930 default:
843 continue; 931 continue;
844
845#if defined(__sh__)
846 case R_SH_GOT32:
847#else
848 case R_386_GOT32:
849#endif
850 break;
851 } 932 }
852 933
853 extsym = &symtab[ELF32_R_SYM(rel->r_info)]; 934 if (extsym->st_name != 0) {
854 if (extsym->st_name)
855 name = strtab + extsym->st_name; 935 name = strtab + extsym->st_name;
856 else 936 } else {
857 name = f->sections[extsym->st_shndx]->name; 937 name = f->sections[extsym->st_shndx]->name;
858 intsym = 938 }
859 (struct arch_symbol *) obj_find_symbol(&ifile->root, name); 939 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
860 940
861 if (!intsym->gotent.offset_done) { 941 if (!intsym->gotent.offset_done) {
862 intsym->gotent.offset_done = 1; 942 intsym->gotent.offset_done = 1;
863 intsym->gotent.offset = offset; 943 intsym->gotent.offset = got_offset;
864 offset += 4; 944 got_offset += 4;
865 } 945 }
946#if defined(__arm__)
947 if (pltneeded && intsym->pltent.allocated == 0) {
948 intsym->pltent.allocated = 1;
949 intsym->pltent.offset = plt_offset;
950 plt_offset += 8;
951 intsym->pltent.inited = 0;
952 pltneeded = 0;
953 }
954#endif
955 }
956 }
957
958#if defined(__arm__)
959 if (got_offset) {
960 struct obj_section* relsec = obj_find_section(f, ".got");
961
962 if (relsec) {
963 obj_extend_section(relsec, got_offset);
964 } else {
965 relsec = obj_create_alloced_section(f, ".got", 8, got_offset);
966 assert(relsec);
866 } 967 }
968
969 ifile->got = relsec;
867 } 970 }
868 971
869 if (offset > 0 || gotneeded) 972 if (plt_offset)
870 ifile->got = 973 ifile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset);
871 obj_create_alloced_section(&ifile->root, ".got", 4, offset); 974#else
975 if (got_offset > 0 || gotneeded)
976 ifile->got = obj_create_alloced_section(f, ".got", 4, got_offset);
977#endif
872 978
873 return 1; 979 return 1;
874} 980}
@@ -1598,7 +1704,7 @@ old_init_module(const char *m_name, struct obj_file *f,
1598 ksym->name = 1704 ksym->name =
1599 (unsigned long) str - (unsigned long) symtab; 1705 (unsigned long) str - (unsigned long) symtab;
1600 1706
1601 str = stpcpy(str, sym->name) + 1; 1707 str = strcpy(str, sym->name) + 1;
1602 ksym++; 1708 ksym++;
1603 } 1709 }
1604 } 1710 }
@@ -2201,8 +2307,9 @@ new_init_module(const char *m_name, struct obj_file *f,
2201#define new_init_module(x, y, z) TRUE 2307#define new_init_module(x, y, z) TRUE
2202#define new_create_this_module(x, y) 0 2308#define new_create_this_module(x, y) 0
2203#define new_create_module_ksymtab(x) 2309#define new_create_module_ksymtab(x)
2310#define query_module(v, w, x, y, z) -1
2204 2311
2205#endif /* BB_FEATURE_INSMOD_OLD_KERNEL */ 2312#endif /* BB_FEATURE_INSMOD_NEW_KERNEL */
2206 2313
2207 2314
2208/*======================================================================*/ 2315/*======================================================================*/
@@ -2372,8 +2479,12 @@ void obj_allocate_commons(struct obj_file *f)
2372 for (i = 0; i < f->header.e_shnum; ++i) { 2479 for (i = 0; i < f->header.e_shnum; ++i) {
2373 struct obj_section *s = f->sections[i]; 2480 struct obj_section *s = f->sections[i];
2374 if (s->header.sh_type == SHT_NOBITS) { 2481 if (s->header.sh_type == SHT_NOBITS) {
2482 if (s->header.sh_size != 0)
2375 s->contents = memset(xmalloc(s->header.sh_size), 2483 s->contents = memset(xmalloc(s->header.sh_size),
2376 0, s->header.sh_size); 2484 0, s->header.sh_size);
2485 else
2486 s->contents = NULL;
2487
2377 s->header.sh_type = SHT_PROGBITS; 2488 s->header.sh_type = SHT_PROGBITS;
2378 } 2489 }
2379 } 2490 }
diff --git a/lsmod.c b/lsmod.c
index ab4726b9e..6fe505bf6 100644
--- a/lsmod.c
+++ b/lsmod.c
@@ -5,6 +5,10 @@
5 * Copyright (C) 1999,2000 by Lineo, inc. 5 * Copyright (C) 1999,2000 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 * 7 *
8 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
9 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels
10 * (which lack the query_module() interface).
11 *
8 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 14 * the Free Software Foundation; either version 2 of the License, or
@@ -32,8 +36,15 @@
32#include <assert.h> 36#include <assert.h>
33#include <getopt.h> 37#include <getopt.h>
34#include <sys/utsname.h> 38#include <sys/utsname.h>
39#include <sys/file.h>
40
35 41
36 42
43#if !defined(BB_FEATURE_LSMOD_NEW_KERNEL) && !defined(BB_FEATURE_LSMOD_OLD_KERNEL)
44#error "Must have ether BB_FEATURE_LSMOD_NEW_KERNEL or BB_FEATURE_LSMOD_OLD_KERNEL defined"
45#endif
46
47#ifdef BB_FEATURE_LSMOD_NEW_KERNEL
37 48
38struct module_info 49struct module_info
39{ 50{
@@ -120,3 +131,30 @@ extern int lsmod_main(int argc, char **argv)
120 131
121 return( 0); 132 return( 0);
122} 133}
134
135#else /*BB_FEATURE_LSMOD_OLD_KERNEL*/
136
137#if ! defined BB_FEATURE_USE_PROCFS
138#error Sorry, I depend on the /proc filesystem right now.
139#endif
140
141extern int lsmod_main(int argc, char **argv)
142{
143 int fd, i;
144 char line[128];
145
146 puts("Module Size Used by");
147 fflush(stdout);
148
149 if ((fd = open("/proc/modules", O_RDONLY)) >= 0 ) {
150 while ((i = read(fd, line, sizeof(line))) > 0) {
151 write(fileno(stdout), line, i);
152 }
153 close(fd);
154 return 0;
155 }
156 fatalError("/proc/modules: %s\n", strerror(errno));
157 return 1;
158}
159
160#endif /*BB_FEATURE_LSMOD_OLD_KERNEL*/
diff --git a/modutils/insmod.c b/modutils/insmod.c
index 6386b9407..0963225fa 100644
--- a/modutils/insmod.c
+++ b/modutils/insmod.c
@@ -7,11 +7,12 @@
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 9 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4
10 * and (theoretically) SH3. Note that there is still no true 10 * and (theoretically) SH3. I have only tested SH4 in little endian mode.
11 * multiple architecture support. You just get SH3|SH4|i386, despite 11 *
12 * the mention of ARM and m68k--which may or may not work (but 12 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
13 * almost certainly do not, due to at least MATCH_MACHINE). I have 13 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only
14 * only tested SH4 in little endian mode. 14 * very minor changes required to also work with StrongArm and presumably
15 * all ARM based systems.
15 * 16 *
16 * Based almost entirely on the Linux modutils-2.3.11 implementation. 17 * Based almost entirely on the Linux modutils-2.3.11 implementation.
17 * Copyright 1996, 1997 Linux International. 18 * Copyright 1996, 1997 Linux International.
@@ -77,7 +78,7 @@
77#ifndef MODUTILS_MODULE_H 78#ifndef MODUTILS_MODULE_H
78#define MODUTILS_MODULE_H 1 79#define MODUTILS_MODULE_H 1
79 80
80#ident "$Id: insmod.c,v 1.29 2000/12/01 02:55:13 kraai Exp $" 81#ident "$Id: insmod.c,v 1.30 2000/12/06 18:18:26 andersen Exp $"
81 82
82/* This file contains the structures used by the 2.0 and 2.1 kernels. 83/* This file contains the structures used by the 2.0 and 2.1 kernels.
83 We do not use the kernel headers directly because we do not wish 84 We do not use the kernel headers directly because we do not wish
@@ -283,7 +284,7 @@ int delete_module(const char *);
283#ifndef MODUTILS_OBJ_H 284#ifndef MODUTILS_OBJ_H
284#define MODUTILS_OBJ_H 1 285#define MODUTILS_OBJ_H 1
285 286
286#ident "$Id: insmod.c,v 1.29 2000/12/01 02:55:13 kraai Exp $" 287#ident "$Id: insmod.c,v 1.30 2000/12/06 18:18:26 andersen Exp $"
287 288
288/* The relocatable object is manipulated using elfin types. */ 289/* The relocatable object is manipulated using elfin types. */
289 290
@@ -317,12 +318,17 @@ int delete_module(const char *);
317#define SHT_RELM SHT_RELA 318#define SHT_RELM SHT_RELA
318#define Elf32_RelM Elf32_Rela 319#define Elf32_RelM Elf32_Rela
319 320
320#else 321#elif defined(__arm__)
321 322
322/* presumably we can use these for anything but the SH */ 323#define MATCH_MACHINE(x) (x == EM_ARM)
324#define SHT_RELM SHT_REL
325#define Elf32_RelM Elf32_Rel
326
327#elif defined(__i386__)
328
329/* presumably we can use these for anything but the SH and ARM*/
323/* this is the previous behavior, but it does result in 330/* this is the previous behavior, but it does result in
324 insmod.c being broken on anything except i386 */ 331 insmod.c being broken on anything except i386 */
325
326#ifndef EM_486 332#ifndef EM_486
327#define MATCH_MACHINE(x) (x == EM_386) 333#define MATCH_MACHINE(x) (x == EM_386)
328#else 334#else
@@ -332,6 +338,8 @@ int delete_module(const char *);
332#define SHT_RELM SHT_REL 338#define SHT_RELM SHT_REL
333#define Elf32_RelM Elf32_Rel 339#define Elf32_RelM Elf32_Rel
334 340
341#else
342#error insmod.c no platform specified
335#endif 343#endif
336 344
337#ifndef ElfW 345#ifndef ElfW
@@ -531,6 +539,17 @@ int flag_export = 1;
531 and we can't support anything else right now anyway. In the 539 and we can't support anything else right now anyway. In the
532 future maybe they should be #if defined'd */ 540 future maybe they should be #if defined'd */
533 541
542/* Done ;-) */
543
544#if defined(__arm__)
545struct arm_plt_entry
546{
547 int offset;
548 int allocated:1;
549 int inited:1; /* has been set up */
550};
551#endif
552
534struct arch_got_entry { 553struct arch_got_entry {
535 int offset; 554 int offset;
536 unsigned offset_done:1; 555 unsigned offset_done:1;
@@ -539,11 +558,17 @@ struct arch_got_entry {
539 558
540struct arch_file { 559struct arch_file {
541 struct obj_file root; 560 struct obj_file root;
561#if defined(__arm__)
562 struct obj_section *plt;
563#endif
542 struct obj_section *got; 564 struct obj_section *got;
543}; 565};
544 566
545struct arch_symbol { 567struct arch_symbol {
546 struct obj_symbol root; 568 struct obj_symbol root;
569#if defined(__arm__)
570 struct arm_plt_entry pltent;
571#endif
547 struct arch_got_entry gotent; 572 struct arch_got_entry gotent;
548}; 573};
549 574
@@ -590,6 +615,10 @@ extern int delete_module(const char *);
590 615
591 -- Bryan Rittmeyer <bryan@ixiacom.com> */ 616 -- Bryan Rittmeyer <bryan@ixiacom.com> */
592 617
618#ifdef BB_FEATURE_INSMOD_OLD_KERNEL
619_syscall1(int, get_kernel_syms, struct old_kernel_sym *, ks)
620#endif
621
593#if defined(__i386__) || defined(__m68k__) || defined(__arm__) 622#if defined(__i386__) || defined(__m68k__) || defined(__arm__)
594/* Jump through hoops to fixup error return codes */ 623/* Jump through hoops to fixup error return codes */
595#define __NR__create_module __NR_create_module 624#define __NR__create_module __NR_create_module
@@ -623,7 +652,7 @@ static int findNamedModule(const char *fileName, struct stat *statbuf,
623 if (fullName[0] == '\0') 652 if (fullName[0] == '\0')
624 return (FALSE); 653 return (FALSE);
625 else { 654 else {
626 char *tmp = strrchr(fileName, '/'); 655 char *tmp = strrchr((char *) fileName, '/');
627 656
628 if (tmp == NULL) 657 if (tmp == NULL)
629 tmp = (char *) fileName; 658 tmp = (char *) fileName;
@@ -667,18 +696,20 @@ arch_apply_relocation(struct obj_file *f,
667 struct obj_section *targsec, 696 struct obj_section *targsec,
668 struct obj_section *symsec, 697 struct obj_section *symsec,
669 struct obj_symbol *sym, 698 struct obj_symbol *sym,
670#if defined(__sh__) 699 ElfW(RelM) *rel, ElfW(Addr) v)
671 Elf32_Rela * rel, Elf32_Addr v)
672#else
673 Elf32_Rel * rel, Elf32_Addr v)
674#endif
675{ 700{
676 struct arch_file *ifile = (struct arch_file *) f; 701 struct arch_file *ifile = (struct arch_file *) f;
677 struct arch_symbol *isym = (struct arch_symbol *) sym; 702 struct arch_symbol *isym = (struct arch_symbol *) sym;
678 703
679 Elf32_Addr *loc = (Elf32_Addr *) (targsec->contents + rel->r_offset); 704 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);
680 Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset; 705 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;
681 Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0; 706 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;
707#if defined(__arm__)
708 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
709
710 struct arm_plt_entry *pe;
711 unsigned long *ip;
712#endif
682 713
683 enum obj_reloc ret = obj_reloc_ok; 714 enum obj_reloc ret = obj_reloc_ok;
684 715
@@ -689,52 +720,91 @@ arch_apply_relocation(struct obj_file *f,
689 and in case that ever changes */ 720 and in case that ever changes */
690#if defined(__sh__) 721#if defined(__sh__)
691 case R_SH_NONE: 722 case R_SH_NONE:
692#else 723#elif defined(__arm__)
724 case R_ARM_NONE:
725#elif defined(__i386__)
693 case R_386_NONE: 726 case R_386_NONE:
694#endif 727#endif
695 break; 728 break;
696 729
697#if defined(__sh__) 730#if defined(__sh__)
698 case R_SH_DIR32: 731 case R_SH_DIR32:
699#else 732#elif defined(__arm__)
733 case R_ARM_ABS32:
734#elif defined(__i386__)
700 case R_386_32: 735 case R_386_32:
701#endif 736#endif
702 *loc += v; 737 *loc += v;
703 break; 738 break;
704 739
705#if defined(__sh__) 740#if defined(__arm__)
741#elif defined(__sh__)
706 case R_SH_REL32: 742 case R_SH_REL32:
707#else 743 *loc += v - dot;
744 break;
745#elif defined(__i386__)
708 case R_386_PLT32: 746 case R_386_PLT32:
709 case R_386_PC32: 747 case R_386_PC32:
710#endif
711 *loc += v - dot; 748 *loc += v - dot;
712 break; 749 break;
750#endif
713 751
714#if defined(__sh__) 752#if defined(__sh__)
715 case R_SH_PLT32: 753 case R_SH_PLT32:
716 *loc = v - dot; 754 *loc = v - dot;
717 break; 755 break;
756#elif defined(__arm__)
757 case R_ARM_PC24:
758 case R_ARM_PLT32:
759 /* find the plt entry and initialize it if necessary */
760 assert(isym != NULL);
761 pe = (struct arm_plt_entry*) &isym->pltent;
762 if (! pe->inited) {
763 ip = (unsigned long *) (ifile->plt->contents + pe->offset);
764 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */
765 ip[1] = v; /* sym@ */
766 pe->inited = 1;
767 }
768
769 /* relative distance to target */
770 v -= dot;
771 /* if the target is too far away.... */
772 if ((int)v < -0x02000000 || (int)v >= 0x02000000) {
773 /* go via the plt */
774 v = plt + pe->offset - dot;
775 }
776 if (v & 3)
777 ret = obj_reloc_dangerous;
778
779 /* Convert to words. */
780 v >>= 2;
781
782 /* merge the offset into the instruction. */
783 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff);
784 break;
785#elif defined(__i386__)
718#endif 786#endif
719 787
720 788
721#if defined(__sh__) 789#if defined(__arm__)
790#elif defined(__sh__)
722 case R_SH_GLOB_DAT: 791 case R_SH_GLOB_DAT:
723 case R_SH_JMP_SLOT: 792 case R_SH_JMP_SLOT:
724 *loc = v; 793 *loc = v;
725 break; 794 break;
726#else 795#elif defined(__i386__)
727 case R_386_GLOB_DAT: 796 case R_386_GLOB_DAT:
728 case R_386_JMP_SLOT: 797 case R_386_JMP_SLOT:
729 *loc = v; 798 *loc = v;
730 break; 799 break;
731#endif 800#endif
732 801
733#if defined(__sh__) 802#if defined(__arm__)
803#elif defined(__sh__)
734 case R_SH_RELATIVE: 804 case R_SH_RELATIVE:
735 *loc += f->baseaddr + rel->r_addend; 805 *loc += f->baseaddr + rel->r_addend;
736 break; 806 break;
737#else 807#elif defined(__i386__)
738 case R_386_RELATIVE: 808 case R_386_RELATIVE:
739 *loc += f->baseaddr; 809 *loc += f->baseaddr;
740 break; 810 break;
@@ -742,41 +812,46 @@ arch_apply_relocation(struct obj_file *f,
742 812
743#if defined(__sh__) 813#if defined(__sh__)
744 case R_SH_GOTPC: 814 case R_SH_GOTPC:
745 assert(got != 0); 815#elif defined(__arm__)
746 *loc += got - dot + rel->r_addend;; 816 case R_ARM_GOTPC:
747 break; 817#elif defined(__i386__)
748#else
749 case R_386_GOTPC: 818 case R_386_GOTPC:
819#endif
750 assert(got != 0); 820 assert(got != 0);
821#if defined(__sh__)
822 *loc += got - dot + rel->r_addend;;
823#elif defined(__i386__) || defined(__arm__)
751 *loc += got - dot; 824 *loc += got - dot;
752 break;
753#endif 825#endif
826 break;
754 827
755#if defined(__sh__) 828#if defined(__sh__)
756 case R_SH_GOT32: 829 case R_SH_GOT32:
757 assert(isym != NULL); 830#elif defined(__arm__)
758 if (!isym->gotent.reloc_done) { 831 case R_ARM_GOT32:
759 isym->gotent.reloc_done = 1; 832#elif defined(__i386__)
760 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) =
761 v;
762 }
763 *loc += isym->gotent.offset + rel->r_addend;
764 break;
765#else
766 case R_386_GOT32: 833 case R_386_GOT32:
834#endif
767 assert(isym != NULL); 835 assert(isym != NULL);
836 /* needs an entry in the .got: set it, once */
768 if (!isym->gotent.reloc_done) { 837 if (!isym->gotent.reloc_done) {
769 isym->gotent.reloc_done = 1; 838 isym->gotent.reloc_done = 1;
770 *(Elf32_Addr *) (ifile->got->contents + isym->gotent.offset) = 839 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v;
771 v;
772 } 840 }
841 /* make the reloc with_respect_to_.got */
842#if defined(__sh__)
843 *loc += isym->gotent.offset + rel->r_addend;
844#elif defined(__i386__) || defined(__arm__)
773 *loc += isym->gotent.offset; 845 *loc += isym->gotent.offset;
774 break;
775#endif 846#endif
847 break;
776 848
849 /* address relative to the got */
777#if defined(__sh__) 850#if defined(__sh__)
778 case R_SH_GOTOFF: 851 case R_SH_GOTOFF:
779#else 852#elif defined(__arm__)
853 case R_ARM_GOTOFF:
854#elif defined(__i386__)
780 case R_386_GOTOFF: 855 case R_386_GOTOFF:
781#endif 856#endif
782 assert(got != 0); 857 assert(got != 0);
@@ -784,6 +859,7 @@ arch_apply_relocation(struct obj_file *f,
784 break; 859 break;
785 860
786 default: 861 default:
862 printf("Warning: unhandled reloc %d\n",ELF32_R_TYPE(rel->r_info));
787 ret = obj_reloc_unhandled; 863 ret = obj_reloc_unhandled;
788 break; 864 break;
789 } 865 }
@@ -794,81 +870,111 @@ arch_apply_relocation(struct obj_file *f,
794int arch_create_got(struct obj_file *f) 870int arch_create_got(struct obj_file *f)
795{ 871{
796 struct arch_file *ifile = (struct arch_file *) f; 872 struct arch_file *ifile = (struct arch_file *) f;
797 int i, n, offset = 0, gotneeded = 0; 873 int i, got_offset = 0, gotneeded = 0;
798 874#if defined(__arm__)
799 n = ifile->root.header.e_shnum; 875 int plt_offset = 0, pltneeded = 0;
800 for (i = 0; i < n; ++i) {
801 struct obj_section *relsec, *symsec, *strsec;
802#if defined(__sh__)
803 Elf32_Rela *rel, *relend;
804#else
805 Elf32_Rel *rel, *relend;
806#endif 876#endif
807 Elf32_Sym *symtab; 877 struct obj_section *relsec, *symsec, *strsec;
808 const char *strtab; 878 ElfW(RelM) *rel, *relend;
879 ElfW(Sym) *symtab, *extsym;
880 const char *strtab, *name;
881 struct arch_symbol *intsym;
809 882
810 relsec = ifile->root.sections[i]; 883 for (i = 0; i < f->header.e_shnum; ++i) {
811 if (relsec->header.sh_type != SHT_REL) 884 relsec = f->sections[i];
885 if (relsec->header.sh_type != SHT_RELM)
812 continue; 886 continue;
813 887
814 symsec = ifile->root.sections[relsec->header.sh_link]; 888 symsec = f->sections[relsec->header.sh_link];
815 strsec = ifile->root.sections[symsec->header.sh_link]; 889 strsec = f->sections[symsec->header.sh_link];
816
817 890
818#if defined(__sh__) 891 rel = (ElfW(RelM) *) relsec->contents;
819 rel = (Elf32_Rela *) relsec->contents; 892 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
820 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela)); 893 symtab = (ElfW(Sym) *) symsec->contents;
821#else
822 rel = (Elf32_Rel *) relsec->contents;
823 relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
824#endif
825 symtab = (Elf32_Sym *) symsec->contents;
826 strtab = (const char *) strsec->contents; 894 strtab = (const char *) strsec->contents;
827 895
828 for (; rel < relend; ++rel) { 896 for (; rel < relend; ++rel) {
829 Elf32_Sym *extsym; 897 extsym = &symtab[ELF32_R_SYM(rel->r_info)];
830 struct arch_symbol *intsym;
831 const char *name;
832 898
833 switch (ELF32_R_TYPE(rel->r_info)) { 899 switch (ELF32_R_TYPE(rel->r_info)) {
834#if defined(__sh__) 900#if defined(__arm__)
901 case R_ARM_GOT32:
902#elif defined(__sh__)
903 case R_SH_GOT32:
904#elif defined(__i386__)
905 case R_386_GOT32:
906#endif
907 break;
908
909#if defined(__arm__)
910 case R_ARM_PC24:
911 case R_ARM_PLT32:
912 pltneeded = 1;
913 break;
914
915 case R_ARM_GOTPC:
916 case R_ARM_GOTOFF:
917 gotneeded = 1;
918 if (got_offset == 0)
919 got_offset = 4;
920#elif defined(__sh__)
835 case R_SH_GOTPC: 921 case R_SH_GOTPC:
836 case R_SH_GOTOFF: 922 case R_SH_GOTOFF:
837#else 923 gotneeded = 1;
924#elif defined(__i386__)
838 case R_386_GOTPC: 925 case R_386_GOTPC:
839 case R_386_GOTOFF: 926 case R_386_GOTOFF:
840#endif
841 gotneeded = 1; 927 gotneeded = 1;
928#endif
929
842 default: 930 default:
843 continue; 931 continue;
844
845#if defined(__sh__)
846 case R_SH_GOT32:
847#else
848 case R_386_GOT32:
849#endif
850 break;
851 } 932 }
852 933
853 extsym = &symtab[ELF32_R_SYM(rel->r_info)]; 934 if (extsym->st_name != 0) {
854 if (extsym->st_name)
855 name = strtab + extsym->st_name; 935 name = strtab + extsym->st_name;
856 else 936 } else {
857 name = f->sections[extsym->st_shndx]->name; 937 name = f->sections[extsym->st_shndx]->name;
858 intsym = 938 }
859 (struct arch_symbol *) obj_find_symbol(&ifile->root, name); 939 intsym = (struct arch_symbol *) obj_find_symbol(f, name);
860 940
861 if (!intsym->gotent.offset_done) { 941 if (!intsym->gotent.offset_done) {
862 intsym->gotent.offset_done = 1; 942 intsym->gotent.offset_done = 1;
863 intsym->gotent.offset = offset; 943 intsym->gotent.offset = got_offset;
864 offset += 4; 944 got_offset += 4;
865 } 945 }
946#if defined(__arm__)
947 if (pltneeded && intsym->pltent.allocated == 0) {
948 intsym->pltent.allocated = 1;
949 intsym->pltent.offset = plt_offset;
950 plt_offset += 8;
951 intsym->pltent.inited = 0;
952 pltneeded = 0;
953 }
954#endif
955 }
956 }
957
958#if defined(__arm__)
959 if (got_offset) {
960 struct obj_section* relsec = obj_find_section(f, ".got");
961
962 if (relsec) {
963 obj_extend_section(relsec, got_offset);
964 } else {
965 relsec = obj_create_alloced_section(f, ".got", 8, got_offset);
966 assert(relsec);
866 } 967 }
968
969 ifile->got = relsec;
867 } 970 }
868 971
869 if (offset > 0 || gotneeded) 972 if (plt_offset)
870 ifile->got = 973 ifile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset);
871 obj_create_alloced_section(&ifile->root, ".got", 4, offset); 974#else
975 if (got_offset > 0 || gotneeded)
976 ifile->got = obj_create_alloced_section(f, ".got", 4, got_offset);
977#endif
872 978
873 return 1; 979 return 1;
874} 980}
@@ -1598,7 +1704,7 @@ old_init_module(const char *m_name, struct obj_file *f,
1598 ksym->name = 1704 ksym->name =
1599 (unsigned long) str - (unsigned long) symtab; 1705 (unsigned long) str - (unsigned long) symtab;
1600 1706
1601 str = stpcpy(str, sym->name) + 1; 1707 str = strcpy(str, sym->name) + 1;
1602 ksym++; 1708 ksym++;
1603 } 1709 }
1604 } 1710 }
@@ -2201,8 +2307,9 @@ new_init_module(const char *m_name, struct obj_file *f,
2201#define new_init_module(x, y, z) TRUE 2307#define new_init_module(x, y, z) TRUE
2202#define new_create_this_module(x, y) 0 2308#define new_create_this_module(x, y) 0
2203#define new_create_module_ksymtab(x) 2309#define new_create_module_ksymtab(x)
2310#define query_module(v, w, x, y, z) -1
2204 2311
2205#endif /* BB_FEATURE_INSMOD_OLD_KERNEL */ 2312#endif /* BB_FEATURE_INSMOD_NEW_KERNEL */
2206 2313
2207 2314
2208/*======================================================================*/ 2315/*======================================================================*/
@@ -2372,8 +2479,12 @@ void obj_allocate_commons(struct obj_file *f)
2372 for (i = 0; i < f->header.e_shnum; ++i) { 2479 for (i = 0; i < f->header.e_shnum; ++i) {
2373 struct obj_section *s = f->sections[i]; 2480 struct obj_section *s = f->sections[i];
2374 if (s->header.sh_type == SHT_NOBITS) { 2481 if (s->header.sh_type == SHT_NOBITS) {
2482 if (s->header.sh_size != 0)
2375 s->contents = memset(xmalloc(s->header.sh_size), 2483 s->contents = memset(xmalloc(s->header.sh_size),
2376 0, s->header.sh_size); 2484 0, s->header.sh_size);
2485 else
2486 s->contents = NULL;
2487
2377 s->header.sh_type = SHT_PROGBITS; 2488 s->header.sh_type = SHT_PROGBITS;
2378 } 2489 }
2379 } 2490 }
diff --git a/modutils/lsmod.c b/modutils/lsmod.c
index ab4726b9e..6fe505bf6 100644
--- a/modutils/lsmod.c
+++ b/modutils/lsmod.c
@@ -5,6 +5,10 @@
5 * Copyright (C) 1999,2000 by Lineo, inc. 5 * Copyright (C) 1999,2000 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 * 7 *
8 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and
9 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels
10 * (which lack the query_module() interface).
11 *
8 * This program is free software; you can redistribute it and/or modify 12 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 13 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 14 * the Free Software Foundation; either version 2 of the License, or
@@ -32,8 +36,15 @@
32#include <assert.h> 36#include <assert.h>
33#include <getopt.h> 37#include <getopt.h>
34#include <sys/utsname.h> 38#include <sys/utsname.h>
39#include <sys/file.h>
40
35 41
36 42
43#if !defined(BB_FEATURE_LSMOD_NEW_KERNEL) && !defined(BB_FEATURE_LSMOD_OLD_KERNEL)
44#error "Must have ether BB_FEATURE_LSMOD_NEW_KERNEL or BB_FEATURE_LSMOD_OLD_KERNEL defined"
45#endif
46
47#ifdef BB_FEATURE_LSMOD_NEW_KERNEL
37 48
38struct module_info 49struct module_info
39{ 50{
@@ -120,3 +131,30 @@ extern int lsmod_main(int argc, char **argv)
120 131
121 return( 0); 132 return( 0);
122} 133}
134
135#else /*BB_FEATURE_LSMOD_OLD_KERNEL*/
136
137#if ! defined BB_FEATURE_USE_PROCFS
138#error Sorry, I depend on the /proc filesystem right now.
139#endif
140
141extern int lsmod_main(int argc, char **argv)
142{
143 int fd, i;
144 char line[128];
145
146 puts("Module Size Used by");
147 fflush(stdout);
148
149 if ((fd = open("/proc/modules", O_RDONLY)) >= 0 ) {
150 while ((i = read(fd, line, sizeof(line))) > 0) {
151 write(fileno(stdout), line, i);
152 }
153 close(fd);
154 return 0;
155 }
156 fatalError("/proc/modules: %s\n", strerror(errno));
157 return 1;
158}
159
160#endif /*BB_FEATURE_LSMOD_OLD_KERNEL*/