* [PATCH] Fix module relocation errors on PowerPC
@ 2011-10-18 4:48 Anton Blanchard
2011-10-18 5:49 ` Anton Blanchard
2011-11-03 18:03 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 2 replies; 5+ messages in thread
From: Anton Blanchard @ 2011-10-18 4:48 UTC (permalink / raw)
To: The development of GNU GRUB
[-- Attachment #1: Type: text/plain, Size: 445 bytes --]
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
[-- Attachment #2: fix_module_relocation --]
[-- Type: application/octet-stream, Size: 1963 bytes --]
2011-10-18 Anton Blanchard <anton@samba.org>
* grub-core/kern/ieee1275/init.c: Use sparc version of grub_claim_heap
on powerpc.
* include/grub/powerpc/ieee1275/ieee1275.h: Define
GRUB_KERNEL_MACHINE_STACK_SIZE.
* grub-core/kern/main.c: Use grub_modules_get_end on powerpc.
Index: grub/grub-core/kern/ieee1275/init.c
===================================================================
--- grub.orig/grub-core/kern/ieee1275/init.c 2011-10-18 15:01:50.894652852 +1100
+++ grub/grub-core/kern/ieee1275/init.c 2011-10-18 15:02:14.659078404 +1100
@@ -135,7 +135,7 @@ grub_machine_get_bootlocation (char **de
}
/* Claim some available memory in the first /memory node. */
-#ifdef __sparc__
+#if defined(__sparc__) || defined(__powerpc__)
static void
grub_claim_heap (void)
{
Index: grub/include/grub/powerpc/ieee1275/ieee1275.h
===================================================================
--- grub.orig/include/grub/powerpc/ieee1275/ieee1275.h 2011-10-18 15:07:11.408488163 +1100
+++ grub/include/grub/powerpc/ieee1275/ieee1275.h 2011-10-18 15:07:13.924534216 +1100
@@ -20,6 +20,8 @@
#ifndef GRUB_IEEE1275_MACHINE_HEADER
#define GRUB_IEEE1275_MACHINE_HEADER 1
+#define GRUB_KERNEL_MACHINE_STACK_SIZE 0
+
#include <grub/types.h>
#define GRUB_IEEE1275_CELL_SIZEOF 4
Index: grub/grub-core/kern/main.c
===================================================================
--- grub.orig/grub-core/kern/main.c 2011-10-18 15:07:54.761281514 +1100
+++ grub/grub-core/kern/main.c 2011-10-18 15:08:37.114056304 +1100
@@ -31,7 +31,7 @@
#include <grub/parser.h>
/* This is actualy platform-independant but used only on loongson and sparc. */
-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64)
+#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) || defined (__powerpc__)
grub_addr_t
grub_modules_get_end (void)
{
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Fix module relocation errors on PowerPC
2011-10-18 4:48 [PATCH] Fix module relocation errors on PowerPC Anton Blanchard
@ 2011-10-18 5:49 ` Anton Blanchard
2011-10-29 9:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-11-03 18:03 ` Vladimir 'φ-coder/phcoder' Serbinenko
1 sibling, 1 reply; 5+ messages in thread
From: Anton Blanchard @ 2011-10-18 5:49 UTC (permalink / raw)
To: The development of GNU GRUB
Hi,
> 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.
Sparc doesn't appear to claim the heap. Adding this patch on top of the
relocation one fixes things for me on PowerPC.
Any suggestions on the best way to fix it? The non Sparc version of
grub_claim_heap is rather complicated and I'm not sure why it just
doesn't allocate a couple of MB right above the executable. Assuming
we have ~4MB of free space at the address OF loads us is pretty
reasonable to me.
Anton
--
Index: grub/grub-core/kern/ieee1275/init.c
===================================================================
--- grub.orig/grub-core/kern/ieee1275/init.c 2011-10-18 16:30:03.824984376 +1100
+++ grub/grub-core/kern/ieee1275/init.c 2011-10-18 16:38:34.394100481 +1100
@@ -139,8 +139,16 @@ grub_machine_get_bootlocation (char **de
static void
grub_claim_heap (void)
{
- grub_mm_init_region ((void *) (grub_modules_get_end ()
- + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
+ grub_uint64_t addr, len;
+
+ addr = grub_modules_get_end () + GRUB_KERNEL_MACHINE_STACK_SIZE;
+ len = 0x200000;
+
+ if (grub_claimmap (addr, len) < 0)
+ grub_error (GRUB_ERR_OUT_OF_MEMORY,
+ "failed to claim heap at 0x%llx, len 0x%llx",
+ addr, len);
+ grub_mm_init_region ((void *) (grub_addr_t)addr, len);
}
#else
static void
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Fix module relocation errors on PowerPC
2011-10-18 5:49 ` Anton Blanchard
@ 2011-10-29 9:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
0 siblings, 0 replies; 5+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-10-29 9:39 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1: Type: text/plain, Size: 2013 bytes --]
On 18.10.2011 07:49, Anton Blanchard wrote:
> Hi,
>
>> 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.
> Sparc doesn't appear to claim the heap. Adding this patch on top of the
> relocation one fixes things for me on PowerPC.
>
> Any suggestions on the best way to fix it? The non Sparc version of
> grub_claim_heap is rather complicated and I'm not sure why it just
> doesn't allocate a couple of MB right above the executable. Assuming
> we have ~4MB of free space at the address OF loads us is pretty
> reasonable to me.
>
This is an eternal course to restrict usable space to supported
relocations. It should be the other way round. I'll prepare a patch for
adding necessary trampolines.
> Anton
>
> --
>
> Index: grub/grub-core/kern/ieee1275/init.c
> ===================================================================
> --- grub.orig/grub-core/kern/ieee1275/init.c 2011-10-18 16:30:03.824984376 +1100
> +++ grub/grub-core/kern/ieee1275/init.c 2011-10-18 16:38:34.394100481 +1100
> @@ -139,8 +139,16 @@ grub_machine_get_bootlocation (char **de
> static void
> grub_claim_heap (void)
> {
> - grub_mm_init_region ((void *) (grub_modules_get_end ()
> - + GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
> + grub_uint64_t addr, len;
> +
> + addr = grub_modules_get_end () + GRUB_KERNEL_MACHINE_STACK_SIZE;
> + len = 0x200000;
> +
> + if (grub_claimmap (addr, len) < 0)
> + grub_error (GRUB_ERR_OUT_OF_MEMORY,
> + "failed to claim heap at 0x%llx, len 0x%llx",
> + addr, len);
> + grub_mm_init_region ((void *) (grub_addr_t)addr, len);
> }
> #else
> static void
>
> _______________________________________________
> Grub-devel mailing list
> Grub-devel@gnu.org
> https://lists.gnu.org/mailman/listinfo/grub-devel
>
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Fix module relocation errors on PowerPC
2011-10-18 4:48 [PATCH] Fix module relocation errors on PowerPC Anton Blanchard
2011-10-18 5:49 ` Anton Blanchard
@ 2011-11-03 18:03 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-11-08 8:57 ` Anton Blanchard
1 sibling, 1 reply; 5+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2011-11-03 18:03 UTC (permalink / raw)
To: grub-devel
[-- Attachment #1.1: Type: text/plain, Size: 789 bytes --]
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
--
Regards
Vladimir 'φ-coder/phcoder' Serbinenko
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: ppc_tramp.diff --]
[-- Type: text/x-diff; name="ppc_tramp.diff", Size: 6033 bytes --]
=== 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 = 0, talign = 1;
-#ifdef __ia64__
+#if defined (__ia64__) || defined (__powerpc__)
grub_size_t tramp;
grub_size_t got;
#endif
@@ -248,9 +248,9 @@
talign = s->sh_addralign;
}
-#ifdef __ia64__
+#if defined (__ia64__) || defined (__powerpc__)
grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
- tramp *= GRUB_IA64_DL_TRAMP_SIZE;
+ tramp *= GRUB_ARCH_DL_TRAMP_SIZE;
got *= sizeof (grub_uint64_t);
tsize += ALIGN_UP (tramp, GRUB_ARCH_DL_TRAMP_ALIGN);
if (talign < GRUB_ARCH_DL_TRAMP_ALIGN)
@@ -316,7 +316,7 @@
mod->segment = seg;
}
}
-#ifdef __ia64__
+#if defined (__ia64__) || defined (__powerpc__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
ptr += tramp;
@@ -575,15 +575,9 @@
static void
grub_dl_flush_cache (grub_dl_t mod)
{
- grub_dl_segment_t seg;
-
- for (seg = mod->segment; seg; seg = 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);
}
/* Load a module from core memory. */
=== 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 @@
}
}
-static grub_uint8_t nopm[5] =
+static const grub_uint8_t nopm[5] =
{
/* [MLX] nop.m 0x0 */
0x05, 0x00, 0x00, 0x00, 0x01
};
-static grub_uint8_t jump[0x20] =
+static const grub_uint8_t jump[0x20] =
{
/* ld8 r16=[r15],8 */
0x02, 0x80, 0x20, 0x1e, 0x18, 0x14,
=== 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;
}
+void
+grub_arch_dl_get_tramp_got_size (const void *ehdr, grub_size_t *tramp,
+ grub_size_t *got)
+{
+ const Elf_Ehdr *e = ehdr;
+ const Elf_Shdr *s;
+ Elf_Word entsize;
+ unsigned i;
+
+ *tramp = 0;
+ *got = 0;
+
+ /* Find a symbol table. */
+ for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_SYMTAB)
+ break;
+
+ if (i == e->e_shnum)
+ return;
+
+ entsize = s->sh_entsize;
+
+ for (i = 0, s = (const Elf_Shdr *) ((const char *) e + e->e_shoff);
+ i < e->e_shnum;
+ i++, s = (const Elf_Shdr *) ((const char *) s + e->e_shentsize))
+ if (s->sh_type == SHT_RELA)
+ {
+ const Elf_Rela *rel, *max;
+
+ for (rel = (const Elf_Rela *) ((const char *) e + s->sh_offset),
+ max = rel + s->sh_size / s->sh_entsize;
+ rel < max;
+ rel++)
+ if (ELF_R_TYPE (rel->r_info) == R_PPC_REL24)
+ (*tramp)++;
+
+ }
+
+ 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 =
+ {
+ 0x3c000000,
+ 0x60000000,
+ 0x7c0903a6,
+ 0x4e800420,
+ };
/* Relocate symbols. */
grub_err_t
@@ -46,6 +105,7 @@
Elf_Shdr *s;
Elf_Word entsize;
unsigned i;
+ struct trampoline *tptr = mod->tramp;
/* Find a symbol table. */
for (i = 0, s = (Elf_Shdr *) ((char *) e + e->e_shoff);
@@ -105,6 +165,18 @@
{
Elf_Sword delta = value - (Elf_Word) addr;
+ //if (delta << 6 >> 6 != delta)
+ {
+ COMPILE_TIME_ASSERT (sizeof (struct trampoline)
+ == GRUB_ARCH_DL_TRAMP_SIZE);
+ grub_memcpy (tptr, &trampoline_template,
+ sizeof (*tptr));
+ delta = (grub_uint8_t *) tptr - (grub_uint8_t *) addr;
+ tptr->lis |= (((value) >> 16) & 0xffff);
+ tptr->ori |= ((value) & 0xffff);
+ tptr++;
+ }
+
if (delta << 6 >> 6 != delta)
return grub_error (GRUB_ERR_BAD_MODULE, "relocation overflow");
*addr = (*addr & 0xfc000003) | (delta & 0x3fffffc);
=== 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);
-#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
#endif
=== 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;
};
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH] Fix module relocation errors on PowerPC
2011-11-03 18:03 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2011-11-08 8:57 ` Anton Blanchard
0 siblings, 0 replies; 5+ messages in thread
From: Anton Blanchard @ 2011-11-08 8:57 UTC (permalink / raw)
To: The development of GNU GRUB; +Cc: phcoder
Hi Vladimir,
> Please try the attached patch
Thanks! I tested it and it does fix the issue.
Anton
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2011-11-08 8:57 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-10-18 4:48 [PATCH] Fix module relocation errors on PowerPC Anton Blanchard
2011-10-18 5:49 ` Anton Blanchard
2011-10-29 9:39 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-11-03 18:03 ` Vladimir 'φ-coder/phcoder' Serbinenko
2011-11-08 8:57 ` Anton Blanchard
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).