[uClibc] -pie support (patches)
Peter S. Mazinger
ps.m at gmx.net
Mon Dec 8 22:46:45 UTC 2003
Hello!
To make the earlier request easier, I resend the needed patches.
Peter
--
Peter S. Mazinger <ps.m at gmx.net> ID: 0xA5F059F2 NIC: IXUYHSKQLI
Key fingerprint = 92A4 31E1 56BC 3D5A 2D08 BB6E C389 975E A5F0 59F2
____________________________________________________________________
Miert fizetsz az internetert? Korlatlan, ingyenes internet hozzaferes a FreeStarttol.
Probald ki most! http://www.freestart.hu
-------------- next part --------------
--- uClibc-0.9.23/extra/Configs/Config.in.mps Wed Nov 19 15:51:08 2003
+++ uClibc-0.9.23/extra/Configs/Config.in Wed Nov 19 15:51:25 2003
@@ -164,7 +164,7 @@
config FORCE_SHAREABLE_TEXT_SEGMENTS
bool "Only load shared libraries which can share their text segment"
- depends on BUILD_UCLIBC_LDSO && UCLIBC_COMPLETELY_PIC
+ depends on BUILD_UCLIBC_LDSO
default n
help
If you answer Y here, the uClibc native shared library loader will
-------------- next part --------------
--- uClibc-0.9.23/libc/sysdeps/linux/i386/crt0.S.mps 2003-11-21 10:51:56.000000000 +0100
+++ uClibc-0.9.23/libc/sysdeps/linux/i386/crt0.S 2003-11-21 11:13:02.000000000 +0100
@@ -18,6 +18,7 @@
/* Based on the code from GNU libc, but hacked up by John Beppu and Erik Andersen */
+/* adapted by PaX Team for ET_DYN/PIE binaries */
/*
When we enter this piece of code, the program stack looks like this:
@@ -37,7 +38,7 @@
.global _start
.type _start,%function
-#if defined L_crt0 || ! defined __UCLIBC_CTOR_DTOR__
+#if defined L_crt0 || defined L_Scrt0 || ! defined __UCLIBC_CTOR_DTOR__
.type __uClibc_main,%function
#else
.weak _init
@@ -74,10 +75,22 @@
pushl %ebp /* callers %ebp (frame pointer) */
movl %esp,%ebp /* mark callers stack frame as invalid */
-#if (defined L_crt1 || defined L_gcrt1 ) && defined __UCLIBC_CTOR_DTOR__
+#if defined L_Scrt0 || defined L_Scrt1
+ call .L0
+.L0:
+ pop %edx
+ addl $_GLOBAL_OFFSET_TABLE_+[.-.L0],%edx
+#endif
+
+#if ((defined L_crt1 || defined L_Scrt1 ) || defined L_gcrt1 ) && defined __UCLIBC_CTOR_DTOR__
/* Push .init and .fini arguments to __uClibc_start_main() on the stack */
+#ifdef L_Scrt1
+ pushl _fini at GOT(%edx)
+ pushl _init at GOT(%edx)
+#else
pushl $_fini
pushl $_init
+#endif
/* Push envp, argc, and argc arguments to __uClibc_start_main() on the stack */
pushl %eax /* Environment pointer */
@@ -85,15 +98,23 @@
pushl %ecx /* And the argument count */
/* Ok, now run uClibc's main() -- shouldn't return */
+#ifdef L_Scrt1
+ call *__uClibc_start_main at GOT(%edx)
+#else
call __uClibc_start_main
+#endif
#else
/* Push envp, argc, and argc arguments to __uClibc_start_main() on the stack */
pushl %eax /* Environment pointer */
pushl %ebx /* Argument pointer */
pushl %ecx /* And the argument count */
+#ifdef L_Scrt0
+ call *__uClibc_main at GOT(%edx)
+#else
call __uClibc_main
#endif
+#endif
/* Crash if somehow `exit' returns anyways. */
hlt
--- uClibc-0.9.23/libc/sysdeps/linux/i386/Makefile.mps 2003-11-21 11:21:04.000000000 +0100
+++ uClibc-0.9.23/libc/sysdeps/linux/i386/Makefile 2003-11-21 11:26:56.000000000 +0100
@@ -22,6 +22,10 @@
CRT0_SRC = crt0.S
CRT0_OBJ = crt0.o crt1.o gcrt1.o
+ifeq ($(strip $(UCLIBC_PIE_SUPPORT)),y)
+CRT0_OBJ += Scrt0.o Scrt1.o
+SCRT_FLAGS = -fPIC
+endif
CRT0_DEPS=gmon-start.S
CTOR_TARGETS=$(TOPDIR)lib/crti.o $(TOPDIR)lib/crtn.o
@@ -52,9 +56,16 @@
ar-target: $(OBJS) $(CRT0_OBJ) $(CTOR_TARGETS)
$(AR) $(ARFLAGS) $(LIBC) $(OBJS)
cp $(CRT0_OBJ) $(TOPDIR)lib/
+ifeq ($(strip $(UCLIBC_PIE_SUPPORT)),y)
+ifeq ($(strip $(UCLIBC_CTOR_DTOR)),y)
+ $(RM) $(TOPDIR)lib/Scrt0.o
+else
+ mv $(TOPDIR)lib/Scrt0.o $(TOPDIR)lib/Scrt1.o
+endif
+endif
$(CRT0_OBJ): $(CRT0_SRC)
- $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o
+ $(CC) $(CFLAGS) $(SCRT_FLAGS) -DL_$* $< -c -o $*.o
$(STRIPTOOL) -x -R .note -R .comment $*.o
$(SOBJS): %.o : %.S
-------------- next part --------------
--- uClibc-0.9.23/extra/Configs/Config.in.pax Wed Nov 19 14:59:04 2003
+++ uClibc-0.9.23/extra/Configs/Config.in Wed Nov 19 15:26:01 2003
@@ -177,6 +177,20 @@
little bit smaller and guarantee that no memory will be wasted by badly
coded shared libraries.
+config UCLIBC_PIE_SUPPORT
+ bool "Support ET_DYN in shared library loader"
+ select FORCE_SHAREABLE_TEXT_SEGMENTS
+ default n
+ help
+ If you answer Y here, the uClibc native shared library loader will
+ support ET_DYN/PIE executables.
+ It requires binutils-2.14.90.0.6 or later and the usage of the
+ -pie option.
+ More about ET_DYN/PIE binaries on <http://pageexec.virtualave.net/> .
+ WARNING: This option also enables FORCE_SHAREABLE_TEXT_SEGMENTS, so all
+ libraries have to be built with -fPIC or -fpic, and all assembler
+ functions must be written as position independent code (PIC).
+
config LDSO_LDD_SUPPORT
bool "Native shared library loader 'ldd' support"
depends on BUILD_UCLIBC_LDSO
--- uClibc-0.9.23/ldso/ldso/ldso.c.pax Sat Oct 4 19:31:22 2003
+++ uClibc-0.9.23/ldso/ldso/ldso.c Wed Nov 19 14:58:39 2003
@@ -371,6 +371,28 @@
app_tpnt = LD_MALLOC(sizeof(struct elf_resolve));
_dl_memset(app_tpnt, 0, sizeof(struct elf_resolve));
+#ifdef __UCLIBC_PIE_SUPPORT__
+ /* Find the runtime load address of the main executable, this may be
+ * different from what the ELF header says for ET_DYN/PIE executables.
+ */
+ {
+ ElfW(Phdr) *ppnt;
+ int i;
+
+ ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+ for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
+ if (ppnt->p_type == PT_PHDR) {
+ app_tpnt->loadaddr = (ElfW(Addr)) (auxvt[AT_PHDR].a_un.a_val - ppnt->p_vaddr);
+ break;
+ }
+ }
+
+#ifdef __SUPPORT_LD_DEBUG_EARLY__
+ SEND_STDERR("app_tpnt->loadaddr=");
+ SEND_ADDRESS_STDERR(app_tpnt->loadaddr, 1);
+#endif
+#endif
+
/*
* This is used by gdb to locate the chain of shared libraries that are currently loaded.
*/
@@ -407,7 +429,11 @@
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
if (ppnt->p_type == PT_DYNAMIC) {
+#ifndef __UCLIBC_PIE_SUPPORT__
dpnt = (Elf32_Dyn *) ppnt->p_vaddr;
+#else
+ dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
+#endif
while (dpnt->d_tag) {
#if defined(__mips__)
if (dpnt->d_tag == DT_MIPS_GOTSYM)
@@ -501,8 +527,13 @@
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
+#ifndef __UCLIBC_PIE_SUPPORT__
_dl_mprotect((void *) (ppnt->p_vaddr & PAGE_ALIGN),
(ppnt->p_vaddr & ADDR_ALIGN) +
+#else
+ _dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN),
+ ((ppnt->p_vaddr + app_tpnt->loadaddr) & ADDR_ALIGN) +
+#endif
(unsigned long) ppnt->p_filesz,
PROT_READ | PROT_WRITE | PROT_EXEC);
}
@@ -715,8 +746,13 @@
ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
if (ppnt->p_type == PT_LOAD) {
+#ifndef __UCLIBC_PIE_SUPPORT__
if (ppnt->p_vaddr + ppnt->p_memsz > brk_addr)
brk_addr = ppnt->p_vaddr + ppnt->p_memsz;
+#else
+ if (ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz > brk_addr)
+ brk_addr = ppnt->p_vaddr + app_tpnt->loadaddr + ppnt->p_memsz;
+#endif
}
if (ppnt->p_type == PT_DYNAMIC) {
#ifndef ALLOW_ZERO_PLTGOT
@@ -725,8 +761,13 @@
continue;
#endif
/* OK, we have what we need - slip this one into the list. */
+#ifndef __UCLIBC_PIE_SUPPORT__
app_tpnt = _dl_add_elf_hash_table("", 0,
app_tpnt->dynamic_info, ppnt->p_vaddr, ppnt->p_filesz);
+#else
+ app_tpnt = _dl_add_elf_hash_table("", (char *)app_tpnt->loadaddr,
+ app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
+#endif
_dl_loaded_modules->libtype = elf_executable;
_dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
@@ -735,7 +776,11 @@
rpnt->dyn = _dl_loaded_modules;
app_tpnt->usage_count++;
app_tpnt->symbol_scope = _dl_symbol_tables;
+#ifndef __UCLIBC_PIE_SUPPORT__
lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT]);
+#else
+ lpnt = (unsigned long *) (app_tpnt->dynamic_info[DT_PLTGOT] + app_tpnt->loadaddr);
+#endif
#ifdef ALLOW_ZERO_PLTGOT
if (lpnt)
#endif
More information about the uClibc
mailing list