On Tue, Nov 25, 2008 at 09:37:43PM +1100, Jeremy Kerr wrote:
>Some powerpc machines can support 64k pages, enabled by the
>CONFIG_64K_PAGES option in linux.
>
>However, the uClibc dynamic loader won't currently work on these
>machines, as it uses hard-coded values (PAGE_ALIGN, ADDR_ALIGN and
>OFFS_ALIGN) in the ldso architecture-specific headers.  When running on
>a kernel with 64k pages, ld.so tries to mmap with 4k-aligned addresses,
>rather than 64k, so mmap fails with -EINVAL.
>
>When booting a 64k machine with a uClibc dynamic linker, init fails
>with:
>
>/init:500: can't map '/lib/libc.so.0'
>/init:500: can't map '/lib/libc.so.0'
>/init:500: can't map '/lib/libc.so.0'
>/init: can't load library 'libc.so.0'
>Kernel panic - not syncing: Attempted to kill init!
>
>This change allows ld.so determine these alignment masks at runtime,
>rather than compile-time. Since we have the _dl_pagesize variable
>available, we can use that to generate the appropriate masks.
>
>This allows me to start a uClibc-based root fs on a 64k machine.
>
>Signed-off-by: Jeremy Kerr <[EMAIL PROTECTED]>
>
>---
>
> ldso/ldso/dl-elf.c |   39 ++++++++++++++++++++++-----------------
> 1 file changed, 22 insertions(+), 17 deletions(-)
>
>Index: uClibc/ldso/ldso/dl-elf.c
>===================================================================
>--- uClibc.orig/ldso/ldso/dl-elf.c     2008-11-25 20:19:19.000000000 +1100
>+++ uClibc/ldso/ldso/dl-elf.c  2008-11-25 20:22:26.000000000 +1100
>@@ -336,6 +336,7 @@ struct elf_resolve *_dl_load_elf_shared_
>       unsigned long dynamic_info[DYNAMIC_SIZE];
>       unsigned long *lpnt;
>       unsigned long libaddr;
>+      unsigned long page_align, addr_align, offs_align;
>       unsigned long minvma = 0xffffffff, maxvma = 0;
>       int i, flags, piclib, infile;
>       ElfW(Addr) relro_addr = 0;
>@@ -442,7 +443,11 @@ struct elf_resolve *_dl_load_elf_shared_
> 
>       DL_CHECK_LIB_TYPE (epnt, piclib, _dl_progname, libname);
> 
>-      maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
>+      addr_align = _dl_pagesize - 1;
>+      page_align = ~addr_align;
>+      offs_align = page_align & ~(1 << 31);

This would brake _MIPS_SIM_ABI64, wouldn't it.

>+
>+      maxvma = (maxvma + addr_align) & ~addr_align;

This should perhaps read
maxvma = (maxvma + ADDR_ALIGN) & PAGE_ALIGN;
for consistency.

Please adjust the per arch dl-sysdep.h defines instead (which you
didn't remove, btw), something like the attached, untested patchlet.
Index: ldso/ldso/powerpc/dl-sysdep.h
===================================================================
--- ldso/ldso/powerpc/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/powerpc/dl-sysdep.h	(working copy)
@@ -68,9 +68,9 @@ extern unsigned long _dl_linux_resolver(
 void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.
Index: ldso/ldso/arm/dl-sysdep.h
===================================================================
--- ldso/ldso/arm/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/arm/dl-sysdep.h	(working copy)
@@ -56,9 +56,9 @@ struct elf_resolve;
 unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.
Index: ldso/ldso/sh64/dl-sysdep.h
===================================================================
--- ldso/ldso/sh64/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/sh64/dl-sysdep.h	(working copy)
@@ -26,9 +26,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
    TLS variable, so undefined references should not be allowed to
Index: ldso/ldso/dl-elf.c
===================================================================
--- ldso/ldso/dl-elf.c	(revision 24137)
+++ ldso/ldso/dl-elf.c	(working copy)
@@ -442,7 +442,7 @@ struct elf_resolve *_dl_load_elf_shared_
 
 	DL_CHECK_LIB_TYPE (epnt, piclib, _dl_progname, libname);
 
-	maxvma = (maxvma + ADDR_ALIGN) & ~ADDR_ALIGN;
+	maxvma = (maxvma + ADDR_ALIGN) & PAGE_ALIGN;
 	minvma = minvma & ~0xffffU;
 
 	flags = MAP_PRIVATE /*| MAP_DENYWRITE */ ;
Index: ldso/ldso/m68k/dl-sysdep.h
===================================================================
--- ldso/ldso/m68k/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/m68k/dl-sysdep.h	(working copy)
@@ -26,9 +26,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver (struct elf_resolve *, int);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.
Index: ldso/ldso/i386/dl-sysdep.h
===================================================================
--- ldso/ldso/i386/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/i386/dl-sysdep.h	(working copy)
@@ -26,9 +26,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
    TLS variable, so undefined references should not be allowed to
Index: ldso/ldso/avr32/dl-sysdep.h
===================================================================
--- ldso/ldso/avr32/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/avr32/dl-sysdep.h	(working copy)
@@ -47,9 +47,9 @@
 unsigned long _dl_linux_resolver(unsigned long got_offset, unsigned long *got);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 #define elf_machine_type_class(type)				\
 	((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT)
Index: ldso/ldso/frv/dl-sysdep.h
===================================================================
--- ldso/ldso/frv/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/frv/dl-sysdep.h	(working copy)
@@ -53,9 +53,9 @@ extern int _dl_linux_resolve(void) __att
 
 /* 16KiB page alignment.  Should perhaps be made dynamic using
    getpagesize(), based on AT_PAGESZ from auxvt?  */
-#define PAGE_ALIGN 0xffffc000
-#define ADDR_ALIGN 0x3fff
-#define OFFS_ALIGN 0x7fffc000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 struct funcdesc_ht;
 
Index: ldso/ldso/x86_64/dl-sysdep.h
===================================================================
--- ldso/ldso/x86_64/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/x86_64/dl-sysdep.h	(working copy)
@@ -42,9 +42,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
    TLS variable, so undefined references should not be allowed to
Index: ldso/ldso/cris/dl-sysdep.h
===================================================================
--- ldso/ldso/cris/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/cris/dl-sysdep.h	(working copy)
@@ -19,9 +19,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry);
 
 /* 8192 bytes alignment */
-#define PAGE_ALIGN 0xffffe000
-#define ADDR_ALIGN 0x1fff
-#define OFFS_ALIGN 0xffffe000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* The union of reloc-type-classes where the reloc TYPE is a member.
 
Index: ldso/ldso/xtensa/dl-sysdep.h
===================================================================
--- ldso/ldso/xtensa/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/xtensa/dl-sysdep.h	(working copy)
@@ -77,9 +77,9 @@ struct elf_resolve;
 extern unsigned long _dl_linux_resolver (struct elf_resolve *, int);
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    undefined references should not be allowed to define the value.  */
Index: ldso/ldso/sparc/dl-sysdep.h
===================================================================
--- ldso/ldso/sparc/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/sparc/dl-sysdep.h	(working copy)
@@ -89,17 +89,11 @@ sparc_mod(unsigned long m, unsigned long
 #define do_rem(result, n, base) ((result) = sparc_mod(n, base))
 #endif
 
-/* 4096 bytes alignment */
-#if defined(__sparc_v9__)
-/* ...but 8192 is required for mmap() on sparc64 kernel */
-#define PAGE_ALIGN 0xffffe000
-#define ADDR_ALIGN 0x1fff
-#define OFFS_ALIGN 0x7fffe000
-#elif defined(__sparc_v8__)
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
-#endif
+/* 4096 bytes alignment for __sparc_v8__ */
+/* ...but 8192 is required for __sparc_v9__'s mmap() on sparc64 kernel */
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so
    PLT entries should not be allowed to define the value.
Index: ldso/ldso/mips/dl-sysdep.h
===================================================================
--- ldso/ldso/mips/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/mips/dl-sysdep.h	(working copy)
@@ -147,15 +147,13 @@ struct elf_resolve;
 void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy);
 
 /* 4096 bytes alignment */
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
 #if _MIPS_SIM == _MIPS_SIM_ABI64
-#define PAGE_ALIGN (~0xfffUL)
-#define ADDR_ALIGN 0xfffUL
-#define OFFS_ALIGN (0x10000000000UL-0x1000)
-#else	/* O32 || N32 */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
-#endif	/* O32 || N32 */
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
+#else /* O32 || N32 */
+#define OFFS_ALIGN (0x10000000000UL - _dl_pagesize)
+#endif
 
 #define elf_machine_type_class(type)		ELF_RTYPE_CLASS_PLT
 /* MIPS does not have COPY relocs */
Index: ldso/ldso/sh/dl-sysdep.h
===================================================================
--- ldso/ldso/sh/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/sh/dl-sysdep.h	(working copy)
@@ -84,9 +84,9 @@ _dl_urem(unsigned int n, unsigned int ba
 #define do_rem(result, n, base)     ((result) = _dl_urem((n), (base)))
 
 /* 4096 bytes alignment */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or
    TLS variable, so undefined references should not be allowed to
Index: ldso/ldso/bfin/dl-sysdep.h
===================================================================
--- ldso/ldso/bfin/dl-sysdep.h	(revision 24137)
+++ ldso/ldso/bfin/dl-sysdep.h	(working copy)
@@ -69,9 +69,9 @@ extern int _dl_linux_resolve(void) __att
 
 /* 4KiB page alignment.  Should perhaps be made dynamic using
    getpagesize(), based on AT_PAGESZ from auxvt?  */
-#define PAGE_ALIGN 0xfffff000
-#define ADDR_ALIGN 0xfff
-#define OFFS_ALIGN 0x7ffff000
+#define PAGE_ALIGN (~ADDR_ALIGN)
+#define ADDR_ALIGN (_dl_pagesize - 1)
+#define OFFS_ALIGN ((PAGE_ALIGN) & ~(1 << 31))
 
 struct funcdesc_ht;
 
_______________________________________________
uClibc mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/uclibc

Reply via email to