Patch from Jason McMullan @ linuxcare.com adding insmod

support for s390 systems.
This commit is contained in:
Eric Andersen 2003-01-23 06:02:39 +00:00
parent 853c494efd
commit bf77f61d69

View File

@ -102,6 +102,19 @@
#define ELFCLASSM ELFCLASS32 #define ELFCLASSM ELFCLASS32
#endif #endif
#if defined(__s390__)
#define BB_USE_PLT_ENTRIES
#define BB_PLT_ENTRY_SIZE 8
#define BB_USE_GOT_ENTRIES
#define BB_GOT_ENTRY_SIZE 8
#define BB_USE_SINGLE
#define MATCH_MACHINE(x) (x == EM_S390)
#define SHT_RELM SHT_RELA
#define Elf32_RelM Elf32_Rela
#define ELFCLASSM ELFCLASS32
#endif
#if defined(__i386__) #if defined(__i386__)
#define CONFIG_USE_GOT_ENTRIES #define CONFIG_USE_GOT_ENTRIES
#define CONFIG_GOT_ENTRY_SIZE 4 #define CONFIG_GOT_ENTRY_SIZE 4
@ -234,7 +247,7 @@
#ifndef MODUTILS_MODULE_H #ifndef MODUTILS_MODULE_H
static const int MODUTILS_MODULE_H = 1; static const int MODUTILS_MODULE_H = 1;
#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $" #ident "$Id: insmod.c,v 1.95 2003/01/23 06:02:39 andersen Exp $"
/* This file contains the structures used by the 2.0 and 2.1 kernels. /* This file contains the structures used by the 2.0 and 2.1 kernels.
We do not use the kernel headers directly because we do not wish We do not use the kernel headers directly because we do not wish
@ -455,7 +468,7 @@ int delete_module(const char *);
#ifndef MODUTILS_OBJ_H #ifndef MODUTILS_OBJ_H
static const int MODUTILS_OBJ_H = 1; static const int MODUTILS_OBJ_H = 1;
#ident "$Id: insmod.c,v 1.94 2003/01/23 04:57:35 andersen Exp $" #ident "$Id: insmod.c,v 1.95 2003/01/23 06:02:39 andersen Exp $"
/* The relocatable object is manipulated using elfin types. */ /* The relocatable object is manipulated using elfin types. */
@ -856,6 +869,89 @@ arch_apply_relocation(struct obj_file *f,
*loc += v - got; *loc += v - got;
break; break;
#elif defined(__s390__)
case R_390_32:
*(unsigned int *) loc += v;
break;
case R_390_16:
*(unsigned short *) loc += v;
break;
case R_390_8:
*(unsigned char *) loc += v;
break;
case R_390_PC32:
*(unsigned int *) loc += v - dot;
break;
case R_390_PC16DBL:
*(unsigned short *) loc += (v - dot) >> 1;
break;
case R_390_PC16:
*(unsigned short *) loc += v - dot;
break;
case R_390_PLT32:
case R_390_PLT16DBL:
/* find the plt entry and initialize it. */
assert(isym != NULL);
pe = (struct arch_single_entry *) &isym->pltent;
assert(pe->allocated);
if (pe->inited == 0) {
ip = (unsigned long *)(ifile->plt->contents + pe->offset);
ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */
ip[1] = 0x100607f1;
if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
ip[2] = v - 2;
else
ip[2] = v;
pe->inited = 1;
}
/* Insert relative distance to target. */
v = plt + pe->offset - dot;
if (ELF32_R_TYPE(rel->r_info) == R_390_PLT32)
*(unsigned int *) loc = (unsigned int) v;
else if (ELF32_R_TYPE(rel->r_info) == R_390_PLT16DBL)
*(unsigned short *) loc = (unsigned short) ((v + 2) >> 1);
break;
case R_390_GLOB_DAT:
case R_390_JMP_SLOT:
*loc = v;
break;
case R_390_RELATIVE:
*loc += f->baseaddr;
break;
case R_390_GOTPC:
assert(got != 0);
*(unsigned long *) loc += got - dot;
break;
case R_390_GOT12:
case R_390_GOT16:
case R_390_GOT32:
assert(isym != NULL);
assert(got != 0);
if (!isym->gotent.inited)
{
isym->gotent.inited = 1;
*(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
}
if (ELF32_R_TYPE(rel->r_info) == R_390_GOT12)
*(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff;
else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT16)
*(unsigned short *) loc += isym->gotent.offset;
else if (ELF32_R_TYPE(rel->r_info) == R_390_GOT32)
*(unsigned int *) loc += isym->gotent.offset;
break;
case R_390_GOTOFF:
assert(got != 0);
*loc += v - got;
break;
#elif defined(__i386__) #elif defined(__i386__)
case R_386_NONE: case R_386_NONE: