aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Mike Frysinger <vapier@gentoo.org>2007-01-26 00:01:55 +0000
committerGravatar Mike Frysinger <vapier@gentoo.org>2007-01-26 00:01:55 +0000
commit4253551cbbf0e9a040f03325242f96a5aa566738 (patch)
tree73ce09609c3a4341a3e7fb64bcd53559351650c6
parentacb14559eb597903baaa2d42dd4ec7354d263883 (diff)
downloaduClibc-4253551cbbf0e9a040f03325242f96a5aa566738.tar.gz
uClibc-4253551cbbf0e9a040f03325242f96a5aa566738.tar.bz2
pull accumulated fixes from trunk
-rw-r--r--Rules.mak2
-rw-r--r--extra/Configs/Config.in2
-rwxr-xr-xextra/scripts/fix_includes.sh32
-rwxr-xr-xextra/scripts/getent16
-rw-r--r--ldso/include/dl-string.h12
-rw-r--r--ldso/ldso/Makefile1
-rw-r--r--ldso/ldso/arm/dl-sysdep.h1
-rw-r--r--ldso/ldso/ldso.c8
-rw-r--r--ldso/ldso/powerpc/dl-startup.h13
-rw-r--r--ldso/ldso/powerpc/dl-sysdep.h52
-rw-r--r--ldso/ldso/powerpc/elfinterp.c113
-rw-r--r--libc/inet/resolv.c11
-rw-r--r--libc/misc/internals/__uClibc_main.c10
-rw-r--r--libc/stdlib/atexit.c8
-rw-r--r--libc/string/arm/strncmp.S7
-rw-r--r--libc/string/i386/string.c19
-rw-r--r--libc/sysdeps/linux/common/getcwd.c3
-rw-r--r--libc/sysdeps/linux/common/getdents.c34
-rw-r--r--libc/sysdeps/linux/common/getdents64.c4
-rw-r--r--libc/sysdeps/linux/common/posix_fadvise.c2
-rw-r--r--libc/sysdeps/linux/common/readahead.c52
-rw-r--r--libc/sysdeps/linux/i386/bits/syscalls.h12
-rw-r--r--libc/sysdeps/linux/mips/bits/stat.h10
-rw-r--r--libc/sysdeps/linux/mips/bits/syscalls.h27
-rw-r--r--libc/sysdeps/linux/mips/brk.c7
-rw-r--r--libc/sysdeps/linux/mips/pipe.S21
-rw-r--r--libc/sysdeps/linux/mips/pipe.c23
-rw-r--r--libc/sysdeps/linux/powerpc/bits/kernel_types.h4
-rw-r--r--libc/sysdeps/linux/powerpc/bits/syscalls.h161
-rw-r--r--libc/sysdeps/linux/powerpc/brk.S7
-rw-r--r--libc/sysdeps/linux/powerpc/bsd-_setjmp.S8
-rw-r--r--libc/sysdeps/linux/powerpc/bsd-setjmp.S8
-rw-r--r--libc/sysdeps/linux/powerpc/crt1.S10
-rw-r--r--libc/sysdeps/linux/powerpc/setjmp.S8
-rw-r--r--libc/sysdeps/linux/powerpc/sys/procfs.h22
-rw-r--r--libc/sysdeps/linux/sh/bits/setjmp.h14
-rw-r--r--utils/Makefile6
37 files changed, 525 insertions, 225 deletions
diff --git a/Rules.mak b/Rules.mak
index 3d3f0e7fa..5b51c4197 100644
--- a/Rules.mak
+++ b/Rules.mak
@@ -217,6 +217,8 @@ ifeq ($(strip $(TARGET_ARCH)),powerpc)
# faster code.
PICFLAG:=-fpic
PIEFLAG_NAME:=-fpie
+ PPC_HAS_REL16:=$(shell echo -e "\t.text\n\taddis 11,30,_GLOBAL_OFFSET_TABLE_-.@ha" | $(CC) -c -x assembler -o /dev/null - 2> /dev/null && echo -n y || echo -n n)
+ CPU_CFLAGS-$(PPC_HAS_REL16)+= -DHAVE_ASM_PPC_REL16
endif
ifeq ($(strip $(TARGET_ARCH)),frv)
diff --git a/extra/Configs/Config.in b/extra/Configs/Config.in
index ac5a3e104..0545663c2 100644
--- a/extra/Configs/Config.in
+++ b/extra/Configs/Config.in
@@ -987,7 +987,7 @@ config UCLIBC_HAS_SYS_SIGLIST
config UCLIBC_HAS_GETTEXT_AWARENESS
bool "Include gettext awareness"
- depends on UCLIBC_HAS_LOCALE && UCLIBC_MJN3_ONLY
+ depends on UCLIBC_HAS_LOCALE
default n
help
NOTE!!! Not yet integrated with strerror and strsignal. NOTE!!!
diff --git a/extra/scripts/fix_includes.sh b/extra/scripts/fix_includes.sh
index 910242fa5..7099bf5dd 100755
--- a/extra/scripts/fix_includes.sh
+++ b/extra/scripts/fix_includes.sh
@@ -78,36 +78,6 @@ if [ ! -d "$KERNEL_SOURCE" ]; then
exit 1;
fi;
-if [ -f "$KERNEL_SOURCE/Makefile" ] ; then
-# set current VERSION, PATCHLEVEL, SUBLEVEL, EXTRAVERSION
-eval `sed -n -e 's/^\([A-Z]*\) = \([0-9]*\)$/\1=\2/p' -e 's/^\([A-Z]*\) = \(-[-a-z0-9]*\)$/\1=\2/p' $KERNEL_SOURCE/Makefile`
-else
-ver=`grep UTS_RELEASE $KERNEL_SOURCE/include/linux/version.h | cut -d '"' -f 2`
-VERSION=`echo "$ver" | cut -d '.' -f 1`
-PATCHLEVEL=`echo "$ver" | cut -d '.' -f 2`
-if echo "$ver" | grep -q '-' ; then
-SUBLEVEL=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.//" | cut -d '-' -f 1`
-EXTRAVERSION=`echo "$ver" | sed "s/${VERSION}.${PATCHLEVEL}.${SUBLEVEL}-//"`
-else
-SUBLEVEL=`echo "$ver" | cut -d '.' -f 3`
-#EXTRAVERSION=
-fi
-fi
-if [ -z "$VERSION" -o -z "$PATCHLEVEL" -o -z "$SUBLEVEL" ]
-then
- echo "Unable to determine version for kernel headers"
- echo -e "\tprovided in directory $KERNEL_SOURCE"
- exit 1
-fi
-
-if [ "$MAKE_IS_SILENT" != "y" ]; then
-echo "Current kernel version is $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION}"
-echo -e "\n"
-echo "Using kernel headers from $VERSION.$PATCHLEVEL.$SUBLEVEL${EXTRAVERSION} for architecture '$TARGET_ARCH'"
-echo -e "\tprovided in directory $KERNEL_SOURCE"
-echo -e "\n"
-fi
-
# Create a symlink to include/asm
rm -f include/asm*
@@ -172,7 +142,7 @@ fi;
# Annoyingly, 2.6.x kernel headers also need an include/asm-generic/ directory
-if [ $VERSION -eq 2 ] && [ $PATCHLEVEL -ge 6 ] ; then
+if [ -e $KERNEL_SOURCE/include/asm-generic ]; then
ln -fs $KERNEL_SOURCE/include/asm-generic include/asm-generic
fi;
diff --git a/extra/scripts/getent b/extra/scripts/getent
index c02149498..acb014038 100755
--- a/extra/scripts/getent
+++ b/extra/scripts/getent
@@ -11,9 +11,19 @@ search_entry() {
fi
}
+if [ -z "$1" ] ; then
+ echo "getent: wrong number of arguments" 1>&2
+ exit 1
+fi
+
file="/etc/$1"
string="dummy"
+if [ ! -f "$file" ] ; then
+ echo "Unknown database: $1" 1>&2
+ exit 1
+fi
+
#aliases|ethers|group|hosts|netgroup|networks|passwd|protocols|rpc|services|shadow)
# dns based search is not supported for hosts|networks
# ethers|netgroup (not done, needed)?
@@ -48,6 +58,10 @@ case $1 in
;;
esac
-search_entry $file $2
+if [ -z "$2" ] ; then
+ exec cat $file
+else
+ search_entry "$file" "$2"
+fi
exit $retval
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index 57f05bd79..42b46c599 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -4,6 +4,14 @@
#include <dl-sysdep.h> // for do_rem
#include <features.h>
+/* provide some sane defaults */
+#ifndef do_rem
+# define do_rem(result, n, base) ((result) = (n) % (base))
+#endif
+#ifndef do_div_10
+# define do_div_10(result, remain) ((result) /= 10)
+#endif
+
static size_t _dl_strlen(const char * str);
static char *_dl_strcat(char *dst, const char *src);
static char * _dl_strcpy(char * dst,const char *src);
@@ -228,7 +236,7 @@ static __always_inline char * _dl_simple_ltoa(char * local, unsigned long i)
char temp;
do_rem(temp, i, 10);
*--p = '0' + temp;
- i /= 10;
+ do_div_10(i, temp);
} while (i > 0);
return p;
}
@@ -318,7 +326,7 @@ static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
do { \
do_rem(v, (X), 10); \
*--tmp2 = '0' + v; \
- (X) /= 10; \
+ do_div_10((X), v); \
} while ((X) > 0); \
_dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \
}
diff --git a/ldso/ldso/Makefile b/ldso/ldso/Makefile
index cb105af2d..d295e98d2 100644
--- a/ldso/ldso/Makefile
+++ b/ldso/ldso/Makefile
@@ -43,6 +43,7 @@ endif
XXFLAGS+= -DUCLIBC_LDSO=\"$(UCLIBC_LDSO)\" $(XARCH_CFLAGS) $(CPU_CFLAGS) $(PICFLAG) \
-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-fno-builtin -nostdinc -D_LIBC -I$(TOPDIR)ldso/include -I. -I$(TOPDIR)include
+XXFLAGS += -D_GNU_SOURCE
# BEWARE!!! At least mips* will die if -O0 is used!!!
XXFLAGS:=$(XXFLAGS:-O0=-O1)
diff --git a/ldso/ldso/arm/dl-sysdep.h b/ldso/ldso/arm/dl-sysdep.h
index 794c86a0c..45a40e2bb 100644
--- a/ldso/ldso/arm/dl-sysdep.h
+++ b/ldso/ldso/arm/dl-sysdep.h
@@ -43,6 +43,7 @@ static inline unsigned long arm_modulus(unsigned long m, unsigned long p)
return m;
}
#define do_rem(result, n, base) ((result) = arm_modulus(n, base))
+#define do_div_10(result, remain) ((result) = (((result) - (remain)) / 2) * -(-1ul / 5ul))
/* Here we define the magic numbers that this dynamic loader should accept */
#define MAGIC1 EM_ARM
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index db250f0be..a16ef5b89 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -766,11 +766,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
#ifdef _DL_FINI_CRT_COMPAT
/* arches that have moved their ldso FINI handling should skip this part */
{
- int (*_dl_atexit) (void *) = (int (*)(void *)) (intptr_t) _dl_find_hash("atexit",
+ void (*__set__dl_fini) (void *) = (void (*)(void *)) (intptr_t) _dl_find_hash("_set__dl_fini",
_dl_symbol_tables, NULL, ELF_RTYPE_CLASS_PLT);
- if (_dl_atexit)
- (*_dl_atexit) (_dl_fini);
+ if (__set__dl_fini)
+ (__set__dl_fini)(_dl_fini);
+ else
+ _dl_if_debug_dprint("_set__dl_fini not found\n");
}
#endif
diff --git a/ldso/ldso/powerpc/dl-startup.h b/ldso/ldso/powerpc/dl-startup.h
index 6fdf74301..11fb95b72 100644
--- a/ldso/ldso/powerpc/dl-startup.h
+++ b/ldso/ldso/powerpc/dl-startup.h
@@ -16,8 +16,15 @@ asm(
" bl _dl_start@local\n" /* Perform relocation */
/* Save the address of the apps entry point in CTR register */
" mtctr 3\n" /* application entry point */
+#ifdef HAVE_ASM_PPC_REL16
+ " bcl 20,31,1f\n"
+ "1: mflr 31\n"
+ " addis 31,31,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+ " addi 31,31,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+#else
" bl _GLOBAL_OFFSET_TABLE_-4@local\n" /* Put our GOT pointer in r31, */
" mflr 31\n"
+#endif
" addi 1,1,16\n" /* Restore SP */
" lwz 7,_dl_skip_args@got(31)\n" /* load EA of _dl_skip_args */
" lwz 7,0(7)\n" /* Load word from _dl_skip_args */
@@ -42,8 +49,10 @@ asm(
" bne 2b\n"
" addi 6,6,4\n"
#endif
- /* Pass a termination function pointer (in this case _dl_fini) in r7. */
- " lwz 7,_dl_fini@got(31)\n"
+ /* Pass a termination function pointer (in this case _dl_fini) in r3. */
+ /* Paulus promized he would keep r3 zero in the exec ABI. */
+ " lwz 3,_dl_fini@got(31)\n"
+ " mr 7,3\n" /* Pass _dl_fini in r7 to maintain compat */
" bctr\n" /* Jump to entry point */
" .size _start,.-_start\n"
" .previous\n"
diff --git a/ldso/ldso/powerpc/dl-sysdep.h b/ldso/ldso/powerpc/dl-sysdep.h
index 6f7bde147..04de1b80a 100644
--- a/ldso/ldso/powerpc/dl-sysdep.h
+++ b/ldso/ldso/powerpc/dl-sysdep.h
@@ -92,23 +92,38 @@ void _dl_init_got(unsigned long *lpnt,struct elf_resolve *tpnt);
DT_RELA table. */
#define ELF_MACHINE_PLTREL_OVERLAP 1
+/* Return the value of the GOT pointer. */
+static inline Elf32_Addr * __attribute__ ((const))
+ppc_got (void)
+{
+ Elf32_Addr *got;
+#ifdef HAVE_ASM_PPC_REL16
+ asm (" bcl 20,31,1f\n"
+ "1:mflr %0\n"
+ " addis %0,%0,_GLOBAL_OFFSET_TABLE_-1b@ha\n"
+ " addi %0,%0,_GLOBAL_OFFSET_TABLE_-1b@l\n"
+ : "=b" (got) : : "lr");
+#else
+ asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
+ : "=l" (got));
+#endif
+ return got;
+}
+
/* Return the link-time address of _DYNAMIC, stored as
the first value in the GOT. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
elf_machine_dynamic (void)
{
- Elf32_Addr *got;
- asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
- : "=l"(got));
- return *got;
+ return *ppc_got();
}
/* Return the run-time load address of the shared object. */
-static inline Elf32_Addr
+static inline Elf32_Addr __attribute__ ((const))
elf_machine_load_address (void)
{
- unsigned int *got;
- unsigned int *branchaddr;
+ Elf32_Addr *branchaddr;
+ Elf32_Addr runtime_dynamic;
/* This is much harder than you'd expect. Possibly I'm missing something.
The 'obvious' way:
@@ -139,19 +154,17 @@ elf_machine_load_address (void)
the address ourselves. That gives us the following code: */
/* Get address of the 'b _DYNAMIC@local'... */
- asm ("bl 0f ;"
+ asm ("bcl 20,31,0f;"
"b _DYNAMIC@local;"
"0:"
: "=l"(branchaddr));
- /* ... and the address of the GOT. */
- asm (" bl _GLOBAL_OFFSET_TABLE_-4@local"
- : "=l"(got));
-
/* So now work out the difference between where the branch actually points,
and the offset of that location in memory from the start of the file. */
- return ((Elf32_Addr)branchaddr - *got
- + ((int)(*branchaddr << 6 & 0xffffff00) >> 6));
+ runtime_dynamic = ((Elf32_Addr) branchaddr
+ + ((Elf32_Sword) (*branchaddr << 6 & 0xffffff00) >> 6));
+
+ return runtime_dynamic - elf_machine_dynamic ();
}
static inline void
@@ -166,3 +179,12 @@ elf_machine_relative (Elf32_Addr load_off, const Elf32_Addr rel_addr,
*reloc_addr = load_off + rpnt->r_addend;
} while (--relative_count);
}
+
+#define ARCH_NUM 1
+#define DT_PPC_GOT_IDX (DT_NUM + OS_NUM)
+
+#define ARCH_DYNAMIC_INFO(dpnt, dynamic, debug_addr) \
+do { \
+if (dpnt->d_tag == DT_PPC_GOT) \
+ dynamic[DT_PPC_GOT_IDX] = dpnt->d_un.d_ptr; \
+} while (0)
diff --git a/ldso/ldso/powerpc/elfinterp.c b/ldso/ldso/powerpc/elfinterp.c
index 4ec459854..5d41ea959 100644
--- a/ldso/ldso/powerpc/elfinterp.c
+++ b/ldso/ldso/powerpc/elfinterp.c
@@ -39,6 +39,12 @@ void _dl_init_got(unsigned long *plt,struct elf_resolve *tpnt)
Elf32_Word rel_offset_words;
Elf32_Word dlrr = (Elf32_Word) _dl_linux_resolve;
+ if (tpnt->dynamic_info[DT_JMPREL] == 0)
+ return;
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ tpnt->dynamic_info[DT_PPC_GOT_IDX] += tpnt->loadaddr;
+ return;
+ }
num_plt_entries = tpnt->dynamic_info[DT_PLTRELSZ] / sizeof(ELF_RELOC);
rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
data_words = (Elf32_Word) (plt + rel_offset_words);
@@ -146,32 +152,35 @@ unsigned long _dl_linux_resolver(struct elf_resolve *tpnt, int reloc_entry)
if(_dl_debug_reloc && _dl_debug_detail)
_dl_dprintf(_dl_debug_file, "%x\n", finaladdr);
#endif
- delta = finaladdr - (Elf32_Word)reloc_addr;
- if (delta<<6>>6 == delta) {
- *reloc_addr = OPCODE_B(delta);
- } else if (finaladdr <= 0x01fffffc) {
- *reloc_addr = OPCODE_BA (finaladdr);
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ *reloc_addr = finaladdr;
} else {
- /* Warning: we don't handle double-sized PLT entries */
- Elf32_Word *plt, *data_words, index, offset;
+ delta = finaladdr - (Elf32_Word)reloc_addr;
+ if (delta<<6>>6 == delta) {
+ *reloc_addr = OPCODE_B(delta);
+ } else if (finaladdr <= 0x01fffffc) {
+ *reloc_addr = OPCODE_BA (finaladdr);
+ } else {
+ /* Warning: we don't handle double-sized PLT entries */
+ Elf32_Word *plt, *data_words, index, offset;
+
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ offset = reloc_addr - plt;
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ data_words = (Elf32_Word *)tpnt->data_words;
+ reloc_addr += 1;
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
- offset = reloc_addr - plt;
- index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
- data_words = (Elf32_Word *)tpnt->data_words;
- reloc_addr += 1;
+ data_words[index] = finaladdr;
+ PPC_SYNC;
+ *reloc_addr = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+ }
- data_words[index] = finaladdr;
+ /* instructions were modified */
+ PPC_DCBST(reloc_addr);
PPC_SYNC;
- *reloc_addr = OPCODE_B ((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+ PPC_ICBI(reloc_addr);
+ PPC_ISYNC;
}
-
- /* instructions were modified */
- PPC_DCBST(reloc_addr);
- PPC_SYNC;
- PPC_ICBI(reloc_addr);
- PPC_ISYNC;
-
return finaladdr;
}
@@ -217,28 +226,33 @@ _dl_do_reloc (struct elf_resolve *tpnt,struct dyn_elf *scope,
goto out_nocode; /* No code code modified */
case R_PPC_JMP_SLOT:
{
- Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
- if (delta<<6>>6 == delta) {
- *reloc_addr = OPCODE_B(delta);
- } else if (finaladdr <= 0x01fffffc) {
- *reloc_addr = OPCODE_BA (finaladdr);
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ *reloc_addr = finaladdr;
+ goto out_nocode; /* No code code modified */
} else {
- /* Warning: we don't handle double-sized PLT entries */
- Elf32_Word *plt, *data_words, index, offset;
-
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
- offset = reloc_addr - plt;
- index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
- data_words = (Elf32_Word *)tpnt->data_words;
-
- data_words[index] = finaladdr;
- reloc_addr[0] = OPCODE_LI(11,index*4);
- reloc_addr[1] = OPCODE_B((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
-
- /* instructions were modified */
- PPC_DCBST(reloc_addr+1);
- PPC_SYNC;
- PPC_ICBI(reloc_addr+1);
+ Elf32_Sword delta = finaladdr - (Elf32_Word)reloc_addr;
+ if (delta<<6>>6 == delta) {
+ *reloc_addr = OPCODE_B(delta);
+ } else if (finaladdr <= 0x01fffffc) {
+ *reloc_addr = OPCODE_BA (finaladdr);
+ } else {
+ /* Warning: we don't handle double-sized PLT entries */
+ Elf32_Word *plt, *data_words, index, offset;
+
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ offset = reloc_addr - plt;
+ index = (offset - PLT_INITIAL_ENTRY_WORDS)/2;
+ data_words = (Elf32_Word *)tpnt->data_words;
+
+ data_words[index] = finaladdr;
+ reloc_addr[0] = OPCODE_LI(11,index*4);
+ reloc_addr[1] = OPCODE_B((PLT_LONGBRANCH_ENTRY_WORDS - (offset+1)) * 4);
+
+ /* instructions were modified */
+ PPC_DCBST(reloc_addr+1);
+ PPC_SYNC;
+ PPC_ICBI(reloc_addr+1);
+ }
}
break;
}
@@ -307,9 +321,22 @@ void _dl_parse_lazy_relocation_information(struct dyn_elf *rpnt,
Elf32_Word *plt, offset, i, num_plt_entries, rel_offset_words;
num_plt_entries = rel_size / sizeof(ELF_RELOC);
+ plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
+ if (tpnt->dynamic_info[DT_PPC_GOT_IDX] != 0) {
+ /* Secure PLT */
+ Elf32_Addr *got = (Elf32_Addr *)tpnt->dynamic_info[DT_PPC_GOT_IDX];
+ Elf32_Word dlrr = (Elf32_Word) _dl_linux_resolve;
+
+ got[1] = (Elf32_Addr) dlrr;
+ got[2] = (Elf32_Addr) tpnt;
+
+ /* Relocate everything in .plt by the load address offset. */
+ while (num_plt_entries-- != 0)
+ *plt++ += tpnt->loadaddr;
+ return;
+ }
rel_offset_words = PLT_DATA_START_WORDS(num_plt_entries);
- plt = (Elf32_Word *)tpnt->dynamic_info[DT_PLTGOT];
/* Set up the lazy PLT entries. */
offset = PLT_INITIAL_ENTRY_WORDS;
diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c
index 27b60efea..0312b2ca3 100644
--- a/libc/inet/resolv.c
+++ b/libc/inet/resolv.c
@@ -2204,6 +2204,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
struct in6_addr *in6;
struct in6_addr **addr_list6;
#endif /* __UCLIBC_HAS_IPV6__ */
+ char **alias;
unsigned char *packet;
struct resolv_answer a;
int i;
@@ -2264,6 +2265,12 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
buf+=sizeof(*addr_list)*2;
buflen-=sizeof(*addr_list)*2;
+ if (buflen < sizeof(char *)*(ALIAS_DIM))
+ return ERANGE;
+ alias=(char **)buf;
+ buf+=sizeof(*alias)*(ALIAS_DIM);
+ buflen-=sizeof(*alias)*(ALIAS_DIM);
+
#ifdef __UCLIBC_HAS_IPV6__
if (plen < sizeof(*in6))
return ERANGE;
@@ -2312,6 +2319,9 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
addr_list[1] = 0;
+ alias[0] = buf;
+ alias[1] = 0;
+
for (;;) {
BIGLOCK;
@@ -2358,6 +2368,7 @@ int gethostbyaddr_r (const void *addr, socklen_t len, int type,
}
result_buf->h_addr_list = (char **) addr_list;
+ result_buf->h_aliases = alias;
break;
} else {
free(packet);
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index 21864ba4f..afea3c6e6 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -160,6 +160,16 @@ void attribute_hidden (*__app_fini)(void) = NULL;
void attribute_hidden (*__rtld_fini)(void) = NULL;
+#ifdef _DL_FINI_CRT_COMPAT
+void attribute_hidden (*__dl_fini)(void) = NULL;
+
+void _set__dl_fini(void *fini_func)
+{
+ if (fini_func != NULL)
+ __dl_fini = fini_func;
+}
+#endif
+
/* __uClibc_start_main is the new main stub for uClibc. This function is
* called from crt0 (version 0.9.16 or newer), after ALL shared libraries
* are initialized, just before we call the application's main function.
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index 280f42cb7..c70318148 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -223,6 +223,11 @@ extern void (*__app_fini)(void);
#endif
extern void (*__rtld_fini)(void);
+
+#ifdef _DL_FINI_CRT_COMPAT
+extern void (*__dl_fini)(void);
+#endif
+
/*
* Normal program termination
*/
@@ -242,6 +247,9 @@ void exit(int rv)
#ifndef _DL_FINI_CRT_COMPAT
if (__rtld_fini != NULL)
(__rtld_fini)();
+#else
+ if (__dl_fini != NULL)
+ (__dl_fini)();
#endif
/* If we are using stdio, try to shut it down. At the very least,
diff --git a/libc/string/arm/strncmp.S b/libc/string/arm/strncmp.S
index 6f478b5ed..13eef9ec2 100644
--- a/libc/string/arm/strncmp.S
+++ b/libc/string/arm/strncmp.S
@@ -35,10 +35,11 @@
.align 4; \
strncmp:
- /* if ((len - 1) < 0) return 0 */
+ /* if (len == 0) return 0 */
+ cmp r2, #0
+ moveq r0, #0
+ moveq pc, lr
subs r2, r2, #1
- movmi r0, #0
- movmi pc, lr
/* ip == last src address to compare */
add ip, r0, r2
diff --git a/libc/string/i386/string.c b/libc/string/i386/string.c
index 779087aed..8a7f1a89b 100644
--- a/libc/string/i386/string.c
+++ b/libc/string/i386/string.c
@@ -48,12 +48,15 @@ char * strncpy(char * dest, const char * src, size_t count)
{
int d0, d1, d2, d3;
__asm__ __volatile__(
- "1:\tdecl %2\n\t"
- "js 2f\n\t"
+ "incl %2\n"
+ "1:\n"
+ "decl %2\n"
+ "jz 2f\n"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n\t"
+ "decl %2\n"
"rep\n\t"
"stosb\n"
"2:"
@@ -93,14 +96,17 @@ char *strncat(char * dest,
"scasb\n\t"
"decl %1\n\t"
"movl %8,%3\n"
+ "incl %3\n"
"1:\tdecl %3\n\t"
- "js 2f\n\t"
+ "jz 2f\n"
"lodsb\n\t"
"stosb\n\t"
"testb %%al,%%al\n\t"
"jne 1b\n"
+ "jmp 3f\n"
"2:\txorl %2,%2\n\t"
- "stosb"
+ "stosb\n"
+ "3:"
: "=&S" (d0), "=&D" (d1), "=&a" (d2), "=&c" (d3)
: "0" (src),"1" (dest),"2" (0),"3" (0xffffffff), "g" (count)
: "memory");
@@ -141,8 +147,9 @@ int strncmp(const char *cs, const char *ct, size_t count)
register int __res;
int d0, d1, d2;
__asm__ __volatile__(
+ "incl %3\n"
"1:\tdecl %3\n\t"
- "js 2f\n\t"
+ "jz 2f\n"
"lodsb\n\t"
"scasb\n\t"
"jne 3f\n\t"
@@ -226,12 +233,12 @@ size_t strnlen(const char *s, size_t count)
register int __res;
__asm__ __volatile__(
"movl %2,%0\n\t"
+ "incl %1\n"
"jmp 2f\n"
"1:\tcmpb $0,(%0)\n\t"
"je 3f\n\t"
"incl %0\n"
"2:\tdecl %1\n\t"
- "cmpl $-1,%1\n\t"
"jne 1b\n"
"3:\tsubl %2,%0"
:"=a" (__res), "=&d" (d0)
diff --git a/libc/sysdeps/linux/common/getcwd.c b/libc/sysdeps/linux/common/getcwd.c
index a1de4510c..b38ea65c0 100644
--- a/libc/sysdeps/linux/common/getcwd.c
+++ b/libc/sysdeps/linux/common/getcwd.c
@@ -5,6 +5,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include <string.h>
+#include <sys/param.h>
#include <sys/syscall.h>
#ifdef __NR_getcwd
@@ -164,7 +165,7 @@ char *getcwd(char *buf, int size)
__set_errno(EINVAL);
return NULL;
}
- alloc_size = PATH_MAX;
+ alloc_size = MAX (PATH_MAX, getpagesize ());
}
path=buf;
if (buf == NULL) {
diff --git a/libc/sysdeps/linux/common/getdents.c b/libc/sysdeps/linux/common/getdents.c
index ab6a276bb..1d066f0ee 100644
--- a/libc/sysdeps/linux/common/getdents.c
+++ b/libc/sysdeps/linux/common/getdents.c
@@ -30,7 +30,9 @@
#include <sys/syscall.h>
+#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
struct kernel_dirent
{
@@ -40,6 +42,8 @@ struct kernel_dirent
char d_name[256];
};
+#if ! defined __UCLIBC_HAS_LFS__ || ! defined __NR_getdents64
+
#define __NR___syscall_getdents __NR_getdents
static inline _syscall3(int, __syscall_getdents, int, fd, unsigned char *, kdirp, size_t, count);
@@ -98,3 +102,33 @@ ssize_t __getdents (int fd, char *buf, size_t nbytes)
}
return (char *) dp - buf;
}
+
+#else
+
+extern ssize_t __getdents64 (int fd, char *buf, size_t nbytes);
+ssize_t __getdents (int fd, char *buf, size_t nbytes)
+{
+ struct dirent *dp;
+ struct dirent64 *dp64;
+ ssize_t ret = __getdents64 (fd, buf, nbytes);
+
+ if (ret <= 0)
+ return ret;
+
+ dp64 = (struct dirent64 *) buf;
+ buf += ret;
+ while ((void *) dp64 < (void *) buf) {
+ dp = (struct dirent *) dp64;
+ dp->d_ino = dp64->d_ino;
+ dp->d_off = dp64->d_off;
+ dp->d_reclen = dp64->d_reclen;
+ dp->d_type = dp64->d_type;
+ memmove (dp->d_name, dp64->d_name, dp->d_reclen - offsetof (struct dirent64, d_name));
+ memmove (dp64, dp, dp->d_reclen);
+ dp64 = ((void *) dp64) + dp->d_reclen;
+ }
+
+ return ret;
+}
+
+#endif
diff --git a/libc/sysdeps/linux/common/getdents64.c b/libc/sysdeps/linux/common/getdents64.c
index a37f5e514..8750f67e6 100644
--- a/libc/sysdeps/linux/common/getdents64.c
+++ b/libc/sysdeps/linux/common/getdents64.c
@@ -33,7 +33,9 @@
#if defined __UCLIBC_HAS_LFS__ && defined __NR_getdents64
+#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
struct kernel_dirent64
{
@@ -95,7 +97,7 @@ ssize_t __getdents64 (int fd, char *buf, size_t nbytes)
dp->d_ino = kdp->d_ino;
dp->d_off = kdp->d_off;
dp->d_reclen = new_reclen;
- dp->d_type = DT_UNKNOWN;
+ dp->d_type = kdp->d_type;
memcpy (dp->d_name, kdp->d_name,
kdp->d_reclen - offsetof (struct kernel_dirent64, d_name));
dp = (struct dirent64 *) ((char *) dp + new_reclen);
diff --git a/libc/sysdeps/linux/common/posix_fadvise.c b/libc/sysdeps/linux/common/posix_fadvise.c
index b37f28861..387cf4ab5 100644
--- a/libc/sysdeps/linux/common/posix_fadvise.c
+++ b/libc/sysdeps/linux/common/posix_fadvise.c
@@ -21,7 +21,7 @@ int __libc_posix_fadvise(int fd, off_t offset, off_t len, int advice)
}
weak_alias(__libc_posix_fadvise, posix_fadvise);
-#if defined __UCLIBC_HAS_LFS__ && !defined __NR_fadvise64_64
+#if defined __UCLIBC_HAS_LFS__ && (!defined __NR_fadvise64_64 || !defined _syscall6)
weak_alias(__libc_posix_fadvise, posix_fadvise64);
#endif
diff --git a/libc/sysdeps/linux/common/readahead.c b/libc/sysdeps/linux/common/readahead.c
new file mode 100644
index 000000000..5220b5dc4
--- /dev/null
+++ b/libc/sysdeps/linux/common/readahead.c
@@ -0,0 +1,52 @@
+/* Provide kernel hint to read ahead.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/syscall.h>
+#include <bits/wordsize.h>
+
+#ifdef __NR_readahead
+
+# define __NR___readahead __NR_readahead
+
+# if __WORDSIZE == 64
+
+static inline _syscall3(ssize_t, __readahead, int, fd,
+ off_t, offset, size_t, count);
+
+ssize_t readahead(int fd, off_t offset, size_t count)
+{
+ return __readahead(fd, offset, count);
+}
+
+# else
+
+static inline _syscall4(ssize_t, __readahead, int, fd,
+ off_t, high_offset, off_t, low_offset, size_t, count);
+
+ssize_t readahead(int fd, off64_t offset, size_t count)
+{
+ return __readahead(fd, (off_t) (offset >> 32), (off_t) (offset & 0xffffffff), count);
+}
+
+# endif
+
+#endif
diff --git a/libc/sysdeps/linux/i386/bits/syscalls.h b/libc/sysdeps/linux/i386/bits/syscalls.h
index 944fb734a..1b364555e 100644
--- a/libc/sysdeps/linux/i386/bits/syscalls.h
+++ b/libc/sysdeps/linux/i386/bits/syscalls.h
@@ -100,6 +100,14 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
}
+#undef _syscall6
+#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5,type6,arg6) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5, type6 arg6) \
+{ \
+return (type) (INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6)); \
+}
+
#define INLINE_SYSCALL(name, nr, args...) \
({ \
unsigned int resultvar; \
@@ -125,6 +133,7 @@ return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
#define LOADARGS_3 LOADARGS_1
#define LOADARGS_4 LOADARGS_1
#define LOADARGS_5 LOADARGS_1
+#define LOADARGS_6 LOADARGS_1 "push %%ebp ; movl %7, %%ebp\n\t"
#define RESTOREARGS_0
#define RESTOREARGS_1 \
@@ -133,6 +142,7 @@ return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
#define RESTOREARGS_3 RESTOREARGS_1
#define RESTOREARGS_4 RESTOREARGS_1
#define RESTOREARGS_5 RESTOREARGS_1
+#define RESTOREARGS_6 "pop %%ebp\n\t" RESTOREARGS_1
#define ASMFMT_0()
#define ASMFMT_1(arg1) \
@@ -145,6 +155,8 @@ return (type) (INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5)); \
, "aD" (arg1), "c" (arg2), "d" (arg3), "S" (arg4)
#define ASMFMT_5(arg1, arg2, arg3, arg4, arg5) \
, "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5)
+#define ASMFMT_6(arg1, arg2, arg3, arg4, arg5, arg6) \
+ , "a" (arg1), "c" (arg2), "d" (arg3), "S" (arg4), "D" (arg5), "m" (arg6)
#endif /* __ASSEMBLER__ */
diff --git a/libc/sysdeps/linux/mips/bits/stat.h b/libc/sysdeps/linux/mips/bits/stat.h
index cc077b8fc..bb4076f05 100644
--- a/libc/sysdeps/linux/mips/bits/stat.h
+++ b/libc/sysdeps/linux/mips/bits/stat.h
@@ -37,7 +37,7 @@
struct stat
{
__dev_t st_dev;
- long int st_pad1[3];
+ long int st_pad1[2];
#ifndef __USE_FILE_OFFSET64
__ino_t st_ino; /* File serial number. */
#else
@@ -49,12 +49,12 @@ struct stat
__gid_t st_gid; /* Group ID of the file's group.*/
__dev_t st_rdev; /* Device number, if device. */
#ifndef __USE_FILE_OFFSET64
- long int st_pad2[2];
+ long int st_pad2[1];
__off_t st_size; /* Size of file, in bytes. */
/* SVR4 added this extra long to allow for expansion of off_t. */
long int st_pad3;
#else
- long int st_pad2[3];
+ long int st_pad2[2];
__off64_t st_size; /* Size of file, in bytes. */
#endif
/*
@@ -81,14 +81,14 @@ struct stat
struct stat64
{
__dev_t st_dev;
- long int st_pad1[3];
+ long int st_pad1[2];
__ino64_t st_ino; /* File serial number. */
__mode_t st_mode; /* File mode. */
__nlink_t st_nlink; /* Link count. */
__uid_t st_uid; /* User ID of the file's owner. */
__gid_t st_gid; /* Group ID of the file's group.*/
__dev_t st_rdev; /* Device number, if device. */
- long int st_pad2[3];
+ long int st_pad2[2];
__off64_t st_size; /* Size of file, in bytes. */
/*
* Actually this should be timestruc_t st_atime, st_mtime and
diff --git a/libc/sysdeps/linux/mips/bits/syscalls.h b/libc/sysdeps/linux/mips/bits/syscalls.h
index 8645d9d75..7133d83e3 100644
--- a/libc/sysdeps/linux/mips/bits/syscalls.h
+++ b/libc/sysdeps/linux/mips/bits/syscalls.h
@@ -18,6 +18,9 @@
#ifndef __ASSEMBLER__
+#define __SYSCALL_CLOBBERS "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
+ "$14", "$15", "$24", "$25", "memory"
+
#define _syscall0(type,name) \
type name(void) \
{ \
@@ -33,8 +36,7 @@ type name(void) \
".set reorder" \
: "=r" (__v0), "=r" (__a3) \
: "i" (SYS_ify(name)) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -60,8 +62,7 @@ type name(atype a) \
".set reorder" \
: "=r" (__v0), "=r" (__a3) \
: "r" (__a0), "i" (SYS_ify(name)) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -88,8 +89,7 @@ type name(atype a,btype b) \
".set reorder" \
: "=r" (__v0), "=r" (__a3) \
: "r" (__a0), "r" (__a1), "i" (SYS_ify(name)) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -117,8 +117,7 @@ type name (atype a, btype b, ctype c) \
".set reorder" \
: "=r" (__v0), "=r" (__a3) \
: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -146,8 +145,7 @@ type name (atype a, btype b, ctype c, dtype d) \
".set reorder" \
: "=r" (__v0), "+r" (__a3) \
: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -181,8 +179,7 @@ type name (atype a,btype b,ctype c,dtype d,etype e) \
: "=r" (__v0), "+r" (__a3) \
: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
"m" (constE) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -219,8 +216,7 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f) \
: "=r" (__v0), "+r" (__a3) \
: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
"m" (constE), "m" (constF) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
@@ -260,8 +256,7 @@ type name (atype a,btype b,ctype c,dtype d,etype e,ftype f,gtype g) \
: "=r" (__v0), "+r" (__a3) \
: "r" (__a0), "r" (__a1), "r" (__a2), "i" (SYS_ify(name)), \
"m" (constE), "m" (constF), "m" (constG) \
- : "$1", "$3", "$8", "$9", "$10", "$11", "$12", "$13", \
- "$14", "$15", "$24", "$25", "memory"); \
+ : __SYSCALL_CLOBBERS); \
err = __a3; \
sys_result = __v0; \
} \
diff --git a/libc/sysdeps/linux/mips/brk.c b/libc/sysdeps/linux/mips/brk.c
index c33111ed7..3eb4d414d 100644
--- a/libc/sysdeps/linux/mips/brk.c
+++ b/libc/sysdeps/linux/mips/brk.c
@@ -1,5 +1,5 @@
/* brk system call for Linux/MIPS.
- Copyright (C) 2000 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2005, 2006 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -31,10 +31,11 @@ int brk (void *addr)
register long int res __asm__ ("$2");
asm ("move\t$4,%2\n\t"
+ "li\t%0,%1\n\t"
"syscall" /* Perform the system call. */
: "=r" (res)
- : "0" (__NR_brk), "r" (addr)
- : "$4", "$7");
+ : "I" (__NR_brk), "r" (addr)
+ : "$4", "$7", __SYSCALL_CLOBBERS);
newbrk = (void *) res;
}
__curbrk = newbrk;
diff --git a/libc/sysdeps/linux/mips/pipe.S b/libc/sysdeps/linux/mips/pipe.S
index c3afae550..41eefe670 100644
--- a/libc/sysdeps/linux/mips/pipe.S
+++ b/libc/sysdeps/linux/mips/pipe.S
@@ -10,15 +10,28 @@
.globl pipe
.ent pipe, 0
pipe:
+ .frame sp, 24, sp
+#ifdef __PIC__
+ .set noreorder
+ .cpload $25
+ .set reorder
addiu sp,sp,-24
+ .cprestore 16
+#else
+ addiu sp,sp,-24
+#endif
sw a0,16(sp)
li v0,__NR_pipe
syscall
beqz a3, 1f
- la t3, errno
- sw v0, (t3)
- li v0, -1
- b 2f
+ addiu sp,sp,24
+ move a0,v0
+#ifdef __PIC__
+ la t9, __syscall_error
+ jr t9
+#else
+ j __syscall_error
+#endif
1:
lw a0, 16(sp)
sw v0, 0(a0)
diff --git a/libc/sysdeps/linux/mips/pipe.c b/libc/sysdeps/linux/mips/pipe.c
deleted file mode 100644
index 65e335964..000000000
--- a/libc/sysdeps/linux/mips/pipe.c
+++ /dev/null
@@ -1,23 +0,0 @@
-/* pipe system call for Linux/MIPS */
-
-/*see uClibc's sh/pipe.c and glibc-2.2.4's mips/pipe.S */
-
-#include <errno.h>
-#include <unistd.h>
-#include <syscall.h>
-
-int pipe(int *fd)
-{
- register long int res __asm__ ("$2"); // v0
- register long int res2 __asm__ ("$3"); // v1
-
- asm ("move\t$4,%2\n\t" // $4 = a0
- "syscall" /* Perform the system call. */
- : "=r" (res)
- : "0" (__NR_pipe), "r" (fd)
- : "$4", "$7");
-
- fd[0] = res;
- fd[1] = res2;
- return(0);
-}
diff --git a/libc/sysdeps/linux/powerpc/bits/kernel_types.h b/libc/sysdeps/linux/powerpc/bits/kernel_types.h
index 711ca4f21..223037545 100644
--- a/libc/sysdeps/linux/powerpc/bits/kernel_types.h
+++ b/libc/sysdeps/linux/powerpc/bits/kernel_types.h
@@ -4,9 +4,11 @@
* our private content, and not the kernel header, will win.
* -Erik
*/
-#if ! defined _PPC_POSIX_TYPES_H && ! defined _PPC64_POSIX_TYPES_H
+#if ! defined _PPC_POSIX_TYPES_H && ! defined _PPC64_POSIX_TYPES_H && \
+ ! defined _ASM_POWERPC_POSIX_TYPES_H
#define _PPC_POSIX_TYPES_H
#define _PPC64_POSIX_TYPES_H
+#define _ASM_POWERPC_POSIX_TYPES_H
# if __WORDSIZE == 64
typedef unsigned int __kernel_dev_t;
diff --git a/libc/sysdeps/linux/powerpc/bits/syscalls.h b/libc/sysdeps/linux/powerpc/bits/syscalls.h
index 6168f3906..e28c380ee 100644
--- a/libc/sysdeps/linux/powerpc/bits/syscalls.h
+++ b/libc/sysdeps/linux/powerpc/bits/syscalls.h
@@ -5,67 +5,164 @@
# error "Never use <bits/syscalls.h> directly; include <sys/syscall.h> instead."
#endif
+#include <errno.h>
+
/* This includes the `__NR_<name>' syscall numbers taken from the Linux kernel
* header files. It also defines the traditional `SYS_<name>' macros for older
* programs. */
#include <bits/sysnum.h>
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno.
+ On powerpc a system call basically clobbers the same registers like a
+ function call, with the exception of LR (which is needed for the
+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
+ an error return status). */
-#define __STRINGIFY(s) __STRINGIFY2 (s)
-#define __STRINGIFY2(s) #s
-
-#undef JUMPTARGET
-#ifdef __PIC__
-#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall@plt)
+# undef INLINE_SYSCALL
+#if 1
+# define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err)); \
+ sc_ret = -1L; \
+ } \
+ sc_ret; \
+ })
#else
-#define __MAKE_SYSCALL __STRINGIFY(__uClibc_syscall)
+# define INLINE_SYSCALL(name, nr, args...) \
+ ({ \
+ INTERNAL_SYSCALL_DECL (sc_err); \
+ long int sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, args); \
+ if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err)) \
+ { \
+ sc_ret = __syscall_error(INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));\
+ } \
+ sc_ret; \
+ })
#endif
-#define unified_syscall_body(name) \
- __asm__ ( \
- ".section \".text\"\n\t" \
- ".align 2\n\t" \
- ".globl " __STRINGIFY(name) "\n\t" \
- ".type " __STRINGIFY(name) ",@function\n\t" \
- #name":\tli 0," __STRINGIFY(__NR_##name) "\n\t" \
- "b " __MAKE_SYSCALL "\n\t" \
- ".size\t" __STRINGIFY(name) ",.""-" __STRINGIFY(name) "\n" \
- )
+/* Define a macro which expands inline into the wrapper code for a system
+ call. This use is for internal calls that do not need to handle errors
+ normally. It will never touch errno.
+ On powerpc a system call basically clobbers the same registers like a
+ function call, with the exception of LR (which is needed for the
+ "sc; bnslr+" sequence) and CR (where only CR0.SO is clobbered to signal
+ an error return status). */
+
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) long int err
+
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+ ({ \
+ register long int r0 __asm__ ("r0"); \
+ register long int r3 __asm__ ("r3"); \
+ register long int r4 __asm__ ("r4"); \
+ register long int r5 __asm__ ("r5"); \
+ register long int r6 __asm__ ("r6"); \
+ register long int r7 __asm__ ("r7"); \
+ register long int r8 __asm__ ("r8"); \
+ register long int r9 __asm__ ("r9"); \
+ register long int r10 __asm__ ("r10"); \
+ register long int r11 __asm__ ("r11"); \
+ register long int r12 __asm__ ("r12"); \
+ LOADARGS_##nr(name, args); \
+ __asm__ __volatile__ \
+ ("sc \n\t" \
+ "mfcr %0" \
+ : "=&r" (r0), \
+ "=&r" (r3), "=&r" (r4), "=&r" (r5), "=&r" (r6), "=&r" (r7), \
+ "=&r" (r8), "=&r" (r9), "=&r" (r10), "=&r" (r11), "=&r" (r12) \
+ : ASM_INPUT_##nr \
+ : "cr0", "ctr", "memory"); \
+ err = r0; \
+ (int) r3; \
+ })
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
+ INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
+
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
+ ((void) (val), __builtin_expect ((err) & (1 << 28), 0))
+
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err) (val)
+
+# define LOADARGS_0(name, dummy) \
+ r0 = (long int)name
+# define LOADARGS_1(name, __arg1) \
+ LOADARGS_0(name, 0); \
+ r3 = (long int)__arg1
+# define LOADARGS_2(name, __arg1, __arg2) \
+ LOADARGS_1(name, __arg1); \
+ r4 = (long int)__arg2
+# define LOADARGS_3(name, __arg1, __arg2, __arg3) \
+ LOADARGS_2(name, __arg1, __arg2); \
+ r5 = (long int)__arg3
+# define LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4) \
+ LOADARGS_3(name, __arg1, __arg2, __arg3); \
+ r6 = (long int)__arg4
+# define LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5) \
+ LOADARGS_4(name, __arg1, __arg2, __arg3, __arg4); \
+ r7 = (long int)__arg5
+# define LOADARGS_6(name, __arg1, __arg2, __arg3, __arg4, __arg5, __arg6) \
+ LOADARGS_5(name, __arg1, __arg2, __arg3, __arg4, __arg5); \
+ r8 = (long int)__arg6
+
+# define ASM_INPUT_0 "0" (r0)
+# define ASM_INPUT_1 ASM_INPUT_0, "1" (r3)
+# define ASM_INPUT_2 ASM_INPUT_1, "2" (r4)
+# define ASM_INPUT_3 ASM_INPUT_2, "3" (r5)
+# define ASM_INPUT_4 ASM_INPUT_3, "4" (r6)
+# define ASM_INPUT_5 ASM_INPUT_4, "5" (r7)
+# define ASM_INPUT_6 ASM_INPUT_5, "6" (r8)
#undef _syscall0
-#define _syscall0(type,name) \
-type name(void); \
-unified_syscall_body(name)
+#define _syscall0(type,name) \
+type name(void){ \
+ return (type) INLINE_SYSCALL(name, 0); \
+}
#undef _syscall1
#define _syscall1(type,name,type1,arg1) \
-type name(type1 arg1); \
-unified_syscall_body(name)
+type name(type1 arg1){ \
+ return (type) INLINE_SYSCALL(name, 1, arg1); \
+}
#undef _syscall2
#define _syscall2(type,name,type1,arg1,type2,arg2) \
-type name(type1 arg1, type2 arg2); \
-unified_syscall_body(name)
+type name(type1 arg1, type2 arg2){ \
+ return (type) INLINE_SYSCALL(name, 2, arg1, arg2); \
+}
#undef _syscall3
#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
-type name(type1 arg1, type2 arg2, type3 arg3); \
-unified_syscall_body(name)
+type name(type1 arg1, type2 arg2, type3 arg3){ \
+ return (type) INLINE_SYSCALL(name, 3, arg1, arg2, arg3); \
+}
#undef _syscall4
#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4); \
-unified_syscall_body(name)
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4){ \
+ return (type) INLINE_SYSCALL(name, 4, arg1, arg2, arg3, arg4); \
+}
#undef _syscall5
#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5); \
-unified_syscall_body(name)
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5){ \
+ return (type) INLINE_SYSCALL(name, 5, arg1, arg2, arg3, arg4, arg5); \
+}
#undef _syscall6
#define _syscall6(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4,type5,arg5,type6,arg6) \
-type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6); \
-unified_syscall_body(name)
+type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6){ \
+ return (type) INLINE_SYSCALL(name, 6, arg1, arg2, arg3, arg4, arg5, arg6); \
+}
#endif /* _BITS_SYSCALLS_H */
diff --git a/libc/sysdeps/linux/powerpc/brk.S b/libc/sysdeps/linux/powerpc/brk.S
index c0b436d96..610c5265c 100644
--- a/libc/sysdeps/linux/powerpc/brk.S
+++ b/libc/sysdeps/linux/powerpc/brk.S
@@ -37,8 +37,15 @@ __brk:
lwz r6,8(r1)
#ifdef __PIC__
mflr r4
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r5
+ addis r5,r5,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r5,r5,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
bl _GLOBAL_OFFSET_TABLE_@local-4
mflr r5
+# endif
lwz r5,__curbrk@got(r5)
mtlr r4
stw r3,0(r5)
diff --git a/libc/sysdeps/linux/powerpc/bsd-_setjmp.S b/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
index d58e45b13..585878acf 100644
--- a/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
+++ b/libc/sysdeps/linux/powerpc/bsd-_setjmp.S
@@ -29,9 +29,7 @@
_setjmp:
li r4,0 /* Set second argument to 0. */
-#ifdef __PIC__
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+
+ b __sigsetjmp@local
+
.size _setjmp,.-_setjmp
diff --git a/libc/sysdeps/linux/powerpc/bsd-setjmp.S b/libc/sysdeps/linux/powerpc/bsd-setjmp.S
index 6128d9fa2..f95d08217 100644
--- a/libc/sysdeps/linux/powerpc/bsd-setjmp.S
+++ b/libc/sysdeps/linux/powerpc/bsd-setjmp.S
@@ -29,11 +29,9 @@
__setjmp:
li r4,1 /* Set second argument to 1. */
-#ifdef __PIC__
- b __sigsetjmp@plt
-#else
- b __sigsetjmp
-#endif
+
+ b __sigsetjmp@local
+
.size __setjmp,.-__setjmp
.globl setjmp;
diff --git a/libc/sysdeps/linux/powerpc/crt1.S b/libc/sysdeps/linux/powerpc/crt1.S
index c042462e9..7928a7ed3 100644
--- a/libc/sysdeps/linux/powerpc/crt1.S
+++ b/libc/sysdeps/linux/powerpc/crt1.S
@@ -48,8 +48,15 @@ _start:
mr r9,r1 /* Save the stack pointer and pass it to __uClibc_main */
clrrwi r1,r1,4 /* Align stack ptr to 16 bytes */
#ifdef __PIC__
+# ifdef HAVE_ASM_PPC_REL16
+ bcl 20,31,1f
+1: mflr r31
+ addis r31,r31,_GLOBAL_OFFSET_TABLE_-1b@ha
+ addi r31,r31,_GLOBAL_OFFSET_TABLE_-1b@l
+# else
bl _GLOBAL_OFFSET_TABLE_-4@local
mflr r31
+# endif
#endif
/* Set up an initial stack frame, and clear the LR. */
li r0,0
@@ -60,7 +67,8 @@ _start:
lwz r4,0(r9)
/* find argv one word offset from the stack pointer */
addi r5,r9,4
- mr r8,r7 /* Pass _dl_fini from ldso or NULL if statically linked */
+ mr r8,r3 /* Pass _dl_fini from ldso or NULL if statically linked
+ Note: using r3 instead of r7, since linux 2.6 clobbers r7 */
/* Ok, now run uClibc's main() -- shouldn't return */
#ifdef __PIC__
lwz r6,_init@got(r31)
diff --git a/libc/sysdeps/linux/powerpc/setjmp.S b/libc/sysdeps/linux/powerpc/setjmp.S
index b1625b615..3bdf6cbfe 100644
--- a/libc/sysdeps/linux/powerpc/setjmp.S
+++ b/libc/sysdeps/linux/powerpc/setjmp.S
@@ -76,9 +76,7 @@ FP( stfd fp29,((JB_FPRS+15*2)*4)(3))
FP( stfd fp30,((JB_FPRS+16*2)*4)(3))
stw r31,((JB_GPRS+17)*4)(3)
FP( stfd fp31,((JB_FPRS+17*2)*4)(3))
-#ifdef __PIC__
- b __sigjmp_save@plt
-#else
- b __sigjmp_save
-#endif
+
+ b __sigjmp_save@local
+
.size __sigsetjmp,.-__sigsetjmp
diff --git a/libc/sysdeps/linux/powerpc/sys/procfs.h b/libc/sysdeps/linux/powerpc/sys/procfs.h
index f2424889e..2a5656122 100644
--- a/libc/sysdeps/linux/powerpc/sys/procfs.h
+++ b/libc/sysdeps/linux/powerpc/sys/procfs.h
@@ -32,9 +32,17 @@
__BEGIN_DECLS
+/* These definitions are normally provided by ucontext.h via
+ asm/sigcontext.h, asm/ptrace.h, and asm/elf.h. Otherwise we define
+ them here. */
+#ifndef __PPC64_ELF_H
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
#define ELF_NFPREG 33 /* includes fpscr */
-#define ELF_NVRREG 33 /* includes vscr */
+#if __WORDSIZE == 32
+# define ELF_NVRREG 33 /* includes vscr */
+#else
+# define ELF_NVRREG 34 /* includes vscr */
+#endif
typedef unsigned long elf_greg_t;
typedef elf_greg_t elf_gregset_t[ELF_NGREG];
@@ -42,16 +50,12 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG];
typedef double elf_fpreg_t;
typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-/* gcc 3.1 and newer support __uint128_t. */
-#if !__GNUC_PREREQ(3,1)
-typedef struct {
- unsigned long u[4];
-} __attribute((aligned(16))) __uint128_t;
-#endif
-
/* Altivec registers */
-typedef __uint128_t elf_vrreg_t;
+typedef struct {
+ unsigned int u[4];
+} __attribute__ ((aligned (16))) elf_vrreg_t;
typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
+#endif
struct elf_siginfo
{
diff --git a/libc/sysdeps/linux/sh/bits/setjmp.h b/libc/sysdeps/linux/sh/bits/setjmp.h
index 5182300f3..6458dfefd 100644
--- a/libc/sysdeps/linux/sh/bits/setjmp.h
+++ b/libc/sysdeps/linux/sh/bits/setjmp.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2003, 2005 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
@@ -17,8 +17,10 @@
02111-1307 USA. */
/* Define the machine-dependent type `jmp_buf'. SH version. */
+#ifndef _BITS_SETJMP_H
+#define _BITS_SETJMP_H 1
-#ifndef _SETJMP_H
+#if !defined _SETJMP_H && !defined _PTHREAD_H
# error "Never include <bits/setjmp.h> directly; use <setjmp.h> instead."
#endif
@@ -42,9 +44,13 @@ typedef struct
} __jmp_buf[1];
#endif
-#define JB_SIZE (4 * 15)
+#if defined __USE_MISC || defined _ASM
+# define JB_SIZE (4 * 15)
+#endif
/* Test if longjmp to JMPBUF would unwind the frame
containing a local variable at ADDRESS. */
#define _JMPBUF_UNWINDS(jmpbuf, address) \
- ((void *) (address) < &(jmpbuf)[0].__regs[7])
+ ((void *) (address) < (void *) (jmpbuf)[0].__regs[7])
+
+#endif /* bits/setjmp.h */
diff --git a/utils/Makefile b/utils/Makefile
index 7023a9b21..2c48749d9 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -19,9 +19,11 @@
TOPDIR=../
include $(TOPDIR)Rules.mak
-CFLAGS+=$(SSP_ALL_CFLAGS)
+CFLAGS+=$(SSP_ALL_CFLAGS) -B../lib
+# This isnt the correct variable, but hijacking it for now is fine by me as it works
+LDPIEFLAG+=../lib/$(UCLIBC_LDSO)
-TARGETS = ldd ldconfig readelf
+TARGETS = ldd ldconfig
ifeq ($(strip $(UCLIBC_HAS_LOCALE)),y)
TARGET_ICONV = iconv