From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from list by lists.gnu.org with archive (Exim 4.71) id 1RM1dN-00010j-5L for mharc-grub-devel@gnu.org; Thu, 03 Nov 2011 14:03:25 -0400 Received: from eggs.gnu.org ([140.186.70.92]:60195) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RM1dE-0000jf-Qk for grub-devel@gnu.org; Thu, 03 Nov 2011 14:03:21 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1RM1dC-0004qI-TE for grub-devel@gnu.org; Thu, 03 Nov 2011 14:03:16 -0400 Received: from mail-wy0-f169.google.com ([74.125.82.169]:46345) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1RM1dC-0004q7-Lg for grub-devel@gnu.org; Thu, 03 Nov 2011 14:03:14 -0400 Received: by wyg24 with SMTP id 24so1875516wyg.0 for ; Thu, 03 Nov 2011 11:03:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type; bh=81zRFmfCqK9puGFjJH59Cecw/WNQPmhyvZLmWtLUcYE=; b=HVa/RyffHuK1BcJbbC+bpnDh0vXgwEG3p17A2EVougsx0otEEW6NguZvCOqsKzH1+M mEXOOdZFa71qTes4FqbO+hWx7q7sNiZSH64BDvJIf/G0DrMu1Ad1i9Wr9UDDfKs/1LvY QkzaWE0PmRG/vsjdKY0UCLkTfZYW/RRFF0lZ4= Received: by 10.227.202.140 with SMTP id fe12mr13099449wbb.27.1320343393237; Thu, 03 Nov 2011 11:03:13 -0700 (PDT) Received: from debian.x201.phnet (gprs03.swisscom-mobile.ch. [193.247.250.3]) by mx.google.com with ESMTPS id fw16sm11541198wbb.13.2011.11.03.11.03.11 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 03 Nov 2011 11:03:12 -0700 (PDT) Message-ID: <4EB2D75D.3020706@gmail.com> Date: Thu, 03 Nov 2011 19:03:09 +0100 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.23) Gecko/20111010 Iceowl/1.0b2 Icedove/3.1.15 MIME-Version: 1.0 To: grub-devel@gnu.org Subject: Re: [PATCH] Fix module relocation errors on PowerPC References: <20111018154817.752a92f6@kryten> In-Reply-To: <20111018154817.752a92f6@kryten> X-Enigmail-Version: 1.1.2 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig70C35FEB569F2258E2B0E390" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.169 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Nov 2011 18:03:22 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig70C35FEB569F2258E2B0E390 Content-Type: multipart/mixed; boundary="------------030700070006060604000702" This is a multi-part message in MIME format. --------------030700070006060604000702 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Please try the attached patch On 18.10.2011 06:48, Anton Blanchard wrote: > Hi, > > I tried grub2 on a POWER6 box and got: > > > Welcome to GRUB! > > error: relocation overflow. > Entering rescue mode... > > > Modules (and therefore the heap) need to be close to the executable to > avoid requiring more complicated relocations. This patch uses the same > method sparc does and puts the heap directly above the executable. > > We use the OF stack so we don't need to reserve any memory for it. Is > it time to create GRUB_MACHINE_POWERPC? > > Anton > > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------030700070006060604000702 Content-Type: text/x-diff; name="ppc_tramp.diff" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="ppc_tramp.diff" =3D=3D=3D modified file 'grub-core/kern/dl.c' --- grub-core/kern/dl.c 2011-07-06 15:40:36 +0000 +++ grub-core/kern/dl.c 2011-11-03 17:54:44 +0000 @@ -233,7 +233,7 @@ unsigned i; Elf_Shdr *s; grub_size_t tsize =3D 0, talign =3D 1; -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) grub_size_t tramp; grub_size_t got; #endif @@ -248,9 +248,9 @@ talign =3D s->sh_addralign; } =20 -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) grub_arch_dl_get_tramp_got_size (e, &tramp, &got); - tramp *=3D GRUB_IA64_DL_TRAMP_SIZE; + tramp *=3D GRUB_ARCH_DL_TRAMP_SIZE; got *=3D sizeof (grub_uint64_t); tsize +=3D ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN); if (talign < GRUB_ARCH_DL_TRAMP_ALIGN) @@ -316,7 +316,7 @@ mod->segment =3D seg; } } -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) ptr =3D (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN= ); mod->tramp =3D ptr; ptr +=3D tramp; @@ -575,15 +575,9 @@ static void grub_dl_flush_cache (grub_dl_t mod) { - grub_dl_segment_t seg; - - for (seg =3D mod->segment; seg; seg =3D seg->next) { - if (seg->size) { - grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", - (unsigned long) seg->size, seg->addr); - grub_arch_sync_caches (seg->addr, seg->size); - } - } + grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n", + (unsigned long) mod->sz, mod->base); + grub_arch_sync_caches (mod->base, mod->sz); } =20 /* Load a module from core memory. */ =3D=3D=3D modified file 'grub-core/kern/ia64/dl.c' --- grub-core/kern/ia64/dl.c 2011-05-08 15:07:40 +0000 +++ grub-core/kern/ia64/dl.c 2011-11-03 17:52:40 +0000 @@ -104,13 +104,13 @@ } } =20 -static grub_uint8_t nopm[5] =3D +static const grub_uint8_t nopm[5] =3D { /* [MLX] nop.m 0x0 */ 0x05, 0x00, 0x00, 0x00, 0x01 }; =20 -static grub_uint8_t jump[0x20] =3D +static const grub_uint8_t jump[0x20] =3D { /* ld8 r16=3D[r15],8 */ 0x02, 0x80, 0x20, 0x1e, 0x18, 0x14, =3D=3D=3D modified file 'grub-core/kern/powerpc/dl.c' --- grub-core/kern/powerpc/dl.c 2010-01-03 22:05:07 +0000 +++ grub-core/kern/powerpc/dl.c 2011-11-03 17:52:01 +0000 @@ -37,6 +37,65 @@ return GRUB_ERR_NONE; } =20 +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got) +{ + const Elf_Ehdr *e =3D ehdr; + const Elf_Shdr *s; + Elf_Word entsize; + unsigned i; + + *tramp =3D 0; + *got =3D 0; + + /* Find a symbol table. */ + for (i =3D 0, s =3D (const Elf_Shdr *) ((const char *) e + e->e_shoff)= ; + i < e->e_shnum; + i++, s =3D (const Elf_Shdr *) ((const char *) s + e->e_shentsize)= ) + if (s->sh_type =3D=3D SHT_SYMTAB) + break; + + if (i =3D=3D e->e_shnum) + return; + + entsize =3D s->sh_entsize; + + for (i =3D 0, s =3D (const Elf_Shdr *) ((const char *) e + e->e_shoff)= ; + i < e->e_shnum; + i++, s =3D (const Elf_Shdr *) ((const char *) s + e->e_shentsize)= ) + if (s->sh_type =3D=3D SHT_RELA) + { + const Elf_Rela *rel, *max; +=09 + for (rel =3D (const Elf_Rela *) ((const char *) e + s->sh_offset), + max =3D rel + s->sh_size / s->sh_entsize; + rel < max; + rel++) + if (ELF_R_TYPE (rel->r_info) =3D=3D R_PPC_REL24) + (*tramp)++; +=09 + } + + return; +} + +/* For low-endian reverse lis and addr_high as well as ori and addr_low.= */ +struct trampoline +{ + grub_uint32_t lis; + grub_uint32_t ori; + grub_uint32_t mtctr; + grub_uint32_t bctr; +}; + +static const struct trampoline trampoline_template =3D=20 + { + 0x3c000000, + 0x60000000, + 0x7c0903a6, + 0x4e800420, + }; =20 /* Relocate symbols. */ grub_err_t @@ -46,6 +105,7 @@ Elf_Shdr *s; Elf_Word entsize; unsigned i; + struct trampoline *tptr =3D mod->tramp; =20 /* Find a symbol table. */ for (i =3D 0, s =3D (Elf_Shdr *) ((char *) e + e->e_shoff); @@ -105,6 +165,18 @@ { Elf_Sword delta =3D value - (Elf_Word) addr; =20 + //if (delta << 6 >> 6 !=3D delta) + { + COMPILE_TIME_ASSERT (sizeof (struct trampoline) + =3D=3D GRUB_ARCH_DL_TRAMP_SIZE); + grub_memcpy (tptr, &trampoline_template, + sizeof (*tptr)); + delta =3D (grub_uint8_t *) tptr - (grub_uint8_t *) addr; + tptr->lis |=3D (((value) >> 16) & 0xffff); + tptr->ori |=3D ((value) & 0xffff); + tptr++; + } + =09 if (delta << 6 >> 6 !=3D delta) return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow"); *addr =3D (*addr & 0xfc000003) | (delta & 0x3fffffc); =3D=3D=3D modified file 'include/grub/dl.h' --- include/grub/dl.h 2011-06-23 22:29:21 +0000 +++ include/grub/dl.h 2011-11-03 17:54:10 +0000 @@ -136,11 +136,12 @@ Elf_Sym *symtab; void (*init) (struct grub_dl *mod); void (*fini) (void); -#ifdef __ia64__ +#if defined (__ia64__) || defined (__powerpc__) void *got; void *tramp; #endif void *base; + grub_size_t sz; struct grub_dl *next; }; typedef struct grub_dl *grub_dl_t; @@ -176,10 +177,20 @@ grub_ia64_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, grub_size_t *got); =20 -#ifdef __ia64__ +#if defined (__ia64__) #define GRUB_ARCH_DL_TRAMP_ALIGN 16 #define GRUB_ARCH_DL_GOT_ALIGN 16 #define grub_arch_dl_get_tramp_got_size grub_ia64_dl_get_tramp_got_size +#else +void +grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp, + grub_size_t *got); +#endif + +#ifdef __powerpc__ +#define GRUB_ARCH_DL_TRAMP_SIZE 16 +#define GRUB_ARCH_DL_TRAMP_ALIGN 4 +#define GRUB_ARCH_DL_GOT_ALIGN 4 #endif =20 #endif =3D=3D=3D modified file 'include/grub/kernel.h' --- include/grub/kernel.h 2011-10-18 13:21:51 +0000 +++ include/grub/kernel.h 2011-11-03 17:27:25 +0000 @@ -34,7 +34,7 @@ struct grub_module_header { /* The type of object. */ - grub_uint8_t type; + grub_uint32_t type; /* The size of object (including this header). */ grub_uint32_t size; }; --------------030700070006060604000702-- --------------enig70C35FEB569F2258E2B0E390 Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iF4EAREKAAYFAk6y110ACgkQNak7dOguQgngrgD/e61lALPUT2mccmuVannyhWt2 Yd9PTj0DKFK8TuxRxCIA/i6u2jcR/H//qrOuMIsOC2Wt6jp/DGrkqMsGZ85qaJcG =J36w -----END PGP SIGNATURE----- --------------enig70C35FEB569F2258E2B0E390--