X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fparisc%2Fkernel%2Fmodule.c;h=f27cfe4771b88c1099995e5964cb2541440da180;hb=9464c7cf61b9433057924c36e6e02f303a00e768;hp=aee311884f3fa114c2a4fa5f5f4b0dc4fbe2d5f3;hpb=41689045f6a3cbe0550e1d34e9cc20d2e8c432ba;p=linux-2.6.git diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c index aee311884..f27cfe477 100644 --- a/arch/parisc/kernel/module.c +++ b/arch/parisc/kernel/module.c @@ -89,12 +89,6 @@ static inline int is_local(struct module *me, void *loc) return is_init(me, loc) || is_core(me, loc); } -static inline int is_local_section(struct module *me, void *loc, void *dot) -{ - return (is_init(me, loc) && is_init(me, dot)) || - (is_core(me, loc) && is_core(me, dot)); -} - #ifndef __LP64__ struct got_entry { @@ -370,14 +364,8 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) } #endif /* __LP64__ */ -enum elf_stub_type { - ELF_STUB_GOT, - ELF_STUB_MILLI, - ELF_STUB_DIRECT, -}; - static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, - enum elf_stub_type stub_type, int init_section) + int millicode, int init_section) { unsigned long i; struct stub_entry *stub; @@ -408,7 +396,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); #else -/* for 64-bit we have three kinds of stubs: +/* for 64-bit we have two kinds of stubs: * for normal function calls: * ldd 0(%dp),%dp * ldd 10(%dp), %r1 @@ -420,23 +408,18 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, * ldo 0(%r1), %r1 * ldd 10(%r1), %r1 * bve,n (%r1) - * - * for direct branches (jumps between different section of the - * same module): - * ldil 0, %r1 - * ldo 0(%r1), %r1 - * bve,n (%r1) */ - switch (stub_type) { - case ELF_STUB_GOT: + if (!millicode) + { stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ stub->insns[2] = 0xe820d000; /* bve (%r1) */ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); - break; - case ELF_STUB_MILLI: + } + else + { stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ @@ -444,17 +427,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[0] |= reassemble_21(lrsel(value, addend)); stub->insns[1] |= reassemble_14(rrsel(value, addend)); - break; - case ELF_STUB_DIRECT: - stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ - stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ - stub->insns[2] = 0xe820d002; /* bve,n (%r1) */ - - stub->insns[0] |= reassemble_21(lrsel(value, addend)); - stub->insns[1] |= reassemble_14(rrsel(value, addend)); - break; } - #endif return (Elf_Addr)stub; @@ -566,14 +539,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); + val = get_stub(me, val, addend, 0, is_init(me, loc)); val = (val - dot - 8)/4; CHECK_RELOC(val, 17) *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: /* 22-bit PC relative address; only defined for pa20 */ - val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); + val = get_stub(me, val, addend, 0, is_init(me, loc)); DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", strtab + sym->st_name, (unsigned long)loc, addend, val) @@ -670,23 +643,13 @@ int apply_relocate_add(Elf_Shdr *sechdrs, strtab + sym->st_name, loc, val); /* can we reach it locally? */ - if(!is_local_section(me, (void *)val, (void *)dot)) { - - if (is_local(me, (void *)val)) - /* this is the case where the - * symbol is local to the - * module, but in a different - * section, so stub the jump - * in case it's more than 22 - * bits away */ - val = get_stub(me, val, addend, ELF_STUB_DIRECT, - is_init(me, loc)); - else if (strncmp(strtab + sym->st_name, "$$", 2) + if(!is_local(me, (void *)val)) { + if (strncmp(strtab + sym->st_name, "$$", 2) == 0) - val = get_stub(me, val, addend, ELF_STUB_MILLI, + val = get_stub(me, val, addend, 1, is_init(me, loc)); else - val = get_stub(me, val, addend, ELF_STUB_GOT, + val = get_stub(me, val, addend, 0, is_init(me, loc)); } DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n",