[parisc-linux] modutils fixes
Richard Hirst
rhirst@linuxcare.com
Fri, 6 Apr 2001 12:15:12 +0100
Hi, this is a diff against modutils 2.4.5 to fix two problems:
1. On 32 bit kernels modutils used data_start to find the kernels
dp value, but it should have really used $global$. Didn't used to
matter as they were the same, but not anymore.
2. On 64 bit kernels modutils uses a different stub to call millicode
functions, which used to assume dp held the modules local value.
That wasn't a valid assumption, so I've reworked the stub such that
it doesn't use dp.
I won't rush to send this upstream as the maintainer is on holiday.
Kernel changes have been made recently relating to module support
(export $global$, set up dp for kernel threads in a module), so
make sure you are up to date there if you want to use modules.
There are also a bunch more symbols needed in parisc_ksyms.c, depending
on what you want to modularise, but I'm holding off on commiting
those as Paul has similar local changes and I don't want to make
life more complicated for him.
Richard
diff -ur -x *.o modutils-2.4.5-clean/ChangeLog modutils-2.4.5/ChangeLog
--- modutils-2.4.5-clean/ChangeLog Wed Mar 28 11:49:06 2001
+++ modutils-2.4.5/ChangeLog Fri Apr 6 11:30:00 2001
@@ -1,3 +1,6 @@
+ * hppa dp is $global$, not data_start. Richard Hirst.
+ * hppa64 stub for millicode calls must not use dp. Richard Hirst.
+
2001-03-29 Keith Owens <kaos@ocs.com.au>
modutils 2.4.5
diff -ur -x *.o modutils-2.4.5-clean/obj/obj_hppa.c modutils-2.4.5/obj/obj_hppa.c
--- modutils-2.4.5-clean/obj/obj_hppa.c Wed Mar 28 11:49:06 2001
+++ modutils-2.4.5/obj/obj_hppa.c Wed Apr 4 14:04:48 2001
@@ -383,7 +383,7 @@
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:
@@ -658,13 +658,13 @@
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 -ur -x *.o modutils-2.4.5-clean/obj/obj_hppa64.c modutils-2.4.5/obj/obj_hppa64.c
--- modutils-2.4.5-clean/obj/obj_hppa64.c Wed Mar 28 11:49:06 2001
+++ modutils-2.4.5/obj/obj_hppa64.c Fri Apr 6 11:31:16 2001
@@ -94,15 +94,15 @@
* 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 +120,10 @@
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,
};
/*======================================================================*/
@@ -575,15 +575,23 @@
*/
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;
+ 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;
- 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));
}
v = hfile->stub->header.sh_addr + se->offset;
}