summaryrefslogtreecommitdiffstats
path: root/mdk-stage1/insmod-modutils/obj
diff options
context:
space:
mode:
Diffstat (limited to 'mdk-stage1/insmod-modutils/obj')
-rw-r--r--mdk-stage1/insmod-modutils/obj/Makefile11
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_alpha.c49
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_arm.c22
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_common.c41
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_hppa.c74
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_hppa64.c60
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_i386.c14
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_ia64.c79
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_kallsyms.c6
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_load.c29
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_m68k.c2
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_mips.c22
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_ppc.c35
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_reloc.c46
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_s390.c181
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_sparc.c2
-rw-r--r--mdk-stage1/insmod-modutils/obj/obj_sparc64.c2
17 files changed, 350 insertions, 325 deletions
diff --git a/mdk-stage1/insmod-modutils/obj/Makefile b/mdk-stage1/insmod-modutils/obj/Makefile
index 34b5df2d9..d44b2a6c6 100644
--- a/mdk-stage1/insmod-modutils/obj/Makefile
+++ b/mdk-stage1/insmod-modutils/obj/Makefile
@@ -23,11 +23,16 @@ INCS = -I./../include
DEFS = -D_GNU_SOURCE -DELF_MACHINE_H='"elf_$(ARCH).h"' -DARCH_$(ARCH) -DCONFIG_ROOT_CHECK_OFF=0
-OBJS = obj_kallsyms.o obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o
+ifeq (x86_64, $(ARCH))
+DEFS += -Wno-error
+endif
+
+OBJS = obj_kallsyms.o obj_common.o obj_load.o obj_reloc.o obj_$(ARCH).o \
+ obj_gpl_license.o
libobj.a: $(OBJS)
ar cru $@ $^
ranlib $@
-.c.o:
- gcc $(CFLAGS) $(DEFS) $(INCS) $(GLIBC_INCLUDES) -c $<
+%.o: %.c
+ $(DIET) gcc $(CFLAGS) $(DEFS) $(INCS) $(INCLUDES) -c $<
diff --git a/mdk-stage1/insmod-modutils/obj/obj_alpha.c b/mdk-stage1/insmod-modutils/obj/obj_alpha.c
index 4006b3442..175012716 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_alpha.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_alpha.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
@@ -28,6 +26,12 @@
#include <obj.h>
#include <util.h>
+
+/* This relocation got renamed, and the change hasn't propagated yet. */
+#ifndef R_ALPHA_GPREL16
+#define R_ALPHA_GPREL16 R_ALPHA_IMMED_GP_16
+#endif
+
/*======================================================================*/
struct alpha_got_entry
@@ -100,6 +104,7 @@ arch_apply_relocation (struct obj_file *f,
unsigned long *lloc = (unsigned long *)(targsec->contents + rel->r_offset);
unsigned int *iloc = (unsigned int *)lloc;
+ unsigned short *sloc = (unsigned short *)lloc;
Elf64_Addr dot = targsec->header.sh_addr + rel->r_offset;
Elf64_Addr gp = af->got->header.sh_addr + 0x8000;
@@ -115,6 +120,30 @@ arch_apply_relocation (struct obj_file *f,
*lloc += v;
break;
+ case R_ALPHA_GPREL16:
+ v -= gp;
+ if ((Elf64_Sxword)v > 0x7fff
+ || (Elf64_Sxword)v < -(Elf64_Sxword)0x8000)
+ ret = obj_reloc_overflow;
+ *sloc = v;
+ break;
+
+ case R_ALPHA_GPRELLOW:
+ /* GPRELLOW does not overflow. Errors are seen in the
+ corresponding GPRELHIGH. */
+ v -= gp;
+ *sloc = v;
+ break;
+
+ case R_ALPHA_GPRELHIGH:
+ v -= gp;
+ v = ((Elf64_Sxword)v >> 16) + ((v >> 15) & 1);
+ if ((Elf64_Sxword)v > 0x7fff
+ || (Elf64_Sxword)v < -(Elf64_Sxword)0x8000)
+ ret = obj_reloc_overflow;
+ *sloc = v;
+ break;
+
case R_ALPHA_GPREL32:
v -= gp;
if ((Elf64_Sxword)v > 0x7fffffff
@@ -138,7 +167,7 @@ arch_apply_relocation (struct obj_file *f,
gotent->reloc_done = 1;
}
- *iloc = (*iloc & ~0xffff) | ((gotent->offset - 0x8000) & 0xffff);
+ *sloc = gotent->offset - 0x8000;
}
break;
@@ -233,19 +262,12 @@ arch_create_got (struct obj_file *f)
for (; rel < relend; ++rel)
{
struct alpha_got_entry *ent;
- Elf64_Sym *extsym;
struct alpha_symbol *intsym;
- const char *name;
if (ELF64_R_TYPE(rel->r_info) != R_ALPHA_LITERAL)
continue;
- extsym = &symtab[ELF64_R_SYM(rel->r_info)];
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct alpha_symbol *)obj_find_symbol(&af->root, name);
+ obj_find_relsym(intsym, f, &af->root, rel, symtab, strtab);
for (ent = intsym->got_entries; ent ; ent = ent->next)
if (ent->addend == rel->r_addend)
@@ -270,9 +292,10 @@ arch_create_got (struct obj_file *f)
}
/* We always want a .got section so that we always have a GP for
- use with GPDISP and GPREL32 relocs. Besides, if the section
+ use with GPDISP and GPREL relocs. Besides, if the section
is empty we don't use up space anyway. */
- af->got = obj_create_alloced_section(&af->root, ".got", 8, offset);
+ af->got = obj_create_alloced_section(&af->root, ".got", 8, offset,
+ SHF_WRITE | SHF_ALPHA_GPREL);
return 1;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_arm.c b/mdk-stage1/insmod-modutils/obj/obj_arm.c
index 7a843f947..78b53700c 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_arm.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_arm.c
@@ -21,8 +21,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
@@ -201,7 +199,7 @@ arch_create_got (struct obj_file *f)
struct obj_section *sec, *syms, *strs;
ElfW(Rel) *rel, *relend;
ElfW(Sym) *symtab, *extsym;
- const char *strtab, *name;
+ const char *strtab;
struct arm_symbol *intsym;
struct arm_plt_entry *pe;
struct arm_got_entry *ge;
@@ -227,11 +225,7 @@ arch_create_got (struct obj_file *f)
switch(ELF32_R_TYPE(rel->r_info)) {
case R_ARM_PC24:
case R_ARM_PLT32:
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct arm_symbol *) obj_find_symbol(f, name);
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
pe = &intsym->pltent;
@@ -252,11 +246,7 @@ arch_create_got (struct obj_file *f)
break;
case R_ARM_GOT32:
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct arm_symbol *) obj_find_symbol(f, name);
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
ge = (struct arm_got_entry *) &intsym->gotent;
if (! ge->allocated)
@@ -282,14 +272,16 @@ arch_create_got (struct obj_file *f)
obj_extend_section(sec, got_offset);
else
{
- sec = obj_create_alloced_section(f, ".got", 8, got_offset);
+ sec = obj_create_alloced_section(f, ".got", 8, got_offset,
+ SHF_WRITE);
assert(sec);
}
afile->got = sec;
}
if (plt_offset)
- afile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset);
+ afile->plt = obj_create_alloced_section(f, ".plt", 8, plt_offset,
+ SHF_WRITE);
return 1;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_common.c b/mdk-stage1/insmod-modutils/obj/obj_common.c
index 2a6606c94..a957ff1be 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_common.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_common.c
@@ -19,11 +19,10 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stdlib.h>
#include <string.h>
#include <assert.h>
+#include <alloca.h>
#include <obj.h>
#include <util.h>
@@ -229,6 +228,14 @@ obj_find_section (struct obj_file *f, const char *name)
return NULL;
}
+#if defined (ARCH_alpha)
+#define ARCH_SHF_SHORT SHF_ALPHA_GPREL
+#elif defined (ARCH_ia64)
+#define ARCH_SHF_SHORT SHF_IA_64_SHORT
+#else
+#define ARCH_SHF_SHORT 0
+#endif
+
static int
obj_load_order_prio(struct obj_section *a)
{
@@ -237,15 +244,24 @@ obj_load_order_prio(struct obj_section *a)
af = a->header.sh_flags;
ac = 0;
- if (a->name[0] != '.' || strlen(a->name) != 10 ||
- strcmp(a->name + 5, ".init")) ac |= 32;
- if (af & SHF_ALLOC) ac |= 16;
+ if (a->name[0] != '.'
+ || strlen(a->name) != 10
+ || strcmp(a->name + 5, ".init"))
+ ac |= 64;
+ if (af & SHF_ALLOC) ac |= 32;
+ if (af & SHF_EXECINSTR) ac |= 16;
if (!(af & SHF_WRITE)) ac |= 8;
- if (af & SHF_EXECINSTR) ac |= 4;
- if (a->header.sh_type != SHT_NOBITS) ac |= 2;
-#if defined(ARCH_ia64)
- if (af & SHF_IA_64_SHORT) ac -= 1;
-#endif
+ if (a->header.sh_type != SHT_NOBITS) ac |= 4;
+ /* Desired order is
+ P S AC & 7
+ .data 1 0 4
+ .got 1 1 3
+ .sdata 1 1 1
+ .sbss 0 1 1
+ .bss 0 0 0 */
+ if (strcmp (a->name, ".got") == 0) ac |= 2;
+ if (af & ARCH_SHF_SHORT)
+ ac = (ac & ~4) | 1;
return ac;
}
@@ -264,7 +280,8 @@ obj_insert_section_load_order (struct obj_file *f, struct obj_section *sec)
struct obj_section *
obj_create_alloced_section (struct obj_file *f, const char *name,
- unsigned long align, unsigned long size)
+ unsigned long align, unsigned long size,
+ unsigned long flags)
{
int newidx = f->header.e_shnum++;
struct obj_section *sec;
@@ -274,7 +291,7 @@ obj_create_alloced_section (struct obj_file *f, const char *name,
memset(sec, 0, sizeof(*sec));
sec->header.sh_type = SHT_PROGBITS;
- sec->header.sh_flags = SHF_WRITE|SHF_ALLOC;
+ sec->header.sh_flags = flags | SHF_ALLOC;
sec->header.sh_size = size;
sec->header.sh_addralign = align;
sec->name = name;
diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa.c b/mdk-stage1/insmod-modutils/obj/obj_hppa.c
index 4207e692e..a6f703c5d 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_hppa.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_hppa.c
@@ -64,36 +64,6 @@ enum hppa_fsel
e_rrsel
};
-/* This could be a call to obj_create_alloced_section() followed
- * by an overwrite of sec->header.sh_flags.
- */
-
-struct obj_section *
-obj_hppa_create_alloced_section (struct obj_file *f, const char *name,
- unsigned long align, unsigned long size,
- unsigned long sh_flags)
-{
- int newidx = f->header.e_shnum++;
- struct obj_section *sec;
-
- f->sections = xrealloc(f->sections, (newidx+1) * sizeof(sec));
- f->sections[newidx] = sec = arch_new_section();
-
- memset(sec, 0, sizeof(*sec));
- sec->header.sh_type = SHT_PROGBITS;
- sec->header.sh_flags = sh_flags;
- sec->header.sh_size = size;
- sec->header.sh_addralign = align;
- sec->name = name;
- sec->idx = newidx;
- if (size)
- sec->contents = xmalloc(size);
-
- obj_insert_section_load_order(f, sec);
-
- return sec;
-}
-
struct obj_file *
arch_new_file (void)
{
@@ -383,14 +353,14 @@ hppa_rebuild_insn (insn, value, r_format)
This is significantly less complex than what we do for shared
libraries because, obviously, modules are not shared. Also we have
no issues related to symbol visibility, lazy linking, etc.
- The kernels dp is fixed (at symbol data_start), and we can fix up any
+ The kernels dp is fixed (at symbol $global$), and we can fix up any
DPREL refs in the module to use that same dp value.
- All PCREL17F refs result in a stub with the following format:
+ All PCREL* refs result in a stub with the following format:
ldil L'func_addr,%r1
be,n R'func_addr(%sr4,%r1)
- Note, all PCREL17F get a stub, regardless of whether they are
+ Note, all PCREL* get a stub, regardless of whether they are
local or external. With local ones, and external ones to other
modules, there is a good chance we could manage without the stub.
I'll leave that for a future optimisation.
@@ -411,7 +381,8 @@ arch_create_got(struct obj_file *f)
/* Create stub section.
* XXX set flags, see obj_ia64.c
*/
- hfile->stub = obj_create_alloced_section(f, ".stub", STUB_SIZE, 0);
+ hfile->stub = obj_create_alloced_section(f, ".stub", STUB_SIZE,
+ 0, SHF_WRITE);
/* Actually this is a lot like check_relocs() in a BFD backend. We
walk all sections and all their relocations and look for ones
@@ -446,30 +417,17 @@ arch_create_got(struct obj_file *f)
continue;
case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
need_stub = 1;
break;
}
if (need_stub)
{
- Elf32_Sym *extsym;
hppa_symbol_t *hsym;
- char const *name;
int local;
- unsigned long symndx;
- symndx = ELF32_R_SYM(rel->r_info);
- extsym = symtab + symndx;
- if (ELF32_ST_BIND(extsym->st_info) == STB_LOCAL)
- hsym = (hppa_symbol_t *) f->local_symtab[symndx];
- else
- {
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- hsym = (hppa_symbol_t *)obj_find_symbol(f, name);
- }
+ obj_find_relsym(hsym, f, f, rel, symtab, strtab);
local = hsym->root.secidx <= SHN_HIRESERVE;
if (need_stub)
@@ -529,12 +487,17 @@ arch_apply_relocation(struct obj_file *f,
/* Easy. */
break;
+ case R_PARISC_SEGREL32:
+ v -= f->baseaddr;
+ break;
+
case R_PARISC_DPREL21L:
case R_PARISC_DPREL14R:
v -= dp;
break;
case R_PARISC_PCREL17F:
+ case R_PARISC_PCREL22F:
/* Find an import stub. */
assert(hsym->stub != NULL);
assert(hfile->stub != NULL);
@@ -566,6 +529,8 @@ arch_apply_relocation(struct obj_file *f,
case R_PARISC_DIR32:
case R_PARISC_PLABEL32:
case R_PARISC_PCREL17F:
+ case R_PARISC_SEGREL32:
+ case R_PARISC_PCREL22F:
fsel = e_fsel;
break;
@@ -602,6 +567,7 @@ arch_apply_relocation(struct obj_file *f,
{
case R_PARISC_DIR32:
case R_PARISC_PLABEL32:
+ case R_PARISC_SEGREL32:
r_format = 32;
break;
@@ -619,6 +585,10 @@ arch_apply_relocation(struct obj_file *f,
r_format = 14;
break;
+ case R_PARISC_PCREL22F:
+ r_format = 22;
+ break;
+
default:
abort();
}
@@ -652,13 +622,13 @@ arch_archdata (struct obj_file *f, struct obj_section *sec)
int i;
hppa_file_t *hfile = (hppa_file_t *)f;
- /* Initialise dp to the kernels dp (symbol data_start)
+ /* Initialise dp to the kernels dp (symbol $global$)
*/
for (i = 0, s = ksyms; i < nksyms; i++, s++)
- if (!strcmp((char *)s->name, "data_start"))
+ if (!strcmp((char *)s->name, "$global$"))
break;
if (i >= nksyms) {
- error("Cannot initialise dp, 'data_start' not found\n");
+ error("Cannot initialise dp, '$global$' not found\n");
return 1;
}
hfile->dp = s->value;
diff --git a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c b/mdk-stage1/insmod-modutils/obj/obj_hppa64.c
index fe32911ff..d9f1ada9d 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_hppa64.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_hppa64.c
@@ -22,8 +22,6 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
#include <stdlib.h>
@@ -94,15 +92,15 @@ typedef struct _hppa64_file_t
* e8 20 d0 00 bve (r1)
* 53 7b 00 30 ldd 18(dp),dp
*
- * We need a different stub for millicode calls, which doesn't screw
- * dp:
+ * We need a different stub for millicode calls, which doesn't depend on
+ * or modify dp:
*
- * 53 61 00 00 ldd 0(dp),r1
- * R_PARISC_LTOFF14R <.got entry offset from dp>
+ * 20 20 00 00 ldil 0,r1
+ * R_PARISC_DIR21L <addr of kernels opd entry>
+ * 34 21 00 00 ldo 0(r1),r1
+ * R_PARISC_DIR14R <addr of kernels opd entry>
* 50 21 00 20 ldd 10(r1),r1
- * e8 20 d0 00 bve (r1)
- * 08 00 02 40 nop
- *
+ * e8 20 d0 02 bve,n (r1)
*/
/* NOTE: to keep the code cleaner we make all stubs the same size.
@@ -120,10 +118,10 @@ unsigned char hppa64_stub_extern[] =
unsigned char hppa64_stub_millicode[] =
{
- 0x53, 0x61, 0x00, 0x00,
+ 0x20, 0x20, 0x00, 0x00,
+ 0x34, 0x21, 0x00, 0x00,
0x50, 0x21, 0x00, 0x20,
- 0xe8, 0x20, 0xd0, 0x00,
- 0x08, 0x00, 0x02, 0x40,
+ 0xe8, 0x20, 0xd0, 0x02,
};
/*======================================================================*/
@@ -361,6 +359,7 @@ arch_create_got(struct obj_file *f)
need_stub = TRUE;
break;
case R_PARISC_DIR64:
+ case R_PARISC_SEGREL32:
break;
case R_PARISC_FPTR64:
/* This is a simple OPD entry (only created for local symbols,
@@ -372,26 +371,10 @@ arch_create_got(struct obj_file *f)
if (need_got || need_opd || need_stub)
{
- Elf64_Sym *extsym;
hppa64_symbol_t *isym;
- const char *name;
int local;
- unsigned long symndx;
- symndx = ELF64_R_SYM(rel->r_info);
- extsym = &symtab[symndx];
- if (ELF64_ST_BIND(extsym->st_info) == STB_LOCAL)
- {
- isym = (hppa64_symbol_t *) f->local_symtab[symndx];
- }
- else
- {
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- isym = (hppa64_symbol_t *)obj_find_symbol(f, name);
- }
+ obj_find_relsym(isym, f, f, rel, symtab, strtab);
local = isym->root.secidx <= SHN_HIRESERVE;
if (need_stub)
@@ -574,16 +557,24 @@ arch_apply_relocation(struct obj_file *f,
*/
unsigned char *stub;
- if (!strncmp(isym->root.name, "$$", 2))
+ if (!strncmp(isym->root.name, "$$", 2)) {
stub = hppa64_stub_millicode;
- else
+ memcpy((Elf64_Addr *)(hfile->stub->contents + se->offset),
+ stub, SIZEOF_STUB);
+ v = (Elf64_Addr)isym->root.value;
+ ret = patch_21l(v, (Elf64_Word *)(hfile->stub->contents + se->offset));
+ if (ret == obj_reloc_ok)
+ ret = patch_14r(v, (Elf64_Word *)(hfile->stub->contents + se->offset + 4));
+ }
+ else {
stub = hppa64_stub_extern;
- se->reloc_done = TRUE;
memcpy((Elf64_Addr *)(hfile->stub->contents + se->offset),
stub, SIZEOF_STUB);
v = (Elf64_Addr)(hfile->got->header.sh_addr + ge->offset) - gp;
ret = patch_14r2(v, (Elf64_Word *)(hfile->stub->contents + se->offset));
}
+ se->reloc_done = TRUE;
+ }
v = hfile->stub->header.sh_addr + se->offset;
}
v = v - dot - 8;
@@ -597,6 +588,11 @@ arch_apply_relocation(struct obj_file *f,
loc[1] = v;
}
break;
+ case R_PARISC_SEGREL32:
+ {
+ loc[0] = v - f->baseaddr;
+ }
+ break;
case R_PARISC_FPTR64:
{
assert(isym != NULL);
diff --git a/mdk-stage1/insmod-modutils/obj/obj_i386.c b/mdk-stage1/insmod-modutils/obj/obj_i386.c
index 28df3448c..fcbce8e04 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_i386.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_i386.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
@@ -183,9 +181,7 @@ arch_create_got (struct obj_file *f)
for (; rel < relend; ++rel)
{
- Elf32_Sym *extsym;
struct i386_symbol *intsym;
- const char *name;
switch (ELF32_R_TYPE(rel->r_info))
{
@@ -199,12 +195,7 @@ arch_create_got (struct obj_file *f)
break;
}
- extsym = &symtab[ELF32_R_SYM(rel->r_info)];
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct i386_symbol *)obj_find_symbol(&ifile->root, name);
+ obj_find_relsym(intsym, f, &ifile->root, rel, symtab, strtab);
if (!intsym->gotent.offset_done)
{
@@ -216,7 +207,8 @@ arch_create_got (struct obj_file *f)
}
if (offset > 0 || gotneeded)
- ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset);
+ ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset,
+ SHF_WRITE);
return 1;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_ia64.c b/mdk-stage1/insmod-modutils/obj/obj_ia64.c
index 4f92c5d27..d207a9042 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_ia64.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_ia64.c
@@ -19,8 +19,6 @@
* Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
#include <stdlib.h>
@@ -255,14 +253,15 @@ obj_ia64_ins_imm64(Elf64_Xword v, Elf64_Addr *bundle, Elf64_Xword slot)
{
Elf64_Xword ins;
- assert(slot == 1);
+ assert(slot == 2);
+
ins = obj_ia64_ins_extract_from_bundle(bundle, slot);
- ins &= 0xffffffee000101ff;
- ins |= ((v & 0x8000000000000000) >> 28) | ((v & 0x0000000000200000)) |
+ ins &= 0xffffffe000101fff;
+ ins |= ((v & 0x8000000000000000) >> 27) | ((v & 0x0000000000200000)) |
((v & 0x00000000001f0000) << 6) | ((v & 0x000000000000ff80) << 20) |
((v & 0x000000000000007f) << 13);
obj_ia64_ins_insert_in_bundle(bundle, slot, ins);
- obj_ia64_ins_insert_in_bundle(bundle, ++slot, ((v & 0x7fffffffffc00000) >> 22));
+ obj_ia64_ins_insert_in_bundle(bundle, --slot, ((v & 0x7fffffffffc00000) >> 22));
return obj_reloc_ok;
}
@@ -295,30 +294,6 @@ obj_ia64_generate_plt(Elf64_Addr v,
(Elf64_Addr *)(ifile->pltt->contents + pltent->text_offset), 0);
}
-struct obj_section *
-obj_ia64_create_alloced_section (struct obj_file *f, const char *name,
- unsigned long align, unsigned long size, unsigned long sh_flags)
-{
- int newidx = f->header.e_shnum++;
- struct obj_section *sec;
-
- f->sections = xrealloc(f->sections, (newidx+1) * sizeof(sec));
- f->sections[newidx] = sec = arch_new_section();
-
- memset(sec, 0, sizeof(*sec));
- sec->header.sh_type = SHT_PROGBITS;
- sec->header.sh_flags = sh_flags;
- sec->header.sh_size = size;
- sec->header.sh_addralign = align;
- sec->name = name;
- sec->idx = newidx;
- if (size)
- sec->contents = xmalloc(size);
-
- obj_insert_section_load_order(f, sec);
-
- return sec;
-}
/*======================================================================*/
@@ -457,26 +432,10 @@ arch_create_got(struct obj_file *f)
if (need_got || need_opd || need_plt)
{
- Elf64_Sym *extsym;
ia64_symbol_t *isym;
- const char *name;
int local;
- unsigned long symndx;
- symndx = ELF64_R_SYM(rel->r_info);
- extsym = &symtab[symndx];
- if (ELF64_ST_BIND(extsym->st_info) == STB_LOCAL)
- {
- isym = (ia64_symbol_t *) f->local_symtab[symndx];
- }
- else
- {
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- isym = (ia64_symbol_t *)obj_find_symbol(f, name);
- }
+ obj_find_relsym(isym, f, f, rel, symtab, strtab);
local = isym->root.secidx <= SHN_HIRESERVE;
if (need_plt)
@@ -545,20 +504,22 @@ arch_create_got(struct obj_file *f)
}
}
- ifile->got = obj_ia64_create_alloced_section(f, ".got", 8, got_offset,
- (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT));
+ ifile->got = obj_create_alloced_section(f, ".got", 8, got_offset,
+ SHF_WRITE | SHF_IA_64_SHORT);
assert(ifile->got != NULL);
- ifile->opd = obj_ia64_create_alloced_section(f, ".opd", 16, opd_offset,
- (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT));
+ ifile->opd = obj_create_alloced_section(f, ".opd", 16, opd_offset,
+ SHF_WRITE | SHF_IA_64_SHORT);
assert(ifile->opd != NULL);
if (plt_text_offset > 0)
{
- ifile->pltt = obj_ia64_create_alloced_section(f, ".plt", 16,
- plt_text_offset, (SHF_ALLOC | SHF_EXECINSTR | SHF_IA_64_SHORT));
- ifile->pltd = obj_ia64_create_alloced_section(f, ".IA_64.pltoff",
- 16, plt_data_offset, (SHF_ALLOC | SHF_WRITE | SHF_IA_64_SHORT));
+ ifile->pltt = obj_create_alloced_section(f, ".plt", 16,
+ plt_text_offset,
+ SHF_WRITE | SHF_IA_64_SHORT);
+ ifile->pltd = obj_create_alloced_section(f, ".IA_64.pltoff", 16,
+ plt_data_offset,
+ SHF_WRITE | SHF_IA_64_SHORT);
assert(ifile->pltt != NULL);
assert(ifile->pltd != NULL);
}
@@ -950,12 +911,8 @@ arch_apply_relocation(struct obj_file *f,
case R_IA64_SEGREL32LSB : /* @segrel(sym + add), data4 LSB */
case R_IA64_SEGREL64LSB : /* @segrel(sym + add), data8 LSB */
- if (targsec->header.sh_type & SHT_NOBITS)
- v = ifile->bss - v;
- else if (targsec->header.sh_flags & SHF_EXECINSTR)
- v = ifile->text - v;
- else
- v = ifile->data - v;
+ /* Only one segment for modules, see segment_base in arch_archdata */
+ v -= f->sections[1]->header.sh_addr;
if (r_info == R_IA64_SEGREL32LSB)
COPY_32LSB(loc, v);
else
diff --git a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c b/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c
index 8385fb892..1836141e9 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_kallsyms.c
@@ -17,8 +17,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
@@ -37,7 +35,7 @@ static void
append_string (const char *s, char **strings,
ElfW(Word) *strings_size, ElfW(Word) *strings_left)
{
- int l = strlen(s) + 1;
+ size_t l = strlen(s) + 1;
while (l > *strings_left) {
*strings = xrealloc(*strings, *strings_size += EXPAND_BY);
*strings_left += EXPAND_BY;
@@ -54,7 +52,7 @@ append_symbol (const struct kallsyms_symbol *s,
struct kallsyms_symbol **symbols,
ElfW(Word) *symbols_size, ElfW(Word) *symbols_left)
{
- int l = sizeof(*s);
+ size_t l = sizeof(*s);
while (l > *symbols_left) {
*symbols = xrealloc(*symbols, *symbols_size += EXPAND_BY);
*symbols_left += EXPAND_BY;
diff --git a/mdk-stage1/insmod-modutils/obj/obj_load.c b/mdk-stage1/insmod-modutils/obj/obj_load.c
index 4db20a998..62977acb7 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_load.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_load.c
@@ -21,8 +21,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <alloca.h>
#include <string.h>
#include <stdlib.h>
@@ -52,7 +50,7 @@ obj_load (int fp, Elf32_Half e_type, const char *filename)
gzf_lseek(fp, 0, SEEK_SET);
if (gzf_read(fp, &f->header, sizeof(f->header)) != sizeof(f->header))
{
- error("error reading ELF header %s: %m", filename);
+ error("cannot read ELF header from %s", filename);
return NULL;
}
@@ -257,7 +255,7 @@ obj_load (int fp, Elf32_Half e_type, const char *filename)
{
case SHT_RELM:
{
- unsigned long nrel, j;
+ unsigned long nrel, j, nsyms;
ElfW(RelM) *rel;
struct obj_section *symtab;
char *strtab;
@@ -273,34 +271,25 @@ obj_load (int fp, Elf32_Half e_type, const char *filename)
nrel = sec->header.sh_size / sizeof(ElfW(RelM));
rel = (ElfW(RelM) *) sec->contents;
symtab = f->sections[sec->header.sh_link];
+ nsyms = symtab->header.sh_size / symtab->header.sh_entsize;
strtab = f->sections[symtab->header.sh_link]->contents;
/* Save the relocate type in each symbol entry. */
for (j = 0; j < nrel; ++j, ++rel)
{
- ElfW(Sym) *extsym;
struct obj_symbol *intsym;
unsigned long symndx;
symndx = ELFW(R_SYM)(rel->r_info);
if (symndx)
{
- extsym = ((ElfW(Sym) *) symtab->contents) + symndx;
- if (ELFW(ST_BIND)(extsym->st_info) == STB_LOCAL)
- {
- /* Local symbols we look up in the local table to be sure
- we get the one that is really intended. */
- intsym = f->local_symtab[symndx];
- }
- else
+ if (symndx >= nsyms)
{
- /* Others we look up in the hash table. */
- const char *name;
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = obj_find_symbol(f, name);
+ error("%s: Bad symbol index: %08lx >= %08lx",
+ filename, symndx, nsyms);
+ continue;
}
+
+ obj_find_relsym(intsym, f, f, rel, (ElfW(Sym) *)(symtab->contents), strtab);
intsym->r_type = ELFW(R_TYPE)(rel->r_info);
}
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_m68k.c b/mdk-stage1/insmod-modutils/obj/obj_m68k.c
index cb485aed7..abc070bca 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_m68k.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_m68k.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stddef.h>
#include <module.h>
#include <obj.h>
diff --git a/mdk-stage1/insmod-modutils/obj/obj_mips.c b/mdk-stage1/insmod-modutils/obj/obj_mips.c
index c2315b659..2db0791b6 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_mips.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_mips.c
@@ -18,8 +18,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <stdlib.h>
#include <assert.h>
@@ -232,7 +230,25 @@ arch_finalize_section_address(struct obj_file *f, Elf32_Addr base)
}
int
-arch_archdata (struct obj_file *fin, struct obj_section *sec)
+arch_archdata (struct obj_file *f, struct obj_section *archdata_sec)
{
+ struct archdata {
+ unsigned tgt_long __start___dbe_table;
+ unsigned tgt_long __stop___dbe_table;
+ } *ad;
+ struct obj_section *sec;
+
+ if (archdata_sec->contents)
+ free(archdata_sec->contents);
+ archdata_sec->header.sh_size = 0;
+ sec = obj_find_section(f, "__dbe_table");
+ if (sec) {
+ ad = (struct archdata *) (archdata_sec->contents) = xmalloc(sizeof(*ad));
+ memset(ad, 0, sizeof(*ad));
+ archdata_sec->header.sh_size = sizeof(*ad);
+ ad->__start___dbe_table = sec->header.sh_addr;
+ ad->__stop___dbe_table = sec->header.sh_addr + sec->header.sh_size;
+ }
+
return 0;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_ppc.c b/mdk-stage1/insmod-modutils/obj/obj_ppc.c
index 89bb8e46b..4889454f2 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_ppc.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_ppc.c
@@ -20,8 +20,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stddef.h>
#include <module.h>
#include <obj.h>
@@ -180,8 +178,8 @@ arch_create_got (struct obj_file *f)
int i, offset;
struct obj_section *sec, *syms, *strs;
ElfW(Rela) *rel, *relend;
- ElfW(Sym) *symtab, *extsym;
- const char *strtab, *name;
+ ElfW(Sym) *symtab;
+ const char *strtab;
struct ppc_symbol *intsym;
struct ppc_plt_entry *pe;
@@ -203,12 +201,7 @@ arch_create_got (struct obj_file *f)
{
if (ELF32_R_TYPE(rel->r_info) != R_PPC_REL24)
continue;
- extsym = &symtab[ELF32_R_SYM(rel->r_info)];
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct ppc_symbol *) obj_find_symbol(f, name);
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
for (pe = intsym->plt_entries; pe != NULL; pe = pe->next)
if (pe->addend == rel->r_addend)
@@ -226,7 +219,7 @@ arch_create_got (struct obj_file *f)
}
}
- pf->plt = obj_create_alloced_section(f, ".plt", 16, offset);
+ pf->plt = obj_create_alloced_section(f, ".plt", 16, offset, SHF_WRITE);
return 1;
}
@@ -249,7 +242,25 @@ arch_finalize_section_address(struct obj_file *f, Elf32_Addr base)
}
int
-arch_archdata (struct obj_file *fin, struct obj_section *sec)
+arch_archdata (struct obj_file *f, struct obj_section *archdata_sec)
{
+ struct archdata {
+ unsigned tgt_long __start___ftr_fixup;
+ unsigned tgt_long __stop___ftr_fixup;
+ } *ad;
+ struct obj_section *sec;
+
+ if (archdata_sec->contents)
+ free(archdata_sec->contents);
+ archdata_sec->header.sh_size = 0;
+ sec = obj_find_section(f, "__ftr_fixup");
+ if (sec) {
+ ad = (struct archdata *) (archdata_sec->contents) = xmalloc(sizeof(*ad));
+ memset(ad, 0, sizeof(*ad));
+ archdata_sec->header.sh_size = sizeof(*ad);
+ ad->__start___ftr_fixup = sec->header.sh_addr;
+ ad->__stop___ftr_fixup = sec->header.sh_addr + sec->header.sh_size;
+ }
+
return 0;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_reloc.c b/mdk-stage1/insmod-modutils/obj/obj_reloc.c
index f5f2de90d..3f2c8aab0 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_reloc.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_reloc.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
#include <alloca.h>
@@ -48,7 +46,7 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,
strsec = obj_find_section(f, ".kstrtab");
if (strsec == NULL)
{
- strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);
+ strsec = obj_create_alloced_section(f, ".kstrtab", 1, len, 0);
p->string_offset = 0;
loc = strsec->contents;
}
@@ -284,6 +282,7 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base)
ElfW(RelM) *rel, *relend;
ElfW(Sym) *symtab;
const char *strtab;
+ unsigned long nsyms;
relsec = f->sections[i];
if (relsec->header.sh_type != SHT_RELM)
@@ -293,9 +292,13 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base)
targsec = f->sections[relsec->header.sh_info];
strsec = f->sections[symsec->header.sh_link];
+ if (!(targsec->header.sh_flags & SHF_ALLOC))
+ continue;
+
rel = (ElfW(RelM) *)relsec->contents;
relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM)));
symtab = (ElfW(Sym) *)symsec->contents;
+ nsyms = symsec->header.sh_size / symsec->header.sh_entsize;
strtab = (const char *)strsec->contents;
for (; rel < relend; ++rel)
@@ -303,7 +306,6 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base)
ElfW(Addr) value = 0;
struct obj_symbol *intsym = NULL;
unsigned long symndx;
- ElfW(Sym) *extsym = 0;
const char *errmsg;
/* Attempt to find a value to use for this relocation. */
@@ -313,33 +315,18 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base)
{
/* Note we've already checked for undefined symbols. */
- extsym = &symtab[symndx];
- if (ELFW(ST_BIND)(extsym->st_info) == STB_LOCAL)
- {
- /* Local symbols we look up in the local table to be sure
- we get the one that is really intended. */
- intsym = f->local_symtab[symndx];
- }
- else
+ if (symndx >= nsyms)
{
- /* Others we look up in the hash table. */
- const char *name;
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = obj_find_symbol(f, name);
+ error("Bad symbol index: %08lx >= %08lx",
+ symndx, nsyms);
+ continue;
}
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
value = obj_symbol_final_value(f, intsym);
}
#if SHT_RELM == SHT_RELA
-#if defined(__alpha__) && defined(AXP_BROKEN_GAS)
- /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */
- if (!extsym || !extsym->st_name ||
- ELFW(ST_BIND)(extsym->st_info) != STB_LOCAL)
-#endif
value += rel->r_addend;
#endif
@@ -362,17 +349,8 @@ obj_relocate (struct obj_file *f, ElfW(Addr) base)
errmsg = "Modules compiled with -mconstant-gp cannot be loaded";
goto bad_reloc;
bad_reloc:
- if (extsym)
- {
error("%s of type %ld for %s", errmsg,
- (long)ELFW(R_TYPE)(rel->r_info),
- strtab + extsym->st_name);
- }
- else
- {
- error("%s of type %ld", errmsg,
- (long)ELFW(R_TYPE)(rel->r_info));
- }
+ (long)ELFW(R_TYPE)(rel->r_info), intsym->name);
ret = 0;
break;
}
diff --git a/mdk-stage1/insmod-modutils/obj/obj_s390.c b/mdk-stage1/insmod-modutils/obj/obj_s390.c
index 3da72e771..a76e28479 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_s390.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_s390.c
@@ -1,6 +1,10 @@
-/* S/390 specific support for Elf loading and relocation.
- Copyright 1996, 1997 Linux International.
+/* IBM S/390 31-bit specific support for Elf loading and relocation.
+ Copyright 2000, 2001 IBM Deutschland Entwicklung GmbH, IBM Corporation.
+ Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>
+
+ Derived from obj/obj_i386.c:
+ Copyright 1996, 1997 Linux International.
Contributed by Richard Henderson <rth@tamu.edu>
This file is part of the Linux modutils.
@@ -19,8 +23,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <string.h>
#include <assert.h>
@@ -31,22 +33,31 @@
/*======================================================================*/
+struct s390_plt_entry
+{
+ long offset;
+ int allocated:1;
+ int initialized:1;
+};
+
struct s390_got_entry
{
- int offset;
- unsigned offset_done : 1;
+ long offset;
+ unsigned allocated:1;
unsigned reloc_done : 1;
};
struct s390_file
{
struct obj_file root;
+ struct obj_section *plt;
struct obj_section *got;
};
struct s390_symbol
{
struct obj_symbol root;
+ struct s390_plt_entry pltent;
struct s390_got_entry gotent;
};
@@ -59,6 +70,7 @@ arch_new_file (void)
struct s390_file *f;
f = xmalloc(sizeof(*f));
f->got = NULL;
+ f->plt = NULL;
return &f->root;
}
@@ -74,6 +86,7 @@ arch_new_symbol (void)
struct s390_symbol *sym;
sym = xmalloc(sizeof(*sym));
memset(&sym->gotent, 0, sizeof(sym->gotent));
+ memset(&sym->pltent, 0, sizeof(sym->pltent));
return &sym->root;
}
@@ -95,12 +108,14 @@ arch_apply_relocation (struct obj_file *f,
Elf32_Rela *rel,
Elf32_Addr v)
{
- struct s390_file *ifile = (struct s390_file *)f;
- struct s390_symbol *isym = (struct s390_symbol *)sym;
+ struct s390_file *ifile = (struct s390_file *) f;
+ struct s390_symbol *isym = (struct s390_symbol *) sym;
+ struct s390_plt_entry *pe;
Elf32_Addr *loc = (Elf32_Addr *)(targsec->contents + rel->r_offset);
Elf32_Addr dot = targsec->header.sh_addr + rel->r_offset;
Elf32_Addr got = ifile->got ? ifile->got->header.sh_addr : 0;
+ Elf32_Addr plt = ifile->plt ? ifile->plt->header.sh_addr : 0;
enum obj_reloc ret = obj_reloc_ok;
@@ -110,12 +125,48 @@ arch_apply_relocation (struct obj_file *f,
break;
case R_390_32:
- *loc += v;
+ *(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_PLT32:
case R_390_PC32:
- *loc += v - dot;
+ *(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 s390_plt_entry *) &isym->pltent;
+ assert(pe->allocated);
+ if (pe->initialized == 0) {
+ unsigned int *ip = (unsigned int *)(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->initialized = 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:
@@ -129,17 +180,25 @@ arch_apply_relocation (struct obj_file *f,
case R_390_GOTPC:
assert(got != 0);
- *loc += got - dot;
+ *(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.reloc_done)
{
isym->gotent.reloc_done = 1;
*(Elf32_Addr *)(ifile->got->contents + isym->gotent.offset) = v;
}
- *loc += isym->gotent.offset;
+ 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:
@@ -158,71 +217,98 @@ arch_apply_relocation (struct obj_file *f,
int
arch_create_got (struct obj_file *f)
{
- struct s390_file *ifile = (struct s390_file *)f;
- int i, n, offset = 0, gotneeded = 0;
+ struct s390_file *ifile = (struct s390_file *) f;
+ int i, got_offset = 0, plt_offset = 0, gotneeded = 0;
- n = ifile->root.header.e_shnum;
- for (i = 0; i < n; ++i)
+ for (i = 0; i < f->header.e_shnum; ++i)
{
struct obj_section *relsec, *symsec, *strsec;
- Elf32_Rel *rel, *relend;
+ Elf32_Rela *rel, *relend;
Elf32_Sym *symtab;
const char *strtab;
- relsec = ifile->root.sections[i];
- if (relsec->header.sh_type != SHT_REL)
+ relsec = f->sections[i];
+ if (relsec->header.sh_type != SHT_RELA)
continue;
- symsec = ifile->root.sections[relsec->header.sh_link];
- strsec = ifile->root.sections[symsec->header.sh_link];
+ symsec = f->sections[relsec->header.sh_link];
+ strsec = f->sections[symsec->header.sh_link];
- rel = (Elf32_Rel *)relsec->contents;
- relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rel));
+ rel = (Elf32_Rela *)relsec->contents;
+ relend = rel + (relsec->header.sh_size / sizeof(Elf32_Rela));
symtab = (Elf32_Sym *)symsec->contents;
strtab = (const char *)strsec->contents;
for (; rel < relend; ++rel)
{
- Elf32_Sym *extsym;
struct s390_symbol *intsym;
- const char *name;
-
- switch (ELF32_R_TYPE(rel->r_info))
- {
+ struct s390_plt_entry *pe;
+ struct s390_got_entry *ge;
+
+ switch (ELF32_R_TYPE(rel->r_info)) {
+ /* These four relocations refer to a plt entry. */
+ case R_390_PLT16DBL:
+ case R_390_PLT32:
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
+ assert(intsym);
+ pe = &intsym->pltent;
+ if (!pe->allocated) {
+ pe->allocated = 1;
+ pe->offset = plt_offset;
+ plt_offset += 12;
+ }
+ break;
+ /* The next three don't need got entries but the address
+ of the got itself. */
case R_390_GOTPC:
case R_390_GOTOFF:
gotneeded = 1;
- default:
- continue;
+ break;
+ case R_390_GOT12:
+ case R_390_GOT16:
case R_390_GOT32:
- break;
+ obj_find_relsym(intsym, f, f, rel, symtab, strtab);
+ assert(intsym);
+ ge = (struct s390_got_entry *) &intsym->gotent;
+ if (!ge->allocated) {
+ ge->allocated = 1;
+ ge->offset = got_offset;
+ got_offset += sizeof(void*);
}
+ break;
- extsym = &symtab[ELF32_R_SYM(rel->r_info)];
- if (extsym->st_name)
- name = strtab + extsym->st_name;
- else
- name = f->sections[extsym->st_shndx]->name;
- intsym = (struct s390_symbol *)obj_find_symbol(&ifile->root, name);
-
- if (!intsym->gotent.offset_done)
- {
- intsym->gotent.offset_done = 1;
- intsym->gotent.offset = offset;
- offset += 4;
+ default:
+ break;
}
}
}
- if (offset > 0 || gotneeded)
- ifile->got = obj_create_alloced_section(&ifile->root, ".got", 4, offset);
+ if (got_offset > 0 || gotneeded) {
+ struct obj_section *gotsec;
+ struct obj_symbol *gotsym;
+
+ gotsec = obj_find_section(f, ".got");
+ if (gotsec == NULL)
+ gotsec = obj_create_alloced_section(f, ".got", 4, got_offset, SHF_WRITE);
+ else
+ obj_extend_section(gotsec, got_offset);
+ gotsym = obj_add_symbol(f, "_GLOBAL_OFFSET_TABLE_", -1,
+ ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT),
+ gotsec->idx, 0, 0);
+ gotsym->secidx = gotsec->idx; /* mark the symbol as defined */
+ ifile->got = gotsec;
+ }
+
+ if (plt_offset > 0)
+ ifile->plt = obj_create_alloced_section(f, ".plt", 4, plt_offset,
+ SHF_WRITE);
return 1;
}
int
-arch_init_module (struct obj_file *f, struct module *m)
+arch_init_module (struct obj_file *f, struct module *mod)
{
return 1;
}
@@ -243,3 +329,4 @@ arch_archdata (struct obj_file *fin, struct obj_section *sec)
{
return 0;
}
+
diff --git a/mdk-stage1/insmod-modutils/obj/obj_sparc.c b/mdk-stage1/insmod-modutils/obj/obj_sparc.c
index 1a03c9090..d1eb3da44 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_sparc.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_sparc.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stddef.h>
#include <module.h>
#include <obj.h>
diff --git a/mdk-stage1/insmod-modutils/obj/obj_sparc64.c b/mdk-stage1/insmod-modutils/obj/obj_sparc64.c
index 84e8d18a0..f025667f8 100644
--- a/mdk-stage1/insmod-modutils/obj/obj_sparc64.c
+++ b/mdk-stage1/insmod-modutils/obj/obj_sparc64.c
@@ -19,8 +19,6 @@
along with this program; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-#ident "$Id$"
-
#include <stddef.h>
#include <module.h>
#include <obj.h>