diff options
Diffstat (limited to 'modutils/insmod.c')
-rw-r--r-- | modutils/insmod.c | 100 |
1 files changed, 98 insertions, 2 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index af12f36a6..5faae5251 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -102,6 +102,19 @@ | |||
102 | #define ELFCLASSM ELFCLASS32 | 102 | #define ELFCLASSM ELFCLASS32 |
103 | #endif | 103 | #endif |
104 | 104 | ||
105 | #if defined(__s390__) | ||
106 | #define BB_USE_PLT_ENTRIES | ||
107 | #define BB_PLT_ENTRY_SIZE 8 | ||
108 | #define BB_USE_GOT_ENTRIES | ||
109 | #define BB_GOT_ENTRY_SIZE 8 | ||
110 | #define BB_USE_SINGLE | ||
111 | |||
112 | #define MATCH_MACHINE(x) (x == EM_S390) | ||
113 | #define SHT_RELM SHT_RELA | ||
114 | #define Elf32_RelM Elf32_Rela | ||
115 | #define ELFCLASSM ELFCLASS32 | ||
116 | #endif | ||
117 | |||
105 | #if defined(__i386__) | 118 | #if defined(__i386__) |
106 | #define CONFIG_USE_GOT_ENTRIES | 119 | #define CONFIG_USE_GOT_ENTRIES |
107 | #define CONFIG_GOT_ENTRY_SIZE 4 | 120 | #define CONFIG_GOT_ENTRY_SIZE 4 |
@@ -234,7 +247,7 @@ | |||
234 | #ifndef MODUTILS_MODULE_H | 247 | #ifndef MODUTILS_MODULE_H |
235 | static const int MODUTILS_MODULE_H = 1; | 248 | static const int MODUTILS_MODULE_H = 1; |
236 | 249 | ||
237 | #ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $" | 250 | #ident "$Id: insmod.c,v 1.95 2003/01/23 06:02:39 andersen Exp $" |
238 | 251 | ||
239 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | 252 | /* This file contains the structures used by the 2.0 and 2.1 kernels. |
240 | We do not use the kernel headers directly because we do not wish | 253 | We do not use the kernel headers directly because we do not wish |
@@ -455,7 +468,7 @@ int delete_module(const char *); | |||
455 | #ifndef MODUTILS_OBJ_H | 468 | #ifndef MODUTILS_OBJ_H |
456 | static const int MODUTILS_OBJ_H = 1; | 469 | static const int MODUTILS_OBJ_H = 1; |
457 | 470 | ||
458 | #ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $" | 471 | #ident "$Id: insmod.c,v 1.95 2003/01/23 06:02:39 andersen Exp $" |
459 | 472 | ||
460 | /* The relocatable object is manipulated using elfin types. */ | 473 | /* The relocatable object is manipulated using elfin types. */ |
461 | 474 | ||
@@ -856,6 +869,89 @@ arch_apply_relocation(struct obj_file *f, | |||
856 | *loc += v - got; | 869 | *loc += v - got; |
857 | break; | 870 | break; |
858 | 871 | ||
872 | #elif defined(__s390__) | ||
873 | case R_390_32: | ||
874 | *(unsigned int *) loc += v; | ||
875 | break; | ||
876 | case R_390_16: | ||
877 | *(unsigned short *) loc += v; | ||
878 | break; | ||
879 | case R_390_8: | ||
880 | *(unsigned char *) loc += v; | ||
881 | break; | ||
882 | |||
883 | case R_390_PC32: | ||
884 | *(unsigned int *) loc += v - dot; | ||
885 | break; | ||
886 | case R_390_PC16DBL: | ||
887 | *(unsigned short *) loc += (v - dot) >> 1; | ||
888 | break; | ||
889 | case R_390_PC16: | ||
890 | *(unsigned short *) loc += v - dot; | ||
891 | break; | ||
892 | |||
893 | case R_390_PLT32: | ||
894 | case R_390_PLT16DBL: | ||
895 | /* find the plt entry and initialize it. */ | ||
896 | assert(isym != NULL); | ||
897 | pe = (struct arch_single_entry *) &isym->pltent; | ||
898 | assert(pe->allocated); | ||
899 | if (pe->inited == 0) { | ||
900 | ip = (unsigned long *)(ifile->plt->contents + pe->offset); | ||
901 | ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */ | ||
902 | ip[1] = 0x100607f1; | ||
903 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) | ||
904 | ip[2] = v - 2; | ||
905 | else | ||
906 | ip[2] = v; | ||
907 | pe->inited = 1; | ||
908 | } | ||
909 | |||
910 | /* Insert relative distance to target. */ | ||
911 | v = plt + pe->offset - dot; | ||
912 | if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32) | ||
913 | *(unsigned int *) loc = (unsigned int) v; | ||
914 | else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL) | ||
915 | *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1); | ||
916 | break; | ||
917 | |||
918 | case R_390_GLOB_DAT: | ||
919 | case R_390_JMP_SLOT: | ||
920 | *loc = v; | ||
921 | break; | ||
922 | |||
923 | case R_390_RELATIVE: | ||
924 | *loc += f->baseaddr; | ||
925 | break; | ||
926 | |||
927 | case R_390_GOTPC: | ||
928 | assert(got != 0); | ||
929 | *(unsigned long *) loc += got - dot; | ||
930 | break; | ||
931 | |||
932 | case R_390_GOT12: | ||
933 | case R_390_GOT16: | ||
934 | case R_390_GOT32: | ||
935 | assert(isym != NULL); | ||
936 | assert(got != 0); | ||
937 | if (!isym->gotent.inited) | ||
938 | { | ||
939 | isym->gotent.inited = 1; | ||
940 | *(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v; | ||
941 | } | ||
942 | if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12) | ||
943 | *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff; | ||
944 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16) | ||
945 | *(unsigned short *) loc += isym->gotent.offset; | ||
946 | else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32) | ||
947 | *(unsigned int *) loc += isym->gotent.offset; | ||
948 | break; | ||
949 | |||
950 | case R_390_GOTOFF: | ||
951 | assert(got != 0); | ||
952 | *loc += v - got; | ||
953 | break; | ||
954 | |||
859 | #elif defined(__i386__) | 955 | #elif defined(__i386__) |
860 | 956 | ||
861 | case R_386_NONE: | 957 | case R_386_NONE: |