All of lore.kernel.org
 help / color / mirror / Atom feed
From: "John David Anglin" <dave@hiauly1.hia.nrc.ca>
To: dave@hiauly1.hia.nrc.ca (John David Anglin)
Cc: deller@gmx.de, kyle@mcmartin.ca, carlos@systemhalted.org,
	elendil@planet.nl, 539378@bugs.debian.org,
	debian-hppa@lists.debian.org, linux-parisc@vger.kernel.org,
	randolph@tausq.org, submit@bugs.debian.org
Subject: Re: Bug#539378: [hppa]: fails to load nfs module: Global Offset Table
Date: Sat, 1 Aug 2009 15:07:13 -0400 (EDT)	[thread overview]
Message-ID: <20090801190715.0929A500B@hiauly1.hia.nrc.ca> (raw)
In-Reply-To: <20090801003740.8BBDE5160@hiauly1.hia.nrc.ca> from "John David Anglin" at Jul 31, 2009 08:37:39 pm

> >  	case ELF_STUB_GOT:
> > -		stub->insns[0] = 0x537b0000;	/* ldd 0(%dp),%dp	*/
> > +		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);
> > +		d = get_got(me, value, addend);
> > +		if (d <= 15)
> > +			stub->insns[0] |= reassemble_14(d);
> 
> reassemble_14 is wrong for ldd format 3.  Need format 5 and im5 insertion.

Since I complained about not using format 5 for small displacements,
here's an updated patch for review.  Seems to work:

dave@mx3210:/usr/src/D$ lsmod
Module                  Size  Used by
dm_snapshot            45680  0 
dm_mirror              27480  0 
dm_region_hash         17408  1 dm_mirror
dm_log                 18968  2 dm_mirror,dm_region_hash
dm_mod                111200  3 dm_snapshot,dm_mirror,dm_log
ext2                   99648  2 
sd_mod                 63792  4 
crc_t10dif              2368  1 sd_mod
tg3                   196428  0 
sym53c8xx             127568  3 
libphy                 39280  1 tg3
scsi_transport_spi     43528  1 sym53c8xx
scsi_mod              261104  3 sd_mod,sym53c8xx,scsi_transport_spi

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

Signed-off-by: John David Anglin <dave.anglin@nrc-cnrc.gc.ca>

diff --git a/arch/parisc/kernel/module.c b/arch/parisc/kernel/module.c
index ecd1c50..88989cb 100644
--- a/arch/parisc/kernel/module.c
+++ b/arch/parisc/kernel/module.c
@@ -86,8 +86,12 @@
  * the bottom of the table, which has a maximum signed displacement of
  * 0x3fff; however, since we're only going forward, this becomes
  * 0x1fff, and thus, since each GOT entry is 8 bytes long we can have
- * at most 1023 entries */
-#define MAX_GOTS	1023
+ * at most 1023 entries.
+ * To overcome this 14bit displacement with some kernel modules, we'll
+ * use instead the unusal 16bit displacement method (see reassemble_16a)
+ * which gives us a maximum positive displacement of 0x7fff, and as such 
+ * allows us to allocate up to 4095 GOT entries. */
+#define MAX_GOTS	4095
 
 /* three functions to determine where in the module core
  * or init pieces the location is */
@@ -145,12 +149,40 @@ struct stub_entry {
 /* The reassemble_* functions prepare an immediate value for
    insertion into an opcode. pa-risc uses all sorts of weird bitfields
    in the instruction to hold the value.  */
+static inline int sign_unext (int x, int len)
+{
+	int len_ones;
+
+	len_ones = (1 << len) - 1;
+	return x & len_ones;
+}
+
+static inline int low_sign_unext(int x, int len)
+{
+	int sign, temp;
+
+	sign = (x >> (len-1)) & 1;
+	temp = sign_unext (x, len-1);
+	return (temp << 1) | sign;
+}
+
 static inline int reassemble_14(int as14)
 {
 	return (((as14 & 0x1fff) << 1) |
 		((as14 & 0x2000) >> 13));
 }
 
+static inline int reassemble_16a(int as16)
+{
+	int s, t;
+
+	/* Unusual 16-bit encoding, for wide mode only.  */
+	t = (as16 << 1) & 0xffff;
+	s = (as16 & 0x8000);
+	return (t ^ s ^ (s >> 1)) | (s >> 15);
+}
+
+
 static inline int reassemble_17(int as17)
 {
 	return (((as17 & 0x10000) >> 16) |
@@ -409,6 +441,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
 	enum elf_stub_type stub_type, Elf_Addr loc0, unsigned int targetsec)
 {
 	struct stub_entry *stub;
+	int d;
 
 	/* initialize stub_offset to point in front of the section */
 	if (!me->arch.section[targetsec].stub_offset) {
@@ -462,12 +495,19 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend,
  */
 	switch (stub_type) {
 	case ELF_STUB_GOT:
-		stub->insns[0] = 0x537b0000;	/* ldd 0(%dp),%dp	*/
+		d = get_got(me, value, addend);
+		if (d <= 15) {
+			/* Format 5 */
+			stub->insns[0] = 0x0f6010db; /* ldd 0(%dp),%dp	*/
+			stub->insns[0] |= low_sign_unext(d, 5) << 16;
+		} else {
+			/* Format 3 */
+			stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp	*/
+			stub->insns[0] |= reassemble_16a(d);
+		}
 		stub->insns[1] = 0x53610020;	/* ldd 10(%dp),%r1	*/
 		stub->insns[2] = 0xe820d000;	/* bve (%r1)		*/
 		stub->insns[3] = 0x537b0030;	/* ldd 18(%dp),%dp	*/

  parent reply	other threads:[~2009-08-01 19:07 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20090731091729.1105.20608.reportbug@aragorn.fjphome.nl>
2009-07-31 18:49 ` Bug#539378: [hppa]: fails to load nfs module: Global Offset Table overflow Carlos O'Donell
2009-07-31 19:03   ` Bug#539378: [hppa]: fails to load nfs module: Global Offset Table John David Anglin
2009-07-31 21:09     ` Helge Deller
2009-07-31 21:13       ` Carlos O'Donell
2009-07-31 21:14         ` Carlos O'Donell
2009-07-31 21:26         ` John David Anglin
2009-07-31 22:00           ` Carlos O'Donell
2009-07-31 23:38             ` Kyle McMartin
2009-07-31 23:45               ` Helge Deller
2009-07-31  0:37                 ` John David Anglin
2009-07-31  1:16                   ` John David Anglin
2009-08-01  1:51                   ` Carlos O'Donell
2009-08-01 13:53                     ` John David Anglin
2009-08-01 19:07                   ` John David Anglin [this message]
2009-08-01 20:02                     ` Carlos O'Donell
2009-08-01 21:17                       ` Frans Pop
2009-08-01  8:08                 ` Frans Pop
2009-08-01  1:49               ` Carlos O'Donell
2009-07-31 21:08   ` Bug#539378: [hppa]: fails to load nfs module: Global Offset Table overflow Helge Deller

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090801190715.0929A500B@hiauly1.hia.nrc.ca \
    --to=dave@hiauly1.hia.nrc.ca \
    --cc=539378@bugs.debian.org \
    --cc=carlos@systemhalted.org \
    --cc=debian-hppa@lists.debian.org \
    --cc=deller@gmx.de \
    --cc=elendil@planet.nl \
    --cc=kyle@mcmartin.ca \
    --cc=linux-parisc@vger.kernel.org \
    --cc=randolph@tausq.org \
    --cc=submit@bugs.debian.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.