diff options
author | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-12-03 19:40:55 +0000 |
---|---|---|
committer | Bernhard Reutner-Fischer <rep.dot.nop@gmail.com> | 2008-12-03 19:40:55 +0000 |
commit | ce54b92b046b65464e2d16b3842f3e97e3e0f27e (patch) | |
tree | 5d840e5451b4259c8ff17b33883256ec24e6de9d | |
parent | 6b497bfbe9428312f56bad4c1a288516882ef689 (diff) |
- Use runtime pagesize (Jeremy Kerr)
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.
Since almost all of the architectures can use the common definitions for
the _ALIGN macros, we can consolidate them all in ldso.h, and override
in the sysdep headers where necessary (ie, mips).
This allows me to start a uClibc-based root fs on a 64k machine.
Signed-off-by: Jeremy Kerr <jk at ozlabs org>
-rw-r--r-- | ldso/include/ldso.h | 13 | ||||
-rw-r--r-- | ldso/ldso/arm/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/avr32/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/bfin/dl-sysdep.h | 6 | ||||
-rw-r--r-- | ldso/ldso/cris/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/frv/dl-sysdep.h | 6 | ||||
-rw-r--r-- | ldso/ldso/i386/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/m68k/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/mips/dl-sysdep.h | 6 | ||||
-rw-r--r-- | ldso/ldso/powerpc/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/sh/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/sh64/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/sparc/dl-sysdep.h | 12 | ||||
-rw-r--r-- | ldso/ldso/x86_64/dl-sysdep.h | 5 | ||||
-rw-r--r-- | ldso/ldso/xtensa/dl-sysdep.h | 5 |
15 files changed, 13 insertions, 80 deletions
diff --git a/ldso/include/ldso.h b/ldso/include/ldso.h index 35a72fc5e..ec0663cea 100644 --- a/ldso/include/ldso.h +++ b/ldso/include/ldso.h @@ -39,6 +39,19 @@ #include <dl-elf.h> #include <dl-hash.h> +/* common align masks, if not specified by sysdep headers */ +#ifndef ADDR_ALIGN +#define ADDR_ALIGN (_dl_pagesize - 1) +#endif + +#ifndef PAGE_ALIGN +#define PAGE_ALIGN (~ADDR_ALIGN) +#endif + +#ifndef OFFS_ALIGN +#define OFFS_ALIGN (PAGE_ALIGN & ~(1ul << (sizeof(_dl_pagesize) * 8 - 1))) +#endif + /* For INIT/FINI dependency sorting. */ struct init_fini_list { struct init_fini_list *next; diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h index c3fc4e538..eea3b9868 100644 --- a/ldso/ldso/arm/dl-sysdep.h +++ b/ldso/ldso/arm/dl-sysdep.h @@ -55,11 +55,6 @@ static __inline__ unsigned long arm_modulus(unsigned long m, unsigned long p) 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one diff --git a/ldso/ldso/avr32/dl-sysdep.h b/ldso/ldso/avr32/dl-sysdep.h index 6696382b3..85c120dd8 100644 --- a/ldso/ldso/avr32/dl-sysdep.h +++ b/ldso/ldso/avr32/dl-sysdep.h @@ -46,11 +46,6 @@ 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 elf_machine_type_class(type) \ ((type == R_AVR32_JMP_SLOT) * ELF_RTYPE_CLASS_PLT) diff --git a/ldso/ldso/bfin/dl-sysdep.h b/ldso/ldso/bfin/dl-sysdep.h index 52df4c91f..a3563a0de 100644 --- a/ldso/ldso/bfin/dl-sysdep.h +++ b/ldso/ldso/bfin/dl-sysdep.h @@ -67,12 +67,6 @@ struct funcdesc_value extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden"))); -/* 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 - struct funcdesc_ht; #undef SEND_EARLY_STDERR diff --git a/ldso/ldso/cris/dl-sysdep.h b/ldso/ldso/cris/dl-sysdep.h index c68541d1b..575145df2 100644 --- a/ldso/ldso/cris/dl-sysdep.h +++ b/ldso/ldso/cris/dl-sysdep.h @@ -18,11 +18,6 @@ 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 - /* The union of reloc-type-classes where the reloc TYPE is a member. TYPE is in the class ELF_RTYPE_CLASS_PLT if it can describe a diff --git a/ldso/ldso/frv/dl-sysdep.h b/ldso/ldso/frv/dl-sysdep.h index 32d86ed2c..8e36ce592 100644 --- a/ldso/ldso/frv/dl-sysdep.h +++ b/ldso/ldso/frv/dl-sysdep.h @@ -51,12 +51,6 @@ struct funcdesc_value extern int _dl_linux_resolve(void) __attribute__((__visibility__("hidden"))); -/* 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 - struct funcdesc_ht; /* We must force strings used early in the bootstrap into the data diff --git a/ldso/ldso/i386/dl-sysdep.h b/ldso/ldso/i386/dl-sysdep.h index 7090c929d..77fa37211 100644 --- a/ldso/ldso/i386/dl-sysdep.h +++ b/ldso/ldso/i386/dl-sysdep.h @@ -25,11 +25,6 @@ do { \ 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable, so undefined references should not be allowed to define the value. diff --git a/ldso/ldso/m68k/dl-sysdep.h b/ldso/ldso/m68k/dl-sysdep.h index e42be3150..6d206bcbf 100644 --- a/ldso/ldso/m68k/dl-sysdep.h +++ b/ldso/ldso/m68k/dl-sysdep.h @@ -25,11 +25,6 @@ do { \ 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one diff --git a/ldso/ldso/mips/dl-sysdep.h b/ldso/ldso/mips/dl-sysdep.h index 312b9e858..728779250 100644 --- a/ldso/ldso/mips/dl-sysdep.h +++ b/ldso/ldso/mips/dl-sysdep.h @@ -148,13 +148,7 @@ void _dl_perform_mips_global_got_relocations(struct elf_resolve *tpnt, int lazy) /* 4096 bytes alignment */ #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 elf_machine_type_class(type) ELF_RTYPE_CLASS_PLT diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h index 768482272..fdbf564a7 100644 --- a/ldso/ldso/powerpc/dl-sysdep.h +++ b/ldso/ldso/powerpc/dl-sysdep.h @@ -67,11 +67,6 @@ struct elf_resolve; extern unsigned long _dl_linux_resolver(struct elf_resolve * tpnt, int reloc_entry); 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one diff --git a/ldso/ldso/sh/dl-sysdep.h b/ldso/ldso/sh/dl-sysdep.h index fd0f236a2..daedda5e0 100644 --- a/ldso/ldso/sh/dl-sysdep.h +++ b/ldso/ldso/sh/dl-sysdep.h @@ -83,11 +83,6 @@ _dl_urem(unsigned int n, unsigned int base) #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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable, so undefined references should not be allowed to define the value. diff --git a/ldso/ldso/sh64/dl-sysdep.h b/ldso/ldso/sh64/dl-sysdep.h index 21bfffcb6..bb78964ba 100644 --- a/ldso/ldso/sh64/dl-sysdep.h +++ b/ldso/ldso/sh64/dl-sysdep.h @@ -25,11 +25,6 @@ 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable, so undefined references should not be allowed to define the value. diff --git a/ldso/ldso/sparc/dl-sysdep.h b/ldso/ldso/sparc/dl-sysdep.h index 27cb97e38..17359e9b6 100644 --- a/ldso/ldso/sparc/dl-sysdep.h +++ b/ldso/ldso/sparc/dl-sysdep.h @@ -89,18 +89,6 @@ sparc_mod(unsigned long m, unsigned long p) #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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so PLT entries should not be allowed to define the value. ELF_RTYPE_CLASS_NOCOPY iff TYPE should not be allowed to resolve to one diff --git a/ldso/ldso/x86_64/dl-sysdep.h b/ldso/ldso/x86_64/dl-sysdep.h index 202eab19d..0eed657e8 100644 --- a/ldso/ldso/x86_64/dl-sysdep.h +++ b/ldso/ldso/x86_64/dl-sysdep.h @@ -41,11 +41,6 @@ do { \ 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry or TLS variable, so undefined references should not be allowed to define the value. diff --git a/ldso/ldso/xtensa/dl-sysdep.h b/ldso/ldso/xtensa/dl-sysdep.h index b58feff54..57b3e1d09 100644 --- a/ldso/ldso/xtensa/dl-sysdep.h +++ b/ldso/ldso/xtensa/dl-sysdep.h @@ -76,11 +76,6 @@ typedef struct xtensa_got_location_struct { 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 - /* ELF_RTYPE_CLASS_PLT iff TYPE describes relocation of a PLT entry, so undefined references should not be allowed to define the value. */ #define elf_machine_type_class(type) \ |