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 {
}
#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;
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
* 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 */
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;
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)
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",