diff options
author | Mystery Man <unknown@mandriva.org> | 2003-10-29 16:07:11 +0000 |
---|---|---|
committer | Mystery Man <unknown@mandriva.org> | 2003-10-29 16:07:11 +0000 |
commit | fa40f30b4253b1e05c46cc5e0c111176825b7623 (patch) | |
tree | 76cf2d26c0ce0ee7c6a2c1a1a2b65bc4d8e33029 /mdk-stage1/insmod-modutils/obj | |
parent | 327bd24f8e4291bd1882de1990dd7339f781a9cb (diff) | |
download | drakx-Corpo_2_1_1.tar drakx-Corpo_2_1_1.tar.gz drakx-Corpo_2_1_1.tar.bz2 drakx-Corpo_2_1_1.tar.xz drakx-Corpo_2_1_1.zip |
This commit was manufactured by cvs2svn to create tag 'Corpo_2_1_1'.Corpo_2_1_1
Diffstat (limited to 'mdk-stage1/insmod-modutils/obj')
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/Makefile | 11 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_alpha.c | 49 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_arm.c | 22 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_common.c | 41 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_hppa.c | 74 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_hppa64.c | 60 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_i386.c | 14 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_ia64.c | 79 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_kallsyms.c | 6 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_load.c | 29 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_m68k.c | 2 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_mips.c | 22 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_ppc.c | 35 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_reloc.c | 46 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_s390.c | 181 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_sparc.c | 2 | ||||
-rw-r--r-- | mdk-stage1/insmod-modutils/obj/obj_sparc64.c | 2 |
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> |