aboutsummaryrefslogtreecommitdiff
path: root/modutils/insmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'modutils/insmod.c')
-rw-r--r--modutils/insmod.c100
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
235static const int MODUTILS_MODULE_H = 1; 248static 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
456static const int MODUTILS_OBJ_H = 1; 469static 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: