summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--TODO21
-rwxr-xr-xextra/scripts/fix_includes.sh4
-rw-r--r--include/elf.h30
-rw-r--r--include/errno.h13
-rw-r--r--include/signal.h2
-rw-r--r--include/sys/cdefs.h78
-rw-r--r--include/sys/sysmacros.h20
-rw-r--r--ldso/include/dl-defs.h6
-rw-r--r--ldso/include/dl-elf.h54
-rw-r--r--ldso/include/dl-hash.h10
-rw-r--r--ldso/include/dl-string.h30
-rw-r--r--ldso/include/dl-syscall.h6
-rw-r--r--ldso/include/dlfcn.h11
-rw-r--r--ldso/include/unsecvars.h22
-rw-r--r--ldso/ldso/dl-elf.c184
-rw-r--r--ldso/ldso/dl-hash.c16
-rw-r--r--ldso/ldso/dl-startup.c136
-rw-r--r--ldso/ldso/ldso.c142
-rw-r--r--ldso/ldso/mips/dl-startup.h76
-rw-r--r--ldso/ldso/mips/elfinterp.c78
-rw-r--r--ldso/ldso/mips/resolve.S38
-rw-r--r--ldso/libdl/libdl.c173
-rw-r--r--libc/inet/ntop.c2
-rw-r--r--libc/inet/socketcalls.c12
-rw-r--r--libc/misc/error/err.c2
-rw-r--r--libc/misc/glob/glob.c2
-rw-r--r--libc/misc/internals/Makefile8
-rw-r--r--libc/misc/internals/__uClibc_main.c45
-rw-r--r--libc/misc/pthread/weaks.c6
-rw-r--r--libc/misc/sysvipc/ipc.h4
-rw-r--r--libc/misc/sysvipc/msgq.c14
-rw-r--r--libc/misc/sysvipc/shm.c14
-rw-r--r--libc/misc/time/time.c27
-rw-r--r--libc/stdio/_fpmaxtostr.c388
-rw-r--r--libc/stdio/old_vfprintf.c2
-rw-r--r--libc/stdio/perror.c2
-rw-r--r--libc/stdio/vfprintf.c110
-rw-r--r--libc/stdlib/abort.c129
-rw-r--r--libc/stdlib/atexit.c3
-rw-r--r--libc/stdlib/malloc-simple/alloc.c189
-rw-r--r--libc/stdlib/malloc-standard/malloc.c4
-rw-r--r--libc/string/Makefile6
-rw-r--r--libc/string/wstring.c16
-rw-r--r--libc/sysdeps/linux/common/Makefile1
-rw-r--r--libc/sysdeps/linux/common/__syscall_fcntl.c17
-rw-r--r--libc/sysdeps/linux/common/bits/errno.h2
-rw-r--r--libc/sysdeps/linux/common/bits/ipc.h16
-rw-r--r--libc/sysdeps/linux/common/bits/sem.h19
-rw-r--r--libc/sysdeps/linux/common/bits/sigthread.h12
-rw-r--r--libc/sysdeps/linux/common/bits/stat.h16
-rw-r--r--libc/sysdeps/linux/common/ioperm.c6
-rw-r--r--libc/sysdeps/linux/common/pread_write.c4
-rw-r--r--libc/sysdeps/linux/common/ssp.c73
-rw-r--r--libc/sysdeps/linux/common/umount.c15
-rw-r--r--libc/sysdeps/linux/common/xstatconv.c73
-rw-r--r--libc/sysdeps/linux/mips/__syscall_error.c8
-rw-r--r--libc/sysdeps/linux/mips/bits/msq.h23
-rw-r--r--libc/sysdeps/linux/mips/bsd-setjmp.S2
-rw-r--r--libc/sysdeps/linux/mips/clone.S5
-rw-r--r--utils/Makefile4
60 files changed, 1286 insertions, 1145 deletions
diff --git a/TODO b/TODO
index 370af9e68..d8fd25e06 100644
--- a/TODO
+++ b/TODO
@@ -5,8 +5,17 @@ TODO list for the uClibc 0.9.28 release:
*) Audit header files. When options are disabled, also disable
them in the include files as well by checking for the proper
define from include/bits/uClibc_config.h (pulled in from features.h)
- *) Test each architecture with the latest LTP testsuite, and post
- LTP testsuite results for each architecture on uclibc.org.
+ *) Test cris, i386, mips, mipsel, sh, x86_64, arm, armeb, and powerpc
+ with the latest LTP testsuite. Fix any regressions and post LTP
+ testsuite results for each architecture on uclibc.org.
+ *) Fix it so valgrind 2.4.0 no longer complains about the memory mmaped
+ and used by ldso. Currently it whines on basically about virtually
+ every function call when doing default lazy binding, which makes its
+ output virtually useless due to the excess noise.
+ *) Change all references to the older "Library GPL" to the "Lesser GPL"
+ and update COPYING.LIB to LGPL version 2.1.
+
+
TODO list for the uClibc 1.0.0 release:
@@ -45,10 +54,6 @@ TODO list for the uClibc 1.0.0 release:
from ldso (such as HZ). Other stuff it currently just makes
up, which is obviously wrong. Also bits/uClibc_clk_tck.h
needs to be updated at the same time to get proper HZ values.
- *) It would nice if valgrind wouldn't complain about the atexit() malloc'd
- memory for destructors, which happens since the dynamic linker calls
- atexit(), which calls malloc() prior to valgrind starting, so valgrind
- complains because it didn't see that memory allocated.
*) poll emulation using select() for old 2.0.x uClinux kernels
in libc/sysdeps/linux/common/poll.c fails some python self-tests.
Of course, modern systems using the actuall poll() syscall work fine.
@@ -86,6 +91,7 @@ Arch specific TODO:
alpha:
_init/_fini hangs signal-ed (assert test)
output from cloned children seems funky (unistd/clone test)
+ ldso is not implemented
m68k:
need to verify libc again
ldso needs to be updated since it's totally broken atm
@@ -93,7 +99,8 @@ Arch specific TODO:
need a sigaction.c since common one doesnt work (signal tests)
ldso needs to be updated since it's totally broken atm
x86_64:
- ldso needs to be finished off (elfinterp/resolve)
+ ldso needs to have lazy bindings checked
+ pthread isn't working really at all (pthreads tests)
diff --git a/extra/scripts/fix_includes.sh b/extra/scripts/fix_includes.sh
index a57e4f253..910242fa5 100755
--- a/extra/scripts/fix_includes.sh
+++ b/extra/scripts/fix_includes.sh
@@ -100,13 +100,13 @@ then
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
diff --git a/include/elf.h b/include/elf.h
index 11f82ba50..e00969266 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -920,23 +920,25 @@ typedef struct
typedef struct
{
- int a_type; /* Entry type */
+ uint32_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint32_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf32_auxv_t;
typedef struct
{
- long int a_type; /* Entry type */
+ uint64_t a_type; /* Entry type */
union
{
- long int a_val; /* Integer value */
- void *a_ptr; /* Pointer value */
- void (*a_fcn) (void); /* Function pointer value */
+ uint64_t a_val; /* Integer value */
+ /* We use to have pointer elements added here. We cannot do that,
+ though, since it does not work when using 32-bit definitions
+ on 64-bit platforms and vice versa. */
} a_un;
} Elf64_auxv_t;
@@ -1907,6 +1909,9 @@ typedef Elf32_Addr Elf32_Conflict;
#define LITUSE_ALPHA_TLS_GD 4
#define LITUSE_ALPHA_TLS_LDM 5
+/* Legal values for d_tag of Elf64_Dyn. */
+#define DT_ALPHA_PLTRO 0x70000000
+#define DT_ALPHA_NUM 1
/* PowerPC specific declarations */
@@ -2017,10 +2022,19 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_PPC_DIAB_RELSDA_HI 184 /* like EMB_RELSDA, but high 16 bit */
#define R_PPC_DIAB_RELSDA_HA 185 /* like EMB_RELSDA, adjusted high 16 */
+/* GNU relocs used in PIC code sequences. */
+#define R_PPC_REL16 249 /* word32 (sym-.) */
+#define R_PPC_REL16_LO 250 /* half16 (sym-.)@l */
+#define R_PPC_REL16_HI 251 /* half16 (sym-.)@h */
+#define R_PPC_REL16_HA 252 /* half16 (sym-.)@ha */
+
/* This is a phony reloc to handle any old fashioned TOC16 references
that may still be in object files. */
#define R_PPC_TOC16 255
+/* PowerPC specific values for the Dyn d_tag field. */
+#define DT_PPC_GOT (DT_LOPROC + 0)
+#define DT_PPC_NUM 1
/* PowerPC64 relocations defined by the ABIs */
#define R_PPC64_NONE R_PPC_NONE
diff --git a/include/errno.h b/include/errno.h
index 8c7f666fe..390e51521 100644
--- a/include/errno.h
+++ b/include/errno.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 94, 95, 96, 97 Free Software Foundation, Inc.
+/* Copyright (C) 1991,92,93,94,95,96,97,2002 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
@@ -25,8 +25,8 @@
/* The includer defined __need_Emath if he wants only the definitions
of EDOM and ERANGE, and not everything else. */
#ifndef __need_Emath
-#define _ERRNO_H 1
-#include <features.h>
+# define _ERRNO_H 1
+# include <features.h>
#endif
__BEGIN_DECLS
@@ -47,6 +47,13 @@ __BEGIN_DECLS
extern int errno;
#endif
+#if 0 /*def __USE_GNU uClibc note: not supported */
+
+/* The full and simple forms of the name with which the program was
+ invoked. These variables are set up automatically at startup based on
+ the value of ARGV[0] (this works only if you use GNU ld). */
+extern char *program_invocation_name, *program_invocation_short_name;
+#endif /* __USE_GNU */
#endif /* _ERRNO_H */
__END_DECLS
diff --git a/include/signal.h b/include/signal.h
index 7793cdbe1..c22b4372c 100644
--- a/include/signal.h
+++ b/include/signal.h
@@ -276,7 +276,7 @@ extern int sigqueue (__pid_t __pid, int __sig, __const union sigval __val)
#ifdef __UCLIBC_HAS_SYS_SIGLIST__
/* Names of the signals. This variable exists only for compatibility.
Use `strsignal' instead (see <string.h>). */
-extern __const char *__const _sys_siglist[_NSIG];
+#define _sys_siglist sys_siglist
extern __const char *__const sys_siglist[_NSIG];
#endif /* __UCLIBC_HAS_SYS_SIGLIST__ */
diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h
index f370145f1..0a6d345bc 100644
--- a/include/sys/cdefs.h
+++ b/include/sys/cdefs.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992-2001, 2002 Free Software Foundation, Inc.
+/* Copyright (C) 1992-2001, 2002, 2004, 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
@@ -39,24 +39,28 @@
/* GCC can always grok prototypes. For C++ programs we add throw()
to help it optimize the function calls. But this works only with
- gcc 2.8.x and egcs. */
-# if defined __cplusplus && __GNUC_PREREQ (2,8)
-# define __THROW throw ()
+ gcc 2.8.x and egcs. For gcc 3.2 and up we even mark C functions
+ as non-throwing using a function attribute since programs can use
+ the -fexceptions options for C code as well. */
+# if 0 //!defined __cplusplus && __GNUC_PREREQ (3, 3)
+# define __THROW __attribute__ ((__nothrow__))
+# define __NTH(fct) __attribute__ ((__nothrow__)) fct
# else
-# define __THROW
+# if defined __cplusplus && __GNUC_PREREQ (2,8)
+# define __THROW throw ()
+# define __NTH(fct) fct throw ()
+# else
+# define __THROW
+# define __NTH(fct) fct
+# endif
# endif
-# define __P(args) args __THROW
-/* This macro will be used for functions which might take C++ callback
- functions. */
-# define __PMT(args) args
#else /* Not GCC. */
# define __inline /* No inline functions. */
# define __THROW
-# define __P(args) args
-# define __PMT(args) args
+# define __NTH(fct) fct
# define __const const
# define __signed signed
@@ -64,6 +68,11 @@
#endif /* GCC. */
+/* These two macros are not used in glibc anymore. They are kept here
+ only because some other projects expect the macros to be defined. */
+#define __P(args) args
+#define __PMT(args) args
+
/* For these things, GCC behaves the ANSI way normally,
and the non-ANSI way under -traditional. */
@@ -118,6 +127,12 @@
#endif
+/* Fortify support. */
+#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
+#define __warndecl(name, msg) extern void name (void)
+
+
/* Support for flexible arrays. */
#if __GNUC_PREREQ (2,97)
/* GCC 2.97 supports C99 flexible array members. */
@@ -150,6 +165,17 @@
# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
# define __ASMNAME(cname) __C_SYMBOL_PREFIX__ cname
+/*
+# ifdef __cplusplus
+# define __REDIRECT_NTH(name, proto, alias) \
+ name proto __THROW __asm__ (__ASMNAME (#alias))
+# else
+# define __REDIRECT_NTH(name, proto, alias) \
+ name proto __asm__ (__ASMNAME (#alias)) __THROW
+# endif
+# define __ASMNAME(cname) __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
+*/
/*
#elif __SOME_OTHER_COMPILER__
@@ -225,6 +251,36 @@
# define __attribute_format_strfmon__(a,b) /* Ignore */
#endif
+/* The nonull function attribute allows to mark pointer parameters which
+ must not be NULL. */
+#if __GNUC_PREREQ (3,3)
+# define __nonnull(params) __attribute__ ((__nonnull__ params))
+#else
+# define __nonnull(params)
+#endif
+
+/* If fortification mode, we warn about unused results of certain
+ function calls which can lead to problems. */
+#if __GNUC_PREREQ (3,4)
+# define __attribute_warn_unused_result__ \
+ __attribute__ ((__warn_unused_result__))
+# if __USE_FORTIFY_LEVEL > 0
+# define __wur __attribute_warn_unused_result__
+# endif
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+#ifndef __wur
+# define __wur /* Ignore */
+#endif
+
+/* Forces a function to be always inlined. */
+#if __GNUC_PREREQ (3,2)
+# define __always_inline __inline __attribute__ ((__always_inline__))
+#else
+# define __always_inline __inline
+#endif
+
/* It is possible to compile containing GCC extensions even if GCC is
run in pedantic mode if the uses are carefully marked using the
`__extension__' keyword. But this is not generally available before
diff --git a/include/sys/sysmacros.h b/include/sys/sysmacros.h
index 85dc3d281..c5efca4f9 100644
--- a/include/sys/sysmacros.h
+++ b/include/sys/sysmacros.h
@@ -1,5 +1,5 @@
/* Definitions of macros to access `dev_t' values.
- Copyright (C) 1996, 1997, 1999, 2003 Free Software Foundation, Inc.
+ Copyright (C) 1996, 1997, 1999, 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
@@ -25,6 +25,7 @@
/* If the compiler does not know long long it is out of luck. We are
not going to hack weird hacks to support the dev_t representation
they need. */
+#if 1 /*def __GLIBC_HAVE_LONG_LONG uClibc note: always enable */
__extension__
static __inline unsigned int gnu_dev_major (unsigned long long int __dev)
__THROW;
@@ -36,32 +37,33 @@ static __inline unsigned long long int gnu_dev_makedev (unsigned int __major,
unsigned int __minor)
__THROW;
-#if defined __GNUC__ && __GNUC__ >= 2
+# if defined __GNUC__ && __GNUC__ >= 2
__extension__ static __inline unsigned int
-gnu_dev_major (unsigned long long int __dev) __THROW
+__NTH (gnu_dev_major (unsigned long long int __dev))
{
return ((__dev >> 8) & 0xfff) | ((unsigned int) (__dev >> 32) & ~0xfff);
}
__extension__ static __inline unsigned int
-gnu_dev_minor (unsigned long long int __dev) __THROW
+__NTH (gnu_dev_minor (unsigned long long int __dev))
{
return (__dev & 0xff) | ((unsigned int) (__dev >> 12) & ~0xff);
}
__extension__ static __inline unsigned long long int
-gnu_dev_makedev (unsigned int __major, unsigned int __minor) __THROW
+__NTH (gnu_dev_makedev (unsigned int __major, unsigned int __minor))
{
return ((__minor & 0xff) | ((__major & 0xfff) << 8)
| (((unsigned long long int) (__minor & ~0xff)) << 12)
| (((unsigned long long int) (__major & ~0xfff)) << 32));
}
-#endif
+# endif
/* Access the functions with their traditional names. */
-#define major(dev) gnu_dev_major (dev)
-#define minor(dev) gnu_dev_minor (dev)
-#define makedev(maj, min) gnu_dev_makedev (maj, min)
+# define major(dev) gnu_dev_major (dev)
+# define minor(dev) gnu_dev_minor (dev)
+# define makedev(maj, min) gnu_dev_makedev (maj, min)
+#endif
#endif /* sys/sysmacros.h */
diff --git a/ldso/include/dl-defs.h b/ldso/include/dl-defs.h
index de459b0a8..37588b86c 100644
--- a/ldso/include/dl-defs.h
+++ b/ldso/include/dl-defs.h
@@ -1,12 +1,6 @@
#ifndef _LD_DEFS_H
#define _LD_DEFS_H
-/*
- * NPTL - This was taken from 'sysdeps/generic/ldsodefs.h'. It is
- * used for backtrace capability.
- */
-extern void *__libc_stack_end;
-
#define LIB_ANY -1
#define LIB_DLL 0
#define LIB_ELF 1
diff --git a/ldso/include/dl-elf.h b/ldso/include/dl-elf.h
index d8f3b382c..c487436fc 100644
--- a/ldso/include/dl-elf.h
+++ b/ldso/include/dl-elf.h
@@ -36,6 +36,28 @@ extern int _dl_fixup(struct dyn_elf *rpnt, int flag);
extern void _dl_protect_relro (struct elf_resolve *l);
/*
+ * Bitsize related settings for things ElfW()
+ * does not handle already
+ */
+#if __WORDSIZE == 64
+# define ELF_ST_BIND(val) ELF64_ST_BIND(val)
+# define ELF_ST_TYPE(val) ELF64_ST_TYPE(val)
+# define ELF_R_SYM(i) ELF64_R_SYM(i)
+# define ELF_R_TYPE(i) ELF64_R_TYPE(i)
+# ifndef ELF_CLASS
+# define ELF_CLASS ELFCLASS64
+# endif
+#else
+# define ELF_ST_BIND(val) ELF32_ST_BIND(val)
+# define ELF_ST_TYPE(val) ELF32_ST_TYPE(val)
+# define ELF_R_SYM(i) ELF32_R_SYM(i)
+# define ELF_R_TYPE(i) ELF32_R_TYPE(i)
+# ifndef ELF_CLASS
+# define ELF_CLASS ELFCLASS32
+# endif
+#endif
+
+/*
* Datatype of a relocation on this platform
*/
#ifdef ELF_USES_RELOCA
@@ -65,10 +87,10 @@ extern void _dl_protect_relro (struct elf_resolve *l);
#define DYNAMIC_SIZE (DT_NUM+OS_NUM+ARCH_NUM)
-extern void _dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr, Elf32_Addr load_off);
+extern void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off);
-static inline __attribute__((always_inline))
-void __dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr, Elf32_Addr load_off)
+static __always_inline
+void __dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
{
for (; dpnt->d_tag; dpnt++) {
if (dpnt->d_tag < DT_NUM) {
@@ -84,6 +106,12 @@ void __dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void
dynamic_info[DT_BIND_NOW] = 1;
if (dpnt->d_tag == DT_TEXTREL)
dynamic_info[DT_TEXTREL] = 1;
+#ifdef __LDSO_RUNPATH__
+ if (dpnt->d_tag == DT_RUNPATH)
+ dynamic_info[DT_RPATH] = 0;
+ if (dpnt->d_tag == DT_RPATH && dynamic_info[DT_RUNPATH])
+ dynamic_info[DT_RPATH] = 0;
+#endif
} else if (dpnt->d_tag < DT_LOPROC) {
if (dpnt->d_tag == DT_RELOCCOUNT)
dynamic_info[DT_RELCONT_IDX] = dpnt->d_un.d_val;
@@ -97,21 +125,19 @@ void __dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void
}
#endif
}
-# define ADJUST_DYN_INFO(tag, load_off) \
+#define ADJUST_DYN_INFO(tag, load_off) \
do { \
if (dynamic_info[tag]) \
dynamic_info[tag] += load_off; \
} while(0)
-
- ADJUST_DYN_INFO (DT_HASH, load_off);
- ADJUST_DYN_INFO (DT_PLTGOT, load_off);
- ADJUST_DYN_INFO (DT_STRTAB, load_off);
- ADJUST_DYN_INFO (DT_SYMTAB, load_off);
- ADJUST_DYN_INFO (DT_RELOC_TABLE_ADDR, load_off);
- ADJUST_DYN_INFO (DT_JMPREL, load_off);
-# undef ADJUST_DYN_INFO
-
- }
+ ADJUST_DYN_INFO(DT_HASH, load_off);
+ ADJUST_DYN_INFO(DT_PLTGOT, load_off);
+ ADJUST_DYN_INFO(DT_STRTAB, load_off);
+ ADJUST_DYN_INFO(DT_SYMTAB, load_off);
+ ADJUST_DYN_INFO(DT_RELOC_TABLE_ADDR, load_off);
+ ADJUST_DYN_INFO(DT_JMPREL, load_off);
+#undef ADJUST_DYN_INFO
+}
/* Reloc type classes as returned by elf_machine_type_class().
ELF_RTYPE_CLASS_PLT means this reloc should not be satisfied by
diff --git a/ldso/include/dl-hash.h b/ldso/include/dl-hash.h
index dcad7bcee..162c7b425 100644
--- a/ldso/include/dl-hash.h
+++ b/ldso/include/dl-hash.h
@@ -32,19 +32,19 @@ struct elf_resolve{
unsigned short usage_count;
unsigned short int init_flag;
unsigned long rtld_flags; /* RTLD_GLOBAL, RTLD_NOW etc. */
- unsigned int nbucket;
- unsigned long * elf_buckets;
+ Elf32_Word nbucket;
+ Elf32_Word *elf_buckets;
struct init_fini_list *init_fini;
struct init_fini_list *rtld_local; /* keep tack of RTLD_LOCAL libs in same group */
/*
* These are only used with ELF style shared libraries
*/
- unsigned long nchain;
- unsigned long * chains;
+ Elf32_Word nchain;
+ Elf32_Word *chains;
unsigned long dynamic_info[DYNAMIC_SIZE];
unsigned long n_phent;
- Elf32_Phdr * ppnt;
+ ElfW(Phdr) * ppnt;
ElfW(Addr) relro_addr;
size_t relro_size;
diff --git a/ldso/include/dl-string.h b/ldso/include/dl-string.h
index 9636c2764..8e35e6ad2 100644
--- a/ldso/include/dl-string.h
+++ b/ldso/include/dl-string.h
@@ -2,6 +2,7 @@
#define _LINUX_STRING_H_
#include <dl-sysdep.h> // for do_rem
+#include <features.h>
static size_t _dl_strlen(const char * str);
static char *_dl_strcat(char *dst, const char *src);
@@ -22,7 +23,7 @@ static char *_dl_simple_ltoahex(char * local, unsigned long i);
#define NULL ((void *) 0)
#endif
-static inline size_t __attribute__((__always_inline__)) _dl_strlen(const char * str)
+static __always_inline size_t _dl_strlen(const char * str)
{
register const char *ptr = (char *) str-1;
@@ -30,7 +31,7 @@ static inline size_t __attribute__((__always_inline__)) _dl_strlen(const char *
return (ptr - str);
}
-static inline char * __attribute__((__always_inline__)) _dl_strcat(char *dst, const char *src)
+static __always_inline char * _dl_strcat(char *dst, const char *src)
{
register char *ptr = dst-1;
@@ -43,7 +44,7 @@ static inline char * __attribute__((__always_inline__)) _dl_strcat(char *dst, co
return dst;
}
-static inline char * __attribute__((__always_inline__)) _dl_strcpy(char * dst,const char *src)
+static __always_inline char * _dl_strcpy(char * dst,const char *src)
{
register char *ptr = dst;
@@ -53,7 +54,7 @@ static inline char * __attribute__((__always_inline__)) _dl_strcpy(char * dst,co
return ptr;
}
-static inline int __attribute__((__always_inline__)) _dl_strcmp(const char * s1,const char * s2)
+static __always_inline int _dl_strcmp(const char * s1,const char * s2)
{
register unsigned char c1, c2;
s1--;s2--;
@@ -68,7 +69,7 @@ static inline int __attribute__((__always_inline__)) _dl_strcmp(const char * s1,
return c1 - c2;
}
-static inline int __attribute__((__always_inline__)) _dl_strncmp(const char * s1,const char * s2,size_t len)
+static __always_inline int _dl_strncmp(const char * s1,const char * s2,size_t len)
{
register unsigned char c1 = '\0';
register unsigned char c2 = '\0';
@@ -84,7 +85,7 @@ static inline int __attribute__((__always_inline__)) _dl_strncmp(const char * s1
return c1 - c2;
}
-static inline char * __attribute__((__always_inline__)) _dl_strchr(const char * str,int c)
+static __always_inline char * _dl_strchr(const char * str,int c)
{
register char ch;
str--;
@@ -145,7 +146,7 @@ static inline void * _dl_memcpy(void * dst, const void * src, size_t len)
return dst;
}
-static inline int __attribute__((__always_inline__)) _dl_memcmp(const void * s1,const void * s2,size_t len)
+static __always_inline int _dl_memcmp(const void * s1,const void * s2,size_t len)
{
unsigned char *c1 = (unsigned char *)s1-1;
unsigned char *c2 = (unsigned char *)s2-1;
@@ -160,7 +161,7 @@ static inline int __attribute__((__always_inline__)) _dl_memcmp(const void * s1,
#if defined(powerpc)
/* Will generate smaller and faster code due to loop unrolling.*/
-static inline void * __attribute__((__always_inline__)) _dl_memset(void *to, int c, size_t n)
+static __always_inline void * _dl_memset(void *to, int c, size_t n)
{
unsigned long chunks;
unsigned long *tmp_to;
@@ -185,7 +186,7 @@ static inline void * __attribute__((__always_inline__)) _dl_memset(void *to, int
return to;
}
#else
-static inline void * __attribute__((__always_inline__)) _dl_memset(void * str,int c,size_t len)
+static __always_inline void * _dl_memset(void * str,int c,size_t len)
{
register char *a = str;
@@ -196,7 +197,7 @@ static inline void * __attribute__((__always_inline__)) _dl_memset(void * str,in
}
#endif
-static inline char * __attribute__((__always_inline__)) _dl_get_last_path_component(char *path)
+static __always_inline char * _dl_get_last_path_component(char *path)
{
register char *ptr = path-1;
@@ -217,7 +218,7 @@ static inline char * __attribute__((__always_inline__)) _dl_get_last_path_compon
/* Early on, we can't call printf, so use this to print out
* numbers using the SEND_STDERR() macro. Avoid using mod
* or using long division */
-static inline char * __attribute__((__always_inline__)) _dl_simple_ltoa(char * local, unsigned long i)
+static __always_inline char * _dl_simple_ltoa(char * local, unsigned long i)
{
/* 20 digits plus a null terminator should be good for
* 64-bit or smaller ints (2^64 - 1)*/
@@ -232,7 +233,7 @@ static inline char * __attribute__((__always_inline__)) _dl_simple_ltoa(char * l
return p;
}
-static inline char * __attribute__((__always_inline__)) _dl_simple_ltoahex(char * local, unsigned long i)
+static __always_inline char * _dl_simple_ltoahex(char * local, unsigned long i)
{
/* 16 digits plus a leading "0x" plus a null terminator,
* should be good for 64-bit or smaller ints */
@@ -305,9 +306,10 @@ static inline char * __attribute__((__always_inline__)) _dl_simple_ltoahex(char
_dl_write(2, tmp2, tmp1 - tmp2 + sizeof(tmp) - 1); \
}
-#define SEND_NUMBER_STDERR(X, add_a_newline) \
+#define SEND_NUMBER_STDERR(NUM, add_a_newline) \
{ \
char tmp[26], v, *tmp2, *tmp1 = tmp; \
+ unsigned long X = (unsigned long)(NUM); \
CONSTANT_STRING_GOT_FIXUP(tmp1); \
tmp2 = tmp1 + sizeof(tmp); \
*--tmp2 = '\0'; \
@@ -323,9 +325,11 @@ static inline char * __attribute__((__always_inline__)) _dl_simple_ltoahex(char
#ifdef __SUPPORT_LD_DEBUG_EARLY__
# define SEND_STDERR_DEBUG(X) SEND_STDERR(X)
+# define SEND_NUMBER_STDERR_DEBUG(X, add_a_newline) SEND_NUMBER_STDERR(X, add_a_newline)
# define SEND_ADDRESS_STDERR_DEBUG(X, add_a_newline) SEND_ADDRESS_STDERR(X, add_a_newline)
#else
# define SEND_STDERR_DEBUG(X)
+# define SEND_NUMBER_STDERR_DEBUG(X, add_a_newline)
# define SEND_ADDRESS_STDERR_DEBUG(X, add_a_newline)
#endif
diff --git a/ldso/include/dl-syscall.h b/ldso/include/dl-syscall.h
index fbe852d18..1bcf95fb1 100644
--- a/ldso/include/dl-syscall.h
+++ b/ldso/include/dl-syscall.h
@@ -47,8 +47,8 @@
#ifndef _dl_MAX_ERRNO
#define _dl_MAX_ERRNO 4096
#endif
-#define _dl_mmap_check_error(__res) \
- (((int)__res) < 0 && ((int)__res) >= -_dl_MAX_ERRNO)
+#define _dl_mmap_check_error(__res) \
+ (((long)__res) < 0 && ((long)__res) >= -_dl_MAX_ERRNO)
#endif
@@ -104,7 +104,7 @@ static inline _syscall0(gid_t, _dl_getpid);
static inline _syscall3(int, _dl_readlink, const char *, path, char *, buf, size_t, bufsiz);
#ifdef __NR_mmap
-#if defined(__powerpc__) || defined(__mips__) || defined(__sh__) || defined(__sparc__)
+#if defined(__powerpc__) || defined(__mips__) || defined(__sh__) || defined(__sparc__) || defined(__x86_64__)
/* PowerPC, MIPS and SuperH have a different calling convention for mmap(). */
#define __NR__dl_mmap __NR_mmap
static inline _syscall6(void *, _dl_mmap, void *, start, size_t, length,
diff --git a/ldso/include/dlfcn.h b/ldso/include/dlfcn.h
index 484558d83..0bacc1a22 100644
--- a/ldso/include/dlfcn.h
+++ b/ldso/include/dlfcn.h
@@ -12,11 +12,10 @@
`dladdr'. */
typedef struct
{
- __const char *dli_fname; /* File name of defining object. */
- void *dli_fbase; /* Load address of that object. */
- __const char *dli_sname; /* Name of nearest symbol. */
- void *dli_saddr; /* Exact value of nearest symbol. */
+ __const char *dli_fname; /* File name of defining object. */
+ void *dli_fbase; /* Load address of that object. */
+ __const char *dli_sname; /* Name of nearest symbol. */
+ void *dli_saddr; /* Exact value of nearest symbol. */
} Dl_info;
-
-#endif /* dlfcn.h */
+#endif /* _DLFCN_H */
diff --git a/ldso/include/unsecvars.h b/ldso/include/unsecvars.h
index 4ed2c356c..0d996a91f 100644
--- a/ldso/include/unsecvars.h
+++ b/ldso/include/unsecvars.h
@@ -4,17 +4,17 @@
* '\0' explicitly.
*/
-#define UNSECURE_ENVVARS \
- "LD_AOUT_PRELOAD\0" \
- "LD_AOUT_LIBRARY_PATH\0" \
- "LD_PRELOAD\0" \
- "LD_LIBRARY_PATH\0" \
- "LD_DEBUG\0" \
- "LD_DEBUG_OUTPUT\0" \
- "LD_TRACE_LOADED_OBJECTS\0" \
- "HOSTALIASES\0" \
- "LOCALDOMAIN\0" \
- "RES_OPTIONS\0" \
+#define UNSECURE_ENVVARS \
+ "LD_AOUT_PRELOAD\0" \
+ "LD_AOUT_LIBRARY_PATH\0" \
+ "LD_PRELOAD\0" \
+ "LD_LIBRARY_PATH\0" \
+ "LD_DEBUG\0" \
+ "LD_DEBUG_OUTPUT\0" \
+ "LD_TRACE_LOADED_OBJECTS\0" \
+ "HOSTALIASES\0" \
+ "LOCALDOMAIN\0" \
+ "RES_OPTIONS\0" \
"TMPDIR\0"
/*
diff --git a/ldso/ldso/dl-elf.c b/ldso/ldso/dl-elf.c
index a3177fb59..15ba3b947 100644
--- a/ldso/ldso/dl-elf.c
+++ b/ldso/ldso/dl-elf.c
@@ -37,13 +37,6 @@
static caddr_t _dl_cache_addr = NULL;
static size_t _dl_cache_size = 0;
-/*
- * NPTL - This was taken from 'elf/dl-load.c' in glibc. We may
- * or may not need this for backtrace support. Define
- * it for NPTL compilation.
- */
-void *__libc_stack_end;
-
int _dl_map_cache(void)
{
int fd;
@@ -129,10 +122,7 @@ _dl_protect_relro (struct elf_resolve *l)
& ~(_dl_pagesize - 1));
ElfW(Addr) end = ((l->loadaddr + l->relro_addr + l->relro_size)
& ~(_dl_pagesize - 1));
-#if defined (__SUPPORT_LD_DEBUG__)
- if (_dl_debug)
- _dl_dprintf(2, "RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end);
-#endif
+ _dl_if_debug_dprint("RELRO protecting %s: start:%x, end:%x\n", l->libname, start, end);
if (start != end &&
_dl_mprotect ((void *) start, end - start, PROT_READ) < 0) {
_dl_dprintf(2, "%s: cannot apply additional memory protection after relocation", l->libname);
@@ -146,10 +136,10 @@ static struct elf_resolve *
search_for_named_library(const char *name, int secure, const char *path_list,
struct dyn_elf **rpnt)
{
- int i, count = 1;
char *path, *path_n;
char mylibname[2050];
- struct elf_resolve *tpnt1;
+ struct elf_resolve *tpnt;
+ int done = 0;
if (path_list==NULL)
return NULL;
@@ -161,29 +151,32 @@ search_for_named_library(const char *name, int secure, const char *path_list,
_dl_exit(0);
}
-
/* Unlike ldd.c, don't bother to eliminate double //s */
-
- /* Replace colons with zeros in path_list and count them */
- for(i=_dl_strlen(path); i > 0; i--) {
- if (path[i]==':') {
- path[i]=0;
- count++;
- }
- }
-
+ /* Replace colons with zeros in path_list */
+ /* : at the beginning or end of path maps to CWD */
+ /* :: anywhere maps CWD */
+ /* "" maps to CWD */
path_n = path;
- for (i = 0; i < count; i++) {
- _dl_strcpy(mylibname, path_n);
- _dl_strcat(mylibname, "/");
- _dl_strcat(mylibname, name);
- if ((tpnt1 = _dl_load_elf_shared_library(secure, rpnt, mylibname)) != NULL)
- {
- return tpnt1;
+ do {
+ if (*path == 0) {
+ *path = ':';
+ done = 1;
}
- path_n += (_dl_strlen(path_n) + 1);
- }
+ if (*path == ':') {
+ *path = 0;
+ if (*path_n)
+ _dl_strcpy(mylibname, path_n);
+ else
+ _dl_strcpy(mylibname, "."); /* Assume current dir if empty path */
+ _dl_strcat(mylibname, "/");
+ _dl_strcat(mylibname, name);
+ if ((tpnt = _dl_load_elf_shared_library(secure, rpnt, mylibname)) != NULL)
+ return tpnt;
+ path_n = path+1;
+ }
+ path++;
+ } while (!done);
return NULL;
}
@@ -199,10 +192,7 @@ struct elf_resolve *_dl_check_if_named_library_is_loaded(const char *full_libnam
pnt = libname = full_libname;
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file, "Checking if '%s' is already loaded\n", full_libname);
-#endif
+ _dl_if_debug_dprint("Checking if '%s' is already loaded\n", full_libname);
/* quick hack to ensure mylibname buffer doesn't overflow. don't
allow full_libname or any directory to be longer than 1024. */
if (_dl_strlen(full_libname) > 1024)
@@ -262,7 +252,7 @@ unsigned long _dl_internal_error_number;
struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
struct elf_resolve *tpnt, char *full_libname, int __attribute__((unused)) trace_loaded_objects)
{
- char *pnt, *pnt1;
+ char *pnt;
struct elf_resolve *tpnt1;
char *libname;
@@ -276,9 +266,9 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
/* Skip over any initial initial './' and '/' stuff to
* get the short form libname with no path garbage */
- pnt1 = _dl_strrchr(libname, '/');
- if (pnt1) {
- libname = pnt1 + 1;
+ pnt = _dl_strrchr(libname, '/');
+ if (pnt) {
+ libname = pnt + 1;
}
/* Critical step! Weed out duplicates early to avoid
@@ -289,17 +279,13 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
return tpnt1;
}
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tfind library='%s'; searching\n", libname);
-#endif
+ _dl_if_debug_dprint("\tfind library='%s'; searching\n", libname);
/* If the filename has any '/', try it straight and leave it at that.
For IBCS2 compatibility under linux, we substitute the string
/usr/i486-sysv4/lib for /usr/lib in library names. */
if (libname != full_libname) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\ttrying file='%s'\n", full_libname);
-#endif
+ _dl_if_debug_dprint("\ttrying file='%s'\n", full_libname);
tpnt1 = _dl_load_elf_shared_library(secure, rpnt, full_libname);
if (tpnt1) {
return tpnt1;
@@ -308,30 +294,22 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
}
/*
- * The ABI specifies that RPATH is searched before LD_*_PATH or
+ * The ABI specifies that RPATH is searched before LD_LIBRARY_PATH or
* the default path of /usr/lib. Check in rpath directories.
*/
- for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
- if (tpnt->libtype == elf_executable) {
- pnt = (char *) tpnt->dynamic_info[DT_RPATH];
- if (pnt) {
- pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching RPATH='%s'\n", pnt);
-#endif
- if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
- {
- return tpnt1;
- }
- }
- }
+#ifdef __LDSO_RUNPATH__
+ pnt = (tpnt ? (char *) tpnt->dynamic_info[DT_RPATH] : NULL);
+ if (pnt) {
+ pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
+ _dl_if_debug_dprint("\tsearching RPATH='%s'\n", pnt);
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
+ return tpnt1;
}
+#endif
/* Check in LD_{ELF_}LIBRARY_PATH, if specified and allowed */
if (_dl_library_path) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path);
-#endif
+ _dl_if_debug_dprint("\tsearching LD_LIBRARY_PATH='%s'\n", _dl_library_path);
if ((tpnt1 = search_for_named_library(libname, secure, _dl_library_path, rpnt)) != NULL)
{
return tpnt1;
@@ -339,6 +317,19 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
}
/*
+ * The ABI specifies that RUNPATH is searched after LD_LIBRARY_PATH.
+ */
+#ifdef __LDSO_RUNPATH__
+ pnt = (tpnt ? (char *)tpnt->dynamic_info[DT_RUNPATH] : NULL);
+ if (pnt) {
+ pnt += (unsigned long) tpnt->dynamic_info[DT_STRTAB];
+ _dl_if_debug_dprint("\tsearching RUNPATH='%s'\n", pnt);
+ if ((tpnt1 = search_for_named_library(libname, secure, pnt, rpnt)) != NULL)
+ return tpnt1;
+ }
+#endif
+
+ /*
* Where should the cache be searched? There is no such concept in the
* ABI, so we have some flexibility here. For now, search it before
* the hard coded paths that follow (i.e before /lib and /usr/lib).
@@ -350,9 +341,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
libentry_t *libent = (libentry_t *) & header[1];
char *strs = (char *) &libent[header->nlibs];
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching cache='%s'\n", LDSO_CACHE);
-#endif
+ _dl_if_debug_dprint("\tsearching cache='%s'\n", LDSO_CACHE);
for (i = 0; i < header->nlibs; i++) {
if ((libent[i].flags == LIB_ELF ||
libent[i].flags == LIB_ELF_LIBC0 ||
@@ -367,9 +356,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
/* Look for libraries wherever the shared library loader
* was installed */
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching ldso dir='%s'\n", _dl_ldsopath);
-#endif
+ _dl_if_debug_dprint("\tsearching ldso dir='%s'\n", _dl_ldsopath);
if ((tpnt1 = search_for_named_library(libname, secure, _dl_ldsopath, rpnt)) != NULL)
{
return tpnt1;
@@ -378,9 +365,7 @@ struct elf_resolve *_dl_load_shared_library(int secure, struct dyn_elf **rpnt,
/* Lastly, search the standard list of paths for the library.
This list must exactly match the list in uClibc/ldso/util/ldd.c */
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(_dl_debug_file, "\tsearching full lib path list\n");
-#endif
+ _dl_if_debug_dprint("\tsearching full lib path list\n");
if ((tpnt1 = search_for_named_library(libname, secure,
UCLIBC_RUNTIME_PREFIX "lib:"
UCLIBC_RUNTIME_PREFIX "usr/lib"
@@ -399,9 +384,7 @@ goof:
_dl_error_number = _dl_internal_error_number;
else
_dl_error_number = LD_ERROR_NOFILE;
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(2, "Bummer: could not find '%s'!\n", libname);
-#endif
+ _dl_if_debug_dprint("Bummer: could not find '%s'!\n", libname);
return NULL;
}
@@ -417,7 +400,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
{
ElfW(Ehdr) *epnt;
unsigned long dynamic_addr = 0;
- Elf32_Dyn *dpnt;
+ ElfW(Dyn) *dpnt;
struct elf_resolve *tpnt;
ElfW(Phdr) *ppnt;
char *status, *header;
@@ -442,9 +425,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
}
tpnt->usage_count++;
tpnt->libtype = elf_lib;
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) _dl_dprintf(2, "file='%s'; already loaded\n", libname);
-#endif
+ _dl_if_debug_dprint("file='%s'; already loaded\n", libname);
return tpnt;
}
@@ -657,7 +638,7 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
return NULL;
}
- dpnt = (Elf32_Dyn *) dynamic_addr;
+ dpnt = (ElfW(Dyn) *) dynamic_addr;
_dl_memset(dynamic_info, 0, sizeof(dynamic_info));
_dl_parse_dynamic_info(dpnt, dynamic_info, NULL, libaddr);
/* If the TEXTREL is set, this means that we need to make the pages
@@ -714,43 +695,34 @@ struct elf_resolve *_dl_load_elf_shared_library(int secure,
INIT_GOT(lpnt, tpnt);
};
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) {
- _dl_dprintf(2, "\n\tfile='%s'; generating link map\n", libname);
- _dl_dprintf(2, "\t\tdynamic: %x base: %x\n",
- dynamic_addr, libaddr);
- _dl_dprintf(2, "\t\t entry: %x phdr: %x phnum: %x\n\n",
- epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
+ _dl_if_debug_dprint("\n\tfile='%s'; generating link map\n", libname);
+ _dl_if_debug_dprint("\t\tdynamic: %x base: %x\n", dynamic_addr, libaddr);
+ _dl_if_debug_dprint("\t\t entry: %x phdr: %x phnum: %x\n\n",
+ epnt->e_entry + libaddr, tpnt->ppnt, tpnt->n_phent);
- }
-#endif
_dl_munmap(header, _dl_pagesize);
return tpnt;
}
+
/* now_flag must be RTLD_NOW or zero */
int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
{
int goof = 0;
struct elf_resolve *tpnt;
- Elf32_Word reloc_size, reloc_addr, relative_count;
+ ElfW(Word) reloc_size, relative_count;
+ ElfW(Addr) reloc_addr;
if (rpnt->next)
goof += _dl_fixup(rpnt->next, now_flag);
tpnt = rpnt->dyn;
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug && !(tpnt->init_flag & RELOCS_DONE))
- _dl_dprintf(_dl_debug_file,"\nrelocation processing: %s\n", tpnt->libname);
-#endif
+ if(!(tpnt->init_flag & RELOCS_DONE))
+ _dl_if_debug_dprint("relocation processing: %s\n", tpnt->libname);
if (unlikely(tpnt->dynamic_info[UNSUPPORTED_RELOC_TYPE])) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug) {
- _dl_dprintf(2, "%s: can't handle %s relocation records\n",
- _dl_progname, UNSUPPORTED_RELOC_STR);
- }
-#endif
+ _dl_if_debug_dprint("%s: can't handle %s relocation records\n",
+ _dl_progname, UNSUPPORTED_RELOC_STR);
goof++;
return goof;
}
@@ -768,7 +740,7 @@ int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
if (relative_count) { /* Optimize the XX_RELATIVE relocations if possible */
reloc_size -= relative_count * sizeof(ELF_RELOC);
- elf_machine_relative (tpnt->loadaddr, reloc_addr, relative_count);
+ elf_machine_relative(tpnt->loadaddr, reloc_addr, relative_count);
reloc_addr += relative_count * sizeof(ELF_RELOC);
}
goof += _dl_parse_relocation_information(rpnt,
@@ -798,7 +770,7 @@ int _dl_fixup(struct dyn_elf *rpnt, int now_flag)
/* Minimal printf which handles only %s, %d, and %x */
void _dl_dprintf(int fd, const char *fmt, ...)
{
- int num;
+ long num;
va_list args;
char *start, *ptr, *string;
static char *buf;
@@ -846,7 +818,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
case 'd':
{
char tmp[22];
- num = va_arg(args, int);
+ num = va_arg(args, long);
string = _dl_simple_ltoa(tmp, num);
_dl_write(fd, string, _dl_strlen(string));
@@ -856,7 +828,7 @@ void _dl_dprintf(int fd, const char *fmt, ...)
case 'X':
{
char tmp[22];
- num = va_arg(args, int);
+ num = va_arg(args, long);
string = _dl_simple_ltoahex(tmp, num);
_dl_write(fd, string, _dl_strlen(string));
@@ -888,7 +860,7 @@ char *_dl_strdup(const char *string)
return retval;
}
-void _dl_parse_dynamic_info(Elf32_Dyn *dpnt, unsigned long dynamic_info[], void *debug_addr, Elf32_Addr load_off)
+void _dl_parse_dynamic_info(ElfW(Dyn) *dpnt, unsigned long dynamic_info[], void *debug_addr, ElfW(Addr) load_off)
{
__dl_parse_dynamic_info(dpnt, dynamic_info, debug_addr, load_off);
}
diff --git a/ldso/ldso/dl-hash.c b/ldso/ldso/dl-hash.c
index 55026b4db..977934e8f 100644
--- a/ldso/ldso/dl-hash.c
+++ b/ldso/ldso/dl-hash.c
@@ -57,7 +57,7 @@ struct dyn_elf *_dl_handles = NULL;
/* This is the hash function that is used by the ELF linker to generate the
* hash table that each executable and library is required to have. We need
* it to decode the hash table. */
-static inline unsigned long _dl_elf_hash(const char *name)
+static inline Elf32_Word _dl_elf_hash(const char *name)
{
unsigned long hash=0;
unsigned long tmp;
@@ -101,7 +101,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
char *loadaddr, unsigned long *dynamic_info, unsigned long dynamic_addr,
unsigned long dynamic_size)
{
- unsigned long *hash_addr;
+ Elf32_Word *hash_addr;
struct elf_resolve *tpnt;
int i;
@@ -125,7 +125,7 @@ struct elf_resolve *_dl_add_elf_hash_table(const char *libname,
tpnt->libtype = loaded_file;
if (dynamic_info[DT_HASH] != 0) {
- hash_addr = (unsigned long *) (intptr_t)(dynamic_info[DT_HASH]);
+ hash_addr = (Elf32_Word*)dynamic_info[DT_HASH];
tpnt->nbucket = *hash_addr++;
tpnt->nchain = *hash_addr++;
tpnt->elf_buckets = hash_addr;
@@ -148,13 +148,13 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
struct elf_resolve *tpnt;
int si;
char *strtab;
- Elf32_Sym *symtab;
+ ElfW(Sym) *symtab;
unsigned long elf_hash_number, hn;
const ElfW(Sym) *sym;
char *weak_result = NULL;
elf_hash_number = _dl_elf_hash(name);
-
+
for (; rpnt; rpnt = rpnt->next) {
tpnt = rpnt->dyn;
@@ -178,7 +178,7 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
/* Avoid calling .urem here. */
do_rem(hn, elf_hash_number, tpnt->nbucket);
- symtab = (Elf32_Sym *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
+ symtab = (ElfW(Sym) *) (intptr_t) (tpnt->dynamic_info[DT_SYMTAB]);
strtab = (char *) (tpnt->dynamic_info[DT_STRTAB]);
for (si = tpnt->elf_buckets[hn]; si != STN_UNDEF; si = tpnt->chains[si]) {
@@ -190,10 +190,10 @@ char *_dl_find_hash(const char *name, struct dyn_elf *rpnt, struct elf_resolve *
continue;
if (sym->st_value == 0)
continue;
- if (ELF32_ST_TYPE(sym->st_info) > STT_FUNC)
+ if (ELF_ST_TYPE(sym->st_info) > STT_FUNC)
continue;
- switch (ELF32_ST_BIND(sym->st_info)) {
+ switch (ELF_ST_BIND(sym->st_info)) {
case STB_WEAK:
#if 0
/* Perhaps we should support old style weak symbol handling
diff --git a/ldso/ldso/dl-startup.c b/ldso/ldso/dl-startup.c
index 31529cd18..3c6ce48f5 100644
--- a/ldso/ldso/dl-startup.c
+++ b/ldso/ldso/dl-startup.c
@@ -97,31 +97,31 @@
/* Static declarations */
int (*_dl_elf_main) (int, char **, char **);
-
-
+static void* __rtld_stack_end; /* Points to argc on stack, e.g *((long *)__rtld_stackend) == argc */
+strong_alias(__rtld_stack_end, __libc_stack_end); /* Exported version of __rtld_stack_end */
/* When we enter this piece of code, the program stack looks like this:
- argc argument counter (integer)
- argv[0] program name (pointer)
- argv[1...N] program args (pointers)
- argv[argc-1] end of args (integer)
- NULL
- env[0...N] environment variables (pointers)
- NULL
- auxvt[0...N] Auxiliary Vector Table elements (mixed types)
+ argc argument counter (integer)
+ argv[0] program name (pointer)
+ argv[1...N] program args (pointers)
+ argv[argc-1] end of args (integer)
+ NULL
+ env[0...N] environment variables (pointers)
+ NULL
+ auxvt[0...N] Auxiliary Vector Table elements (mixed types)
*/
static void * __attribute_used__ _dl_start(unsigned long args)
{
unsigned int argc;
char **argv, **envp;
unsigned long load_addr;
- Elf32_Addr got;
+ ElfW(Addr) got;
unsigned long *aux_dat;
ElfW(Ehdr) *header;
struct elf_resolve tpnt_tmp;
struct elf_resolve *tpnt = &tpnt_tmp;
- Elf32_auxv_t auxvt[AT_EGID + 1];
- Elf32_Dyn *dpnt;
+ ElfW(auxv_t) auxvt[AT_EGID + 1];
+ ElfW(Dyn) *dpnt;
/* WARNING! -- we cannot make _any_ funtion calls until we have
* taken care of fixing up our own relocations. Making static
@@ -136,18 +136,16 @@ static void * __attribute_used__ _dl_start(unsigned long args)
aux_dat += argc; /* Skip over the argv pointers */
aux_dat++; /* Skip over NULL at end of argv */
envp = (char **) aux_dat;
+ SEND_STDERR_DEBUG("argc=");
+ SEND_NUMBER_STDERR_DEBUG(argc, 0);
+ SEND_STDERR_DEBUG(" argv=");
+ SEND_ADDRESS_STDERR_DEBUG(argv, 0);
+ SEND_STDERR_DEBUG(" envp=");
+ SEND_ADDRESS_STDERR_DEBUG(envp, 1);
while (*aux_dat)
aux_dat++; /* Skip over the envp pointers */
aux_dat++; /* Skip over NULL at end of envp */
- /*
- * NPTL - This was taken from 'sysdeps/generic/libc-start.c'
- * and is associated with backtrace capability. It
- * It may be removed later, but right now NPTL needs
- * NPTL needs this to compile.
- */
- __libc_stack_end = (void *) argv;
-
/* Place -1 here as a checkpoint. We later check if it was changed
* when we read in the auxvt */
auxvt[AT_UID].a_type = -1;
@@ -156,10 +154,10 @@ static void * __attribute_used__ _dl_start(unsigned long args)
* the Auxiliary Vector Table. Read out the elements of the auxvt,
* sort and store them in auxvt for later use. */
while (*aux_dat) {
- Elf32_auxv_t *auxv_entry = (Elf32_auxv_t *) aux_dat;
+ ElfW(auxv_t) *auxv_entry = (ElfW(auxv_t) *) aux_dat;
if (auxv_entry->a_type <= AT_EGID) {
- _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(Elf32_auxv_t));
+ _dl_memcpy(&(auxvt[auxv_entry->a_type]), auxv_entry, sizeof(ElfW(auxv_t)));
}
aux_dat += 2;
}
@@ -169,10 +167,10 @@ static void * __attribute_used__ _dl_start(unsigned long args)
if (!auxvt[AT_BASE].a_un.a_val)
auxvt[AT_BASE].a_un.a_val = elf_machine_load_address();
load_addr = auxvt[AT_BASE].a_un.a_val;
- header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+ header = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
/* Check the ELF header to make sure everything looks ok. */
- if (!header || header->e_ident[EI_CLASS] != ELFCLASS32 ||
+ if (!header || header->e_ident[EI_CLASS] != ELF_CLASS ||
header->e_ident[EI_VERSION] != EV_CURRENT
/* Do not use an inline _dl_strncmp here or some arches
* will blow chunks, i.e. those that need to relocate all
@@ -185,56 +183,43 @@ static void * __attribute_used__ _dl_start(unsigned long args)
SEND_STDERR("Invalid ELF header\n");
_dl_exit(0);
}
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("ELF header=");
- SEND_ADDRESS_STDERR(load_addr, 1);
-#endif
-
+ SEND_STDERR_DEBUG("ELF header=");
+ SEND_ADDRESS_STDERR_DEBUG(load_addr, 1);
/* Locate the global offset table. Since this code must be PIC
* we can take advantage of the magic offset register, if we
* happen to know what that is for this architecture. If not,
* we can always read stuff out of the ELF file to find it... */
got = elf_machine_dynamic();
- dpnt = (Elf32_Dyn *) (got + load_addr);
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("First Dynamic section entry=");
- SEND_ADDRESS_STDERR(dpnt, 1);
-#endif
+ dpnt = (ElfW(Dyn) *) (got + load_addr);
+ SEND_STDERR_DEBUG("First Dynamic section entry=");
+ SEND_ADDRESS_STDERR_DEBUG(dpnt, 1);
_dl_memset(tpnt, 0, sizeof(struct elf_resolve));
tpnt->loadaddr = load_addr;
/* OK, that was easy. Next scan the DYNAMIC section of the image.
We are only doing ourself right now - we will have to do the rest later */
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("scanning DYNAMIC section\n");
-#endif
+ SEND_STDERR_DEBUG("Scanning DYNAMIC section\n");
tpnt->dynamic_addr = dpnt;
-#if defined(__mips__) || defined(__cris__)
+#if defined(NO_FUNCS_BEFORE_BOOTSTRAP)
/* Some architectures cannot call functions here, must inline */
__dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL, load_addr);
#else
_dl_parse_dynamic_info(dpnt, tpnt->dynamic_info, NULL, load_addr);
#endif
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("done scanning DYNAMIC section\n");
-#endif
+ SEND_STDERR_DEBUG("Done scanning DYNAMIC section\n");
-#if defined(__mips__)
+#if defined(PERFORM_BOOTSTRAP_GOT)
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("About to do specific GOT bootstrap\n");
-#endif
- /* For MIPS we have to do stuff to the GOT before we do relocations. */
+ SEND_STDERR_DEBUG("About to do specific GOT bootstrap\n");
+ /* some arches (like MIPS) we have to tweak the GOT before relocations */
PERFORM_BOOTSTRAP_GOT(tpnt);
#else
/* OK, now do the relocations. We do not do a lazy binding here, so
that once we are done, we have considerably more flexibility. */
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("About to do library loader relocations\n");
-#endif
+ SEND_STDERR_DEBUG("About to do library loader relocations\n");
{
int goof, indx;
@@ -249,50 +234,49 @@ static void * __attribute_used__ _dl_start(unsigned long args)
unsigned long *reloc_addr;
unsigned long symbol_addr;
int symtab_index;
- Elf32_Sym *sym;
+ ElfW(Sym) *sym;
ELF_RELOC *rpnt;
unsigned long rel_addr, rel_size;
- Elf32_Word relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
+ ElfW(Word) relative_count = tpnt->dynamic_info[DT_RELCONT_IDX];
- rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] : tpnt->
- dynamic_info[DT_RELOC_TABLE_ADDR]);
- rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] : tpnt->
- dynamic_info[DT_RELOC_TABLE_SIZE]);
+ rel_addr = (indx ? tpnt->dynamic_info[DT_JMPREL] :
+ tpnt->dynamic_info[DT_RELOC_TABLE_ADDR]);
+ rel_size = (indx ? tpnt->dynamic_info[DT_PLTRELSZ] :
+ tpnt->dynamic_info[DT_RELOC_TABLE_SIZE]);
if (!rel_addr)
continue;
/* Now parse the relocation information */
/* Since ldso is linked with -Bsymbolic, all relocs will be RELATIVE(for those archs that have
- RELATIVE relocs) which means that the for(..) loop below has noting to do and can be deleted.
+ RELATIVE relocs) which means that the for(..) loop below has nothing to do and can be deleted.
Possibly one should add a HAVE_RELATIVE_RELOCS directive and #ifdef away some code. */
if (!indx && relative_count) {
rel_size -= relative_count * sizeof(ELF_RELOC);
- elf_machine_relative (load_addr, rel_addr, relative_count);
+ elf_machine_relative(load_addr, rel_addr, relative_count);
rel_addr += relative_count * sizeof(ELF_RELOC);;
}
rpnt = (ELF_RELOC *) (rel_addr + load_addr);
for (i = 0; i < rel_size; i += sizeof(ELF_RELOC), rpnt++) {
reloc_addr = (unsigned long *) (load_addr + (unsigned long) rpnt->r_offset);
- symtab_index = ELF32_R_SYM(rpnt->r_info);
+ symtab_index = ELF_R_SYM(rpnt->r_info);
symbol_addr = 0;
sym = NULL;
if (symtab_index) {
char *strtab;
- Elf32_Sym *symtab;
+ ElfW(Sym) *symtab;
- symtab = (Elf32_Sym *) tpnt->dynamic_info[DT_SYMTAB];
+ symtab = (ElfW(Sym) *) tpnt->dynamic_info[DT_SYMTAB];
strtab = (char *) tpnt->dynamic_info[DT_STRTAB];
sym = &symtab[symtab_index];
symbol_addr = load_addr + sym->st_value;
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("relocating symbol: ");
- SEND_STDERR(strtab + sym->st_name);
- SEND_STDERR("\n");
-#endif
- }
+ SEND_STDERR_DEBUG("relocating symbol: ");
+ SEND_STDERR_DEBUG(strtab + sym->st_name);
+ SEND_STDERR_DEBUG("\n");
+ } else
+ SEND_STDERR_DEBUG("relocating unknown symbol\n");
/* Use this machine-specific macro to perform the actual relocation. */
PERFORM_BOOTSTRAP_RELOC(rpnt, reloc_addr, symbol_addr, load_addr, sym);
}
@@ -304,24 +288,22 @@ static void * __attribute_used__ _dl_start(unsigned long args)
}
#endif
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
/* Wahoo!!! */
- SEND_STDERR("Done relocating library loader, so we can now\n"
- "\tuse globals and make function calls!\n");
-#endif
+ SEND_STDERR_DEBUG("Done relocating ldso; we can now use globals and make function calls!\n");
/* Now we have done the mandatory linking of some things. We are now
free to start using global variables, since these things have all been
- fixed up by now. Still no function calls outside of this library ,
+ fixed up by now. Still no function calls outside of this library,
since the dynamic resolver is not yet ready. */
+
+ __rtld_stack_end = (void *)(argv - 1);
+
_dl_get_ready_to_run(tpnt, load_addr, auxvt, envp, argv);
/* Transfer control to the application. */
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- SEND_STDERR("transfering control to application\n");
-#endif
- _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_fcn;
+ SEND_STDERR_DEBUG("transfering control to application @ ");
+ _dl_elf_main = (int (*)(int, char **, char **)) auxvt[AT_ENTRY].a_un.a_val;
+ SEND_ADDRESS_STDERR_DEBUG(_dl_elf_main, 1);
START();
}
-
diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
index 54da613aa..709d58d25 100644
--- a/ldso/ldso/ldso.c
+++ b/ldso/ldso/ldso.c
@@ -33,6 +33,9 @@
#include "ldso.h"
#include "unsecvars.h"
+/* Pull in common debug code */
+#include "dl-debug.c"
+
#define ALLOW_ZERO_PLTGOT
/* Pull in the value of _dl_progname */
@@ -97,23 +100,18 @@ static void __attribute__ ((destructor)) __attribute_used__ _dl_fini(void)
void (*dl_elf_func) (void);
dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file,
- "\ncalling FINI: %s\n\n",
- tpnt->libname);
-#endif
+ _dl_if_debug_dprint("\ncalling FINI: %s\n\n", tpnt->libname);
(*dl_elf_func) ();
}
}
}
void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
- Elf32_auxv_t auxvt[AT_EGID + 1], char **envp,
+ ElfW(auxv_t) auxvt[AT_EGID + 1], char **envp,
char **argv)
{
ElfW(Phdr) *ppnt;
- Elf32_Dyn *dpnt;
+ ElfW(Dyn) *dpnt;
char *lpntstr;
int i, goof = 0, unlazy = 0, trace_loaded_objects = 0;
struct dyn_elf *rpnt;
@@ -127,7 +125,6 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
ElfW(Addr) relro_addr = 0;
size_t relro_size = 0;
-
/* Wahoo!!! We managed to make a function call! Get malloc
* setup so we can use _dl_dprintf() to print debug noise
* instead of the SEND_STDERR macros used in dl-startup.c */
@@ -142,10 +139,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
_dl_malloc_addr = (unsigned char *)_dl_pagesize;
_dl_mmap_zero = 0;
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
/* Wahoo!!! */
- _dl_dprintf(2, "\nCool, ldso survived making function calls.\n");
-#endif
+ _dl_debug_early("Cool, ldso survived making function calls\n");
/* Now we have done the mandatory linking of some things. We are now
* free to start using global variables, since these things have all
@@ -156,8 +151,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
_dl_progname = argv[0];
}
- if (_start == (void *) auxvt[AT_ENTRY].a_un.a_fcn) {
- _dl_dprintf(2, "Standalone execution is not supported yet\n");
+ if (_start == (void *) auxvt[AT_ENTRY].a_un.a_val) {
+ _dl_dprintf(_dl_debug_file, "Standalone execution is not supported yet\n");
_dl_exit(1);
}
@@ -213,7 +208,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
*/
{
int i;
- ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+ ElfW(Phdr) *ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++)
if (ppnt->p_type == PT_PHDR) {
@@ -221,12 +216,9 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
break;
}
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- if (app_tpnt->loadaddr) {
- _dl_dprintf(2, "Position Independent Executable: "
+ if (app_tpnt->loadaddr)
+ _dl_debug_early("Position Independent Executable: "
"app_tpnt->loadaddr=%x\n", app_tpnt->loadaddr);
- }
-#endif
}
/*
@@ -236,14 +228,14 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
debug_addr = _dl_malloc(sizeof(struct r_debug));
_dl_memset(debug_addr, 0, sizeof(struct r_debug));
- ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+ ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
if (ppnt->p_type == PT_GNU_RELRO) {
relro_addr = ppnt->p_vaddr;
relro_size = ppnt->p_memsz;
}
if (ppnt->p_type == PT_DYNAMIC) {
- dpnt = (Elf32_Dyn *) (ppnt->p_vaddr + app_tpnt->loadaddr);
+ dpnt = (ElfW(Dyn) *) (ppnt->p_vaddr + app_tpnt->loadaddr);
_dl_parse_dynamic_info(dpnt, app_tpnt->dynamic_info, debug_addr, app_tpnt->loadaddr);
#ifndef __FORCE_SHAREABLE_TEXT_SEGMENTS__
/* Ugly, ugly. We need to call mprotect to change the
@@ -251,12 +243,10 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
* dynamic linking. We can set the protection back
* again once we are done.
*/
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "calling mprotect on the application program\n");
-#endif
+ _dl_debug_early("calling mprotect on the application program\n");
/* Now cover the application program. */
if (app_tpnt->dynamic_info[DT_TEXTREL]) {
- ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+ ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
for (i = 0; i < auxvt[AT_PHNUM].a_un.a_val; i++, ppnt++) {
if (ppnt->p_type == PT_LOAD && !(ppnt->p_flags & PF_W))
_dl_mprotect((void *) ((ppnt->p_vaddr + app_tpnt->loadaddr) & PAGE_ALIGN),
@@ -276,7 +266,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
app_tpnt = _dl_add_elf_hash_table(_dl_progname, (char *)app_tpnt->loadaddr,
app_tpnt->dynamic_info, ppnt->p_vaddr + app_tpnt->loadaddr, ppnt->p_filesz);
_dl_loaded_modules->libtype = elf_executable;
- _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_ptr;
+ _dl_loaded_modules->ppnt = (ElfW(Phdr) *) auxvt[AT_PHDR].a_un.a_val;
_dl_loaded_modules->n_phent = auxvt[AT_PHNUM].a_un.a_val;
_dl_symbol_tables = rpnt = (struct dyn_elf *) _dl_malloc(sizeof(struct dyn_elf));
_dl_memset(rpnt, 0, sizeof(struct dyn_elf));
@@ -305,10 +295,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
if (ptmp != _dl_ldsopath)
*ptmp = '\0';
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "Lib Loader:\t(%x) %s\n",
- tpnt->loadaddr, tpnt->libname);
-#endif
+ _dl_debug_early("Lib Loader: (%x) %s\n", tpnt->loadaddr, tpnt->libname);
}
}
app_tpnt->relro_addr = relro_addr;
@@ -355,7 +342,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
_dl_debug_file= _dl_open(filename, O_WRONLY|O_CREAT, 0644);
if (_dl_debug_file < 0) {
_dl_debug_file = 2;
- _dl_dprintf (2, "can't open file: '%s'\n",filename);
+ _dl_dprintf(_dl_debug_file, "can't open file: '%s'\n",filename);
}
}
}
@@ -411,12 +398,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
*str2 = '\0';
if (!_dl_secure || _dl_strchr(str, '/') == NULL) {
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file,
- "\tfile='%s'; needed by '%s'\n",
- str, _dl_progname);
-#endif
+ _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", str, _dl_progname);
tpnt1 = _dl_load_shared_library(_dl_secure, &rpnt, NULL, str, trace_loaded_objects);
if (!tpnt1) {
@@ -426,16 +408,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
else
#endif
{
- _dl_dprintf(2, "%s: can't load " "library '%s'\n", _dl_progname, str);
+ _dl_dprintf(_dl_debug_file, "%s: can't load " "library '%s'\n", _dl_progname, str);
_dl_exit(15);
}
} else {
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2,
- "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
-#endif
+ _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#ifdef __LDSO_LDD_SUPPORT__
if (trace_loaded_objects &&
@@ -447,7 +426,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
*/
if (_dl_strcmp(_dl_progname, str) != 0)
_dl_dprintf(1, "\t%s => %s (%x)\n", str, tpnt1->libname,
- (unsigned)tpnt1->loadaddr);
+ tpnt1->loadaddr);
}
#endif
}
@@ -472,7 +451,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
}
if ((fd = _dl_open(LDSO_PRELOAD, O_RDONLY, 0)) < 0) {
- _dl_dprintf(2, "%s: can't open file '%s'\n",
+ _dl_dprintf(_dl_debug_file, "%s: can't open file '%s'\n",
_dl_progname, LDSO_PRELOAD);
break;
}
@@ -481,7 +460,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
_dl_close(fd);
if (preload == (caddr_t) -1) {
- _dl_dprintf(2, "%s: can't map file '%s'\n",
+ _dl_dprintf(_dl_debug_file, "%s: can't map file '%s'\n",
_dl_progname, LDSO_PRELOAD);
break;
}
@@ -509,12 +488,8 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
/*nada */ ;
c = *cp;
*cp = '\0';
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file,
- "\tfile='%s'; needed by '%s'\n",
- cp2, _dl_progname);
-#endif
+
+ _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", cp2, _dl_progname);
tpnt1 = _dl_load_shared_library(0, &rpnt, NULL, cp2, trace_loaded_objects);
if (!tpnt1) {
@@ -524,15 +499,13 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
else
#endif
{
- _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, cp2);
+ _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, cp2);
_dl_exit(15);
}
} else {
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
-#endif
+ _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#ifdef __LDSO_LDD_SUPPORT__
if (trace_loaded_objects &&
@@ -556,23 +529,20 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
nlist = 0;
for (tcurr = _dl_loaded_modules; tcurr; tcurr = tcurr->next) {
- Elf32_Dyn *dpnt;
+ ElfW(Dyn) *dpnt;
nlist++;
- for (dpnt = (Elf32_Dyn *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
+ for (dpnt = (ElfW(Dyn) *) tcurr->dynamic_addr; dpnt->d_tag; dpnt++) {
if (dpnt->d_tag == DT_NEEDED) {
char *name;
struct init_fini_list *tmp;
lpntstr = (char*) (tcurr->dynamic_info[DT_STRTAB] + dpnt->d_un.d_val);
name = _dl_get_last_path_component(lpntstr);
+ if (_dl_strcmp(name, "ld-uClibc.so.0") == 0)
+ continue;
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file,
- "\tfile='%s'; needed by '%s'\n",
- lpntstr, _dl_progname);
-#endif
+ _dl_if_debug_dprint("\tfile='%s'; needed by '%s'\n", lpntstr, _dl_progname);
if (!(tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, trace_loaded_objects))) {
#ifdef __LDSO_LDD_SUPPORT__
@@ -582,7 +552,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
} else
#endif
{
- _dl_dprintf(2, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
+ _dl_dprintf(_dl_debug_file, "%s: can't load library '%s'\n", _dl_progname, lpntstr);
_dl_exit(16);
}
}
@@ -594,9 +564,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
tpnt1->rtld_flags = unlazy | RTLD_GLOBAL;
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "Loading:\t(%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
-#endif
+ _dl_debug_early("Loading: (%x) %s\n", tpnt1->loadaddr, tpnt1->libname);
#ifdef __LDSO_LDD_SUPPORT__
if (trace_loaded_objects &&
@@ -630,10 +598,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
for (; runp; runp = runp->next) {
if (runp->tpnt == tcurr) {
struct elf_resolve *here = init_fini_list[k];
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- _dl_dprintf(2, "Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
-#endif
+ _dl_if_debug_dprint("Move %s from pos %d to %d in INIT/FINI list\n", here->libname, k, j);
for (i = (k - j); i; --i)
init_fini_list[i+j] = init_fini_list[i+j-1];
init_fini_list[j] = here;
@@ -645,16 +610,16 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
}
#ifdef __SUPPORT_LD_DEBUG__
if(_dl_debug) {
- _dl_dprintf(2, "\nINIT/FINI order and dependencies:\n");
+ _dl_dprintf(_dl_debug_file, "\nINIT/FINI order and dependencies:\n");
for (i = 0; i < nlist; i++) {
struct init_fini_list *tmp;
- _dl_dprintf(2, "lib: %s has deps:\n",
+ _dl_dprintf(_dl_debug_file, "lib: %s has deps:\n",
init_fini_list[i]->libname);
tmp = init_fini_list[i]->init_fini;
for (; tmp; tmp = tmp->next)
- _dl_dprintf(2, " %s ", tmp->tpnt->libname);
- _dl_dprintf(2, "\n");
+ _dl_dprintf(_dl_debug_file, " %s ", tmp->tpnt->libname);
+ _dl_dprintf(_dl_debug_file, "\n");
}
}
#endif
@@ -666,7 +631,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
* again once all libs are loaded.
*/
if (tpnt) {
- ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_ptr;
+ ElfW(Ehdr) *epnt = (ElfW(Ehdr) *) auxvt[AT_BASE].a_un.a_val;
ElfW(Phdr) *myppnt = (ElfW(Phdr) *) (load_addr + epnt->e_phoff);
int j;
@@ -722,9 +687,7 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
}
#endif
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "Beginning relocation fixups\n");
-#endif
+ _dl_debug_early("Beginning relocation fixups\n");
#ifdef __mips__
/*
@@ -796,17 +759,12 @@ void _dl_get_ready_to_run(struct elf_resolve *tpnt, unsigned long load_addr,
dl_elf_func = (void (*)(void)) (intptr_t) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
-#if defined (__SUPPORT_LD_DEBUG__)
- if(_dl_debug)
- _dl_dprintf(_dl_debug_file,
- "\ncalling INIT: %s\n\n",
- tpnt->libname);
-#endif
+ _dl_if_debug_dprint("calling INIT: %s\n\n", tpnt->libname);
(*dl_elf_func) ();
}
}
-#ifndef _DL_DO_FINI_IN_LIBC
+#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",
@@ -880,22 +838,18 @@ void *_dl_malloc(int size)
void *retval;
#if 0
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "malloc: request for %d bytes\n", size);
-#endif
+ _dl_debug_early("request for %d bytes\n", size);
#endif
if (_dl_malloc_function)
return (*_dl_malloc_function) (size);
if (_dl_malloc_addr - _dl_mmap_zero + (unsigned)size > _dl_pagesize) {
-#ifdef __SUPPORT_LD_DEBUG_EARLY__
- _dl_dprintf(2, "malloc: mmapping more memory\n");
-#endif
+ _dl_debug_early("mmapping more memory\n");
_dl_mmap_zero = _dl_malloc_addr = _dl_mmap((void *) 0, size,
PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
if (_dl_mmap_check_error(_dl_mmap_zero)) {
- _dl_dprintf(2, "%s: mmap of a spare page failed!\n", _dl_progname);
+ _dl_dprintf(_dl_debug_file, "%s: mmap of a spare page failed!\n", _dl_progname);
_dl_exit(20);
}
}
diff --git a/ldso/ldso/mips/dl-startup.h b/ldso/ldso/mips/dl-startup.h
index f369f77f1..df2f25a14 100644
--- a/ldso/ldso/mips/dl-startup.h
+++ b/ldso/ldso/mips/dl-startup.h
@@ -2,40 +2,64 @@
* will work as expected and cope with whatever platform specific wierdness is
* needed for this architecture.
* Copyright (C) 2005 by Joakim Tjernlund
+ * Copyright (C) 2005 by Erik Andersen
*/
+
asm(""
" .text\n"
" .globl _start\n"
+ " .ent _start\n"
" .type _start,@function\n"
"_start:\n"
" .set noreorder\n"
- " bltzal $0, 0f\n"
- " nop\n"
- "0: .cpload $31\n"
- " .set reorder\n"
- " la $4, _DYNAMIC\n"
- " sw $4, -0x7ff0($28)\n"
- " move $4, $29\n"
- " la $8, coff\n"
- " .set noreorder\n"
- " bltzal $0, coff\n"
+ " move $25, $31\n"
+ " bal 0f\n"
" nop\n"
- "coff: subu $8, $31, $8\n"
+ "0:\n"
+ " .cpload $31\n"
+ " move $31, $25\n"
" .set reorder\n"
- " la $25, _dl_start\n"
- " addu $25, $8\n"
- " jalr $25\n"
- " move $17, $2\n"
- " lw $4, 0($29)\n"
- " la $5, 4($29)\n"
- " sll $6, $4, 2\n"
- " addu $6, $6, $5\n"
- " addu $6, $6, 4\n"
- " move $25, $17\n"
- " jr $25\n"
- " .size _start,.-_start\n"
- " .previous\n"
+ " la $4, _DYNAMIC\n"
+ " sw $4, -0x7ff0($28)\n"
+ " move $4, $29\n"
+ " subu $29, 16\n"
+ " la $8, .coff\n"
+ " bltzal $8, .coff\n"
+ ".coff:\n"
+ " subu $8, $31, $8\n"
+ " la $25, _dl_start\n"
+ " addu $25, $8\n"
+ " jalr $25\n"
+ " addiu $29, 16\n"
+ " move $16, $28\n"
+ " move $17, $2\n"
+ " lw $2, _dl_skip_args\n"
+ " beq $2, $0, 1f\n"
+ " lw $4, 0($29)\n"
+ " subu $4, $2\n"
+ " sll $2, 2\n"
+ " addu $29, $2\n"
+ " sw $4, 0($29)\n"
+ "1:\n"
+ " lw $5, 0($29)\n"
+ " la $6, 4 ($29)\n"
+ " sll $7, $5, 2\n"
+ " addu $7, $7, $6\n"
+ " addu $7, $7, 4\n"
+ " and $2, $29, -2 * 4\n"
+ " sw $29, -4($2)\n"
+ " subu $29, $2, 32\n"
+ " .cprestore 16\n"
+ " lw $29, 28($29)\n"
+ " la $2, _dl_fini\n"
+ " move $25, $17\n"
+ " jr $25\n"
+ ".end _start\n"
+ ".size _start, . -_start\n"
+ "\n\n"
+ "\n\n"
+ ".previous\n"
);
/*
@@ -46,6 +70,10 @@ asm(""
#define GET_ARGV(ARGVP, ARGS) ARGVP = (((unsigned long *) ARGS)+1)
+/* We can't call functions earlier in the dl startup process */
+#define NO_FUNCS_BEFORE_BOOTSTRAP
+
+
/*
* Here is a macro to perform the GOT relocation. This is only
* used when bootstrapping the dynamic loader.
diff --git a/ldso/ldso/mips/elfinterp.c b/ldso/ldso/mips/elfinterp.c
index 595653000..18b5799d9 100644
--- a/ldso/ldso/mips/elfinterp.c
+++ b/ldso/ldso/mips/elfinterp.c
@@ -27,82 +27,6 @@
* SUCH DAMAGE.
*/
-#if defined (__SUPPORT_LD_DEBUG__)
-static const char *_dl_reltypes_tab[] =
-{
- [0] "R_MIPS_NONE", "R_MIPS_16", "R_MIPS_32",
- [3] "R_MIPS_REL32", "R_MIPS_26", "R_MIPS_HI16",
- [6] "R_MIPS_LO16", "R_MIPS_GPREL16", "R_MIPS_LITERAL",
- [9] "R_MIPS_GOT16", "R_MIPS_PC16", "R_MIPS_CALL16",
- [12] "R_MIPS_GPREL32",
- [16] "R_MIPS_SHIFT5", "R_MIPS_SHIFT6", "R_MIPS_64",
- [19] "R_MIPS_GOT_DISP", "R_MIPS_GOT_PAGE", "R_MIPS_GOT_OFST",
- [22] "R_MIPS_GOT_HI16", "R_MIPS_GOT_LO16", "R_MIPS_SUB",
- [25] "R_MIPS_INSERT_A", "R_MIPS_INSERT_B", "R_MIPS_DELETE",
- [28] "R_MIPS_HIGHER", "R_MIPS_HIGHEST", "R_MIPS_CALL_HI16",
- [31] "R_MIPS_CALL_LO16", "R_MIPS_SCN_DISP", "R_MIPS_REL16",
- [34] "R_MIPS_ADD_IMMEDIATE", "R_MIPS_PJUMP", "R_MIPS_RELGOT",
- [37] "R_MIPS_JALR",
-};
-
-static const char *
-_dl_reltypes(int type)
-{
- static char buf[22];
- const char *str;
-
- if (type >= (int)(sizeof (_dl_reltypes_tab)/sizeof(_dl_reltypes_tab[0])) ||
- NULL == (str = _dl_reltypes_tab[type]))
- {
- str =_dl_simple_ltoa( buf, (unsigned long)(type));
- }
- return str;
-}
-
-static
-void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index)
-{
- if(_dl_debug_symbols)
- {
- if(symtab_index){
- _dl_dprintf(_dl_debug_file, "\n%s\n\tvalue=%x\tsize=%x\tinfo=%x\tother=%x\tshndx=%x",
- strtab + symtab[symtab_index].st_name,
- symtab[symtab_index].st_value,
- symtab[symtab_index].st_size,
- symtab[symtab_index].st_info,
- symtab[symtab_index].st_other,
- symtab[symtab_index].st_shndx);
- }
- }
-}
-
-static void debug_reloc(Elf32_Sym *symtab,char *strtab, ELF_RELOC *rpnt)
-{
- if(_dl_debug_reloc)
- {
- int symtab_index;
- const char *sym;
- symtab_index = ELF32_R_SYM(rpnt->r_info);
- sym = symtab_index ? strtab + symtab[symtab_index].st_name : "sym=0x0";
-
- if(_dl_debug_symbols)
- _dl_dprintf(_dl_debug_file, "\n\t");
- else
- _dl_dprintf(_dl_debug_file, "\n%s\n\t", sym);
-#ifdef ELF_USES_RELOCA
- _dl_dprintf(_dl_debug_file, "%s\toffset=%x\taddend=%x",
- _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
- rpnt->r_offset,
- rpnt->r_addend);
-#else
- _dl_dprintf(_dl_debug_file, "%s\toffset=%x\n",
- _dl_reltypes(ELF32_R_TYPE(rpnt->r_info)),
- rpnt->r_offset);
-#endif
- }
-}
-#endif
-
extern int _dl_runtime_resolve(void);
#define OFFSET_GP_GOT 0x7ff0
@@ -195,9 +119,9 @@ int _dl_parse_relocation_information(struct dyn_elf *xpnt,
symtab_index = ELF32_R_SYM(rpnt->r_info);
symbol_addr = 0;
-#if defined (__SUPPORT_LD_DEBUG__)
debug_sym(symtab,strtab,symtab_index);
debug_reloc(symtab,strtab,rpnt);
+#if defined (__SUPPORT_LD_DEBUG__)
if (reloc_addr)
old_val = *reloc_addr;
#endif
diff --git a/ldso/ldso/mips/resolve.S b/ldso/ldso/mips/resolve.S
index 8b492947d..6dc89643e 100644
--- a/ldso/ldso/mips/resolve.S
+++ b/ldso/ldso/mips/resolve.S
@@ -11,6 +11,7 @@
* Copyright (C) 2002 Steven J. Hill <sjhill@realitydiluted.com>
*
*/
+
.text
.align 2
.globl _dl_runtime_resolve
@@ -19,27 +20,48 @@
_dl_runtime_resolve:
.frame $29, 40, $31
.set noreorder
- move $3, $28 # Save GP
- addu $25, 8 # t9 ($25) now points at .cpload instruction
- .cpload $25 # Compute GP
- .set reorder
+
+ # Save GP.
+ move $3, $28
+
+ # Save arguments and sp value on stack.
subu $29, 40
+
+ # Modify t9 ($25) so as to point .cpload instruction.
+ addiu $25, 12
+
+ # Compute GP.
+ .set noreorder
+ .cpload $25
+ .set reorder
+
+ # Save slot call pc.
+ move $2, $31
.cprestore 32
+
+ # Store function arguments from registers to stack
sw $15, 36($29)
sw $4, 16($29)
sw $5, 20($29)
sw $6, 24($29)
sw $7, 28($29)
+
+ # Setup functions args and call __dl_runtime_resolve
move $4, $24
move $5, $3
- jal __dl_runtime_resolve
+ jal __dl_runtime_resolve
+
+ # Restore function arguments from stack to registers
lw $31, 36($29)
lw $4, 16($29)
lw $5, 20($29)
lw $6, 24($29)
lw $7, 28($29)
- addu $29, 40
+
+ # Do a tail call to the original function
+ addiu $29, 40
move $25, $2
jr $25
-.size _dl_runtime_resolve,.-_dl_runtime_resolve
-.end _dl_runtime_resolve
+.end _dl_runtime_resolve
+.previous
+
diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 0c744c210..76c8296e1 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -76,17 +76,28 @@ extern char *_dl_debug __attribute__ ((__weak__));
#ifdef __SUPPORT_LD_DEBUG__
char *_dl_debug = 0;
#endif
-char *_dl_library_path = 0; /* Where we look for libraries */
-char *_dl_ldsopath = 0; /* Location of the shared lib loader */
+char *_dl_library_path = 0; /* Where we look for libraries */
+char *_dl_ldsopath = 0; /* Location of the shared lib loader */
int _dl_errno = 0; /* We can't use the real errno in ldso */
size_t _dl_pagesize = PAGE_SIZE; /* Store the page size for use later */
/* This global variable is also to communicate with debuggers such as gdb. */
struct r_debug *_dl_debug_addr = NULL;
#define _dl_malloc malloc
+#include "../ldso/dl-debug.c"
#include "dl-progname.h"
#include "../ldso/dl-hash.c"
#define _dl_trace_loaded_objects 0
#include "../ldso/dl-elf.c"
+#endif /* __LIBDL_SHARED__ */
+
+#ifdef __SUPPORT_LD_DEBUG__
+# define _dl_if_debug_print(fmt, args...) \
+ do { \
+ if (_dl_debug) \
+ fprintf(stderr, "%s():%i: " fmt, __FUNCTION__, __LINE__, ## args); \
+ } while (0)
+#else
+# define _dl_if_debug_print(fmt, args...)
#endif
static int do_dlclose(void *, int need_fini);
@@ -128,7 +139,7 @@ void __attribute__ ((destructor)) dl_cleanup(void)
void *dlopen(const char *libname, int flag)
{
- struct elf_resolve *tpnt, *tfrom, *tcurr=NULL;
+ struct elf_resolve *tpnt, *tfrom;
struct dyn_elf *dyn_chain, *rpnt = NULL, *dyn_ptr, *relro_ptr, *handle;
struct dyn_elf *dpnt;
ElfW(Addr) from;
@@ -155,7 +166,7 @@ void *dlopen(const char *libname, int flag)
/*
* Try and locate the module we were called from - we
- * need this so that we get the correct RPATH. Note that
+ * need this so that we get the correct RPATH/RUNPATH. Note that
* this is the current behavior under Solaris, but the
* ABI+ specifies that we should only use the RPATH from
* the application. Thus this may go away at some time
@@ -168,14 +179,16 @@ void *dlopen(const char *libname, int flag)
&& (tfrom == NULL || tfrom->loadaddr < tpnt->loadaddr))
tfrom = tpnt;
}
- for(rpnt = _dl_symbol_tables; rpnt->next; rpnt=rpnt->next);
+ for(rpnt = _dl_symbol_tables; rpnt && rpnt->next; rpnt=rpnt->next);
relro_ptr = rpnt;
+ now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
+ if (getenv("LD_BIND_NOW"))
+ now_flag = RTLD_NOW;
+
/* Try to load the specified library */
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Trying to dlopen '%s'\n", (char*)libname);
-#endif
+ _dl_if_debug_print("Trying to dlopen '%s', RTLD_GLOBAL:%d RTLD_NOW:%d\n",
+ (char*)libname, (flag & RTLD_GLOBAL ? 1:0), (now_flag & RTLD_NOW ? 1:0));
tpnt = _dl_load_shared_library(0, &rpnt, tfrom, (char*)libname, 0);
if (tpnt == NULL) {
@@ -191,10 +204,7 @@ void *dlopen(const char *libname, int flag)
_dl_handles = dyn_ptr = dyn_chain;
if (tpnt->usage_count > 1) {
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Lib: % already opened\n", libname);
-#endif
+ _dl_if_debug_print("Lib: %s already opened\n", libname);
/* see if there is a handle from a earlier dlopen */
for (handle = _dl_handles->next_handle; handle; handle = handle->next_handle) {
if (handle->dyn == tpnt) {
@@ -211,10 +221,7 @@ void *dlopen(const char *libname, int flag)
tpnt->init_flag |= DL_OPENED;
}
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Looking for needed libraries\n");
-#endif
+ _dl_if_debug_print("Looking for needed libraries\n");
nlist = 0;
runp = alloca(sizeof(*runp));
runp->tpnt = tpnt;
@@ -222,24 +229,21 @@ void *dlopen(const char *libname, int flag)
dep_list = runp2 = runp;
for (; runp; runp = runp->next)
{
- Elf32_Dyn *dpnt;
+ ElfW(Dyn) *dpnt;
char *lpntstr;
nlist++;
runp->tpnt->init_fini = NULL; /* clear any previous dependcies */
- for (dpnt = (Elf32_Dyn *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) {
+ for (dpnt = (ElfW(Dyn) *) runp->tpnt->dynamic_addr; dpnt->d_tag; dpnt++) {
if (dpnt->d_tag == DT_NEEDED) {
char *name;
lpntstr = (char*) (runp->tpnt->dynamic_info[DT_STRTAB] +
dpnt->d_un.d_val);
name = _dl_get_last_path_component(lpntstr);
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Trying to load '%s', needed by '%s'\n",
- lpntstr, runp->tpnt->libname);
-#endif
- tpnt1 = _dl_load_shared_library(0, &rpnt, tcurr, lpntstr, 0);
+ _dl_if_debug_print("Trying to load '%s', needed by '%s'\n",
+ lpntstr, runp->tpnt->libname);
+ tpnt1 = _dl_load_shared_library(0, &rpnt, runp->tpnt, lpntstr, 0);
if (!tpnt1)
goto oops;
@@ -262,11 +266,8 @@ void *dlopen(const char *libname, int flag)
for (tmp=dep_list; tmp; tmp = tmp->next) {
if (tpnt1 == tmp->tpnt) { /* if match => cirular dependency, drop it */
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Circular dependency, skipping '%s',\n",
+ _dl_if_debug_print("Circular dependency, skipping '%s',\n",
tmp->tpnt->libname);
-#endif
tpnt1->usage_count--;
break;
}
@@ -308,10 +309,7 @@ void *dlopen(const char *libname, int flag)
for (; runp; runp = runp->next) {
if (runp->tpnt == runp2->tpnt) {
struct elf_resolve *here = init_fini_list[k];
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
-#endif
+ _dl_if_debug_print("Move %s from pos %d to %d in INIT/FINI list.\n", here->libname, k, j);
for (i = (k - j); i; --i)
init_fini_list[i+j] = init_fini_list[i+j-1];
init_fini_list[j] = here;
@@ -327,26 +325,19 @@ void *dlopen(const char *libname, int flag)
for (i=0;i < nlist;i++) {
fprintf(stderr, "lib: %s has deps:\n", init_fini_list[i]->libname);
runp = init_fini_list[i]->init_fini;
- for ( ;runp; runp = runp->next)
+ for (; runp; runp = runp->next)
printf(" %s ", runp->tpnt->libname);
printf("\n");
}
}
#endif
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "Beginning dlopen relocation fixups\n");
-#endif
+ _dl_if_debug_print("Beginning dlopen relocation fixups\n");
/*
* OK, now all of the kids are tucked into bed in their proper addresses.
* Now we go through and look for REL and RELA records that indicate fixups
* to the GOT tables. We need to do this in reverse order so that COPY
* directives work correctly */
- now_flag = (flag & RTLD_NOW) ? RTLD_NOW : 0;
- if (getenv("LD_BIND_NOW"))
- now_flag = RTLD_NOW;
-
#ifdef __mips__
/*
* Relocation of the GOT entries for MIPS have to be done
@@ -358,9 +349,11 @@ void *dlopen(const char *libname, int flag)
if (_dl_fixup(dyn_chain, now_flag))
goto oops;
- for (rpnt = relro_ptr->next; rpnt; rpnt = rpnt->next) {
- if (rpnt->dyn->relro_size)
- _dl_protect_relro(rpnt->dyn);
+ if (relro_ptr) {
+ for (rpnt = relro_ptr->next; rpnt; rpnt = rpnt->next) {
+ if (rpnt->dyn->relro_size)
+ _dl_protect_relro(rpnt->dyn);
+ }
}
/* TODO: Should we set the protections of all pages back to R/O now ? */
@@ -389,10 +382,8 @@ void *dlopen(const char *libname, int flag)
void (*dl_elf_func) (void);
dl_elf_func = (void (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_INIT]);
if (dl_elf_func && *dl_elf_func != NULL) {
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "running ctors for library %s at '%x'\n", tpnt->libname, (unsigned)dl_elf_func);
-#endif
+ _dl_if_debug_print("running ctors for library %s at '%p'\n",
+ tpnt->libname, dl_elf_func);
(*dl_elf_func) ();
}
}
@@ -492,10 +483,8 @@ static int do_dlclose(void *vhandle, int need_fini)
rpnt1->next_handle = rpnt->next_handle;
else
_dl_handles = rpnt->next_handle;
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "dlclose: %s, usage count: %d\n", handle->dyn->libname, handle->dyn->usage_count);
-#endif
+ _dl_if_debug_print("%s: usage count: %d\n",
+ handle->dyn->libname, handle->dyn->usage_count);
if (handle->dyn->usage_count != 1) {
handle->dyn->usage_count--;
free(handle);
@@ -509,17 +498,12 @@ static int do_dlclose(void *vhandle, int need_fini)
!(tpnt->init_flag & FINI_FUNCS_CALLED)) {
tpnt->init_flag |= FINI_FUNCS_CALLED;
dl_elf_fini = (int (*)(void)) (tpnt->loadaddr + tpnt->dynamic_info[DT_FINI]);
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "running dtors for library %s at '%x'\n", tpnt->libname, (unsigned)dl_elf_fini);
-#endif
+ _dl_if_debug_print("running dtors for library %s at '%p'\n",
+ tpnt->libname, dl_elf_fini);
(*dl_elf_fini) ();
}
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "dlclose unmapping: %s\n", tpnt->libname);
-#endif
+ _dl_if_debug_print("unmapping: %s\n", tpnt->libname);
end = 0;
for (i = 0, ppnt = tpnt->ppnt;
i < tpnt->n_phent; ppnt++, i++) {
@@ -543,10 +527,7 @@ static int do_dlclose(void *vhandle, int need_fini)
} else
for (run_tpnt = _dl_loaded_modules; run_tpnt; run_tpnt = run_tpnt->next)
if (run_tpnt->next == tpnt) {
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "dlclose removing loaded_modules: %s\n", tpnt->libname);
-#endif
+ _dl_if_debug_print("removing loaded_modules: %s\n", tpnt->libname);
run_tpnt->next = run_tpnt->next->next;
if (run_tpnt->next)
run_tpnt->next->prev = run_tpnt;
@@ -554,24 +535,23 @@ static int do_dlclose(void *vhandle, int need_fini)
}
/* Next, remove tpnt from the global symbol table list */
- if (_dl_symbol_tables->dyn == tpnt) {
- _dl_symbol_tables = _dl_symbol_tables->next;
- if (_dl_symbol_tables)
- _dl_symbol_tables->prev = 0;
- } else
- for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
- if (rpnt1->next->dyn == tpnt) {
-#ifdef __SUPPORT_LD_DEBUG__
- if(_dl_debug)
- fprintf(stderr, "dlclose removing symbol_tables: %s\n", tpnt->libname);
-#endif
- free(rpnt1->next);
- rpnt1->next = rpnt1->next->next;
- if (rpnt1->next)
- rpnt1->next->prev = rpnt1;
- break;
+ if (_dl_symbol_tables) {
+ if (_dl_symbol_tables->dyn == tpnt) {
+ _dl_symbol_tables = _dl_symbol_tables->next;
+ if (_dl_symbol_tables)
+ _dl_symbol_tables->prev = 0;
+ } else
+ for (rpnt1 = _dl_symbol_tables; rpnt1->next; rpnt1 = rpnt1->next) {
+ if (rpnt1->next->dyn == tpnt) {
+ _dl_if_debug_print("removing symbol_tables: %s\n", tpnt->libname);
+ free(rpnt1->next);
+ rpnt1->next = rpnt1->next->next;
+ if (rpnt1->next)
+ rpnt1->next->prev = rpnt1;
+ break;
+ }
}
- }
+ }
free(tpnt->libname);
free(tpnt);
}
@@ -623,24 +603,21 @@ int dlinfo(void)
fprintf(stderr, "List of loaded modules\n");
/* First start with a complete list of all of the loaded files. */
for (tpnt = _dl_loaded_modules; tpnt; tpnt = tpnt->next) {
- fprintf(stderr, "\t%x %x %x %s %d %s\n",
- (unsigned) tpnt->loadaddr, (unsigned) tpnt,
- (unsigned) tpnt->symbol_scope,
- type[tpnt->libtype],
- tpnt->usage_count, tpnt->libname);
+ fprintf(stderr, "\t%p %p %p %s %d %s\n",
+ tpnt->loadaddr, tpnt, tpnt->symbol_scope,
+ type[tpnt->libtype],
+ tpnt->usage_count, tpnt->libname);
}
/* Next dump the module list for the application itself */
- fprintf(stderr, "\nModules for application (%x):\n",
- (unsigned) _dl_symbol_tables);
+ fprintf(stderr, "\nModules for application (%p):\n", _dl_symbol_tables);
for (rpnt = _dl_symbol_tables; rpnt; rpnt = rpnt->next)
- fprintf(stderr, "\t%x %s\n", (unsigned) rpnt->dyn, rpnt->dyn->libname);
+ fprintf(stderr, "\t%p %s\n", rpnt->dyn, rpnt->dyn->libname);
for (hpnt = _dl_handles; hpnt; hpnt = hpnt->next_handle) {
- fprintf(stderr, "Modules for handle %x\n", (unsigned) hpnt);
+ fprintf(stderr, "Modules for handle %p\n", hpnt);
for (rpnt = hpnt; rpnt; rpnt = rpnt->next)
- fprintf(stderr, "\t%x %s\n", (unsigned) rpnt->dyn,
- rpnt->dyn->libname);
+ fprintf(stderr, "\t%p %s\n", rpnt->dyn, rpnt->dyn->libname);
}
return 0;
}
@@ -658,7 +635,7 @@ int dladdr(const void *__address, Dl_info * __info)
pelf = NULL;
#if 0
- fprintf(stderr, "dladdr( %x, %x )\n", __address, __info);
+ fprintf(stderr, "dladdr( %p, %p )\n", __address, __info);
#endif
for (rpnt = _dl_loaded_modules; rpnt; rpnt = rpnt->next) {
@@ -666,7 +643,7 @@ int dladdr(const void *__address, Dl_info * __info)
tpnt = rpnt;
#if 0
- fprintf(stderr, "Module \"%s\" at %x\n",
+ fprintf(stderr, "Module \"%s\" at %p\n",
tpnt->libname, tpnt->loadaddr);
#endif
if (tpnt->loadaddr < (ElfW(Addr)) __address
@@ -685,14 +662,14 @@ int dladdr(const void *__address, Dl_info * __info)
{
char *strtab;
- Elf32_Sym *symtab;
+ ElfW(Sym) *symtab;
int hn, si;
int sf;
int sn = 0;
ElfW(Addr) sa;
sa = 0;
- symtab = (Elf32_Sym *) (pelf->dynamic_info[DT_SYMTAB]);
+ symtab = (ElfW(Sym) *) (pelf->dynamic_info[DT_SYMTAB]);
strtab = (char *) (pelf->dynamic_info[DT_STRTAB]);
sf = 0;
@@ -707,7 +684,7 @@ int dladdr(const void *__address, Dl_info * __info)
sf = 1;
}
#if 0
- fprintf(stderr, "Symbol \"%s\" at %x\n",
+ fprintf(stderr, "Symbol \"%s\" at %p\n",
strtab + symtab[si].st_name, symbol_addr);
#endif
}
diff --git a/libc/inet/ntop.c b/libc/inet/ntop.c
index bcdc57df8..35c302950 100644
--- a/libc/inet/ntop.c
+++ b/libc/inet/ntop.c
@@ -58,10 +58,12 @@ inet_ntop4(const u_char *src, char *dst, size_t size)
i = 0;
for (octet = 0; octet <= 3; octet++) {
+#if 0 /* since src is unsigned char, it will never be > 255 ... */
if (src[octet] > 255) {
__set_errno (ENOSPC);
return (NULL);
}
+#endif
tmp[i++] = '0' + src[octet] / 100;
if (tmp[i - 1] == '0') {
tmp[i - 1] = '0' + (src[octet] / 10 % 10);
diff --git a/libc/inet/socketcalls.c b/libc/inet/socketcalls.c
index f93d10952..35ab1d7a8 100644
--- a/libc/inet/socketcalls.c
+++ b/libc/inet/socketcalls.c
@@ -164,6 +164,12 @@ ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
return (__socketcall(SYS_RECV, args));
}
weak_alias(__libc_recv, recv);
+#elif defined(__NR_recvfrom)
+ssize_t __libc_recv(int sockfd, __ptr_t buffer, size_t len, int flags)
+{
+ return (recvfrom(sockfd, buffer, len, flags, NULL, NULL));
+}
+weak_alias(__libc_recv, recv);
#endif
#endif
@@ -227,6 +233,12 @@ ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
return (__socketcall(SYS_SEND, args));
}
weak_alias(__libc_send, send);
+#elif defined(__NR_sendto)
+ssize_t __libc_send(int sockfd, const void *buffer, size_t len, int flags)
+{
+ return (sendto(sockfd, buffer, len, flags, NULL, 0));
+}
+weak_alias(__libc_send, send);
#endif
#endif
diff --git a/libc/misc/error/err.c b/libc/misc/error/err.c
index 5c53e545f..0d0637148 100644
--- a/libc/misc/error/err.c
+++ b/libc/misc/error/err.c
@@ -34,7 +34,7 @@ static void vwarn_work(const char *format, va_list args, int showerr)
f = fmt + 11; /* At 11. */
if (showerr) {
f -= 4; /* At 7. */
- _susv3_strerror_r(errno, buf, sizeof(buf));
+ __xpg_strerror_r(errno, buf, sizeof(buf));
}
__STDIO_AUTO_THREADLOCK(stderr);
diff --git a/libc/misc/glob/glob.c b/libc/misc/glob/glob.c
index 14e2a6e22..a93cf0ab4 100644
--- a/libc/misc/glob/glob.c
+++ b/libc/misc/glob/glob.c
@@ -59,7 +59,7 @@ int glob_pattern_p(const char *pattern, int quote)
return 1;
case '\\':
- if (quote)
+ if (quote && p[1] != '\0')
++p;
break;
diff --git a/libc/misc/internals/Makefile b/libc/misc/internals/Makefile
index 23816b38d..933b169a6 100644
--- a/libc/misc/internals/Makefile
+++ b/libc/misc/internals/Makefile
@@ -31,7 +31,7 @@ OBJS=$(COBJS)
OBJ_LIST=../../obj.misc.internals
-all: $(OBJ_LIST) interp.o
+all: $(OBJ_LIST) interp.o static.o
$(OBJ_LIST): $(OBJS)
echo $(patsubst %, misc/internals/%, $(OBJS)) > $(OBJ_LIST)
@@ -44,11 +44,7 @@ interp.c: Makefile
"(\".interp\"))) =\""$(DYNAMIC_LINKER)"\";" >> interp.c
echo "#endif" >> interp.c
-interp.o: interp.c
- $(CC) $(CFLAGS) -c $< -o $@
- $(STRIPTOOL) -x -R .note -R .comment $*.o
-
-$(COBJS): %.o : %.c
+$(COBJS) interp.o static.o: %.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
$(STRIPTOOL) -x -R .note -R .comment $*.o
diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
index a33e6fe4a..21864ba4f 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -32,7 +32,7 @@ extern void __guard_setup(void);
/*
* Prototypes.
*/
-extern int main(int argc, char **argv, char **envp);
+extern void *__libc_stack_end;
extern void weak_function _stdio_init(void);
extern int *weak_const_function __errno_location(void);
extern int *weak_const_function __h_errno_location(void);
@@ -165,14 +165,15 @@ void attribute_hidden (*__rtld_fini)(void) = NULL;
* are initialized, just before we call the application's main function.
*/
void __attribute__ ((__noreturn__))
-__uClibc_start_main(int argc, char **argv, char **envp,
- void (*app_init)(void), void (*app_fini)(void), void (*rtld_fini)(void))
+__uClibc_main(int (*main)(int, char **, char **), int argc,
+ char **argv, void (*app_init)(void), void (*app_fini)(void),
+ void (*rtld_fini)(void), void *stack_end)
{
#ifdef __ARCH_HAS_MMU__
unsigned long *aux_dat;
Elf32_auxv_t auxvt[AT_EGID + 1];
#endif
-
+ __libc_stack_end = stack_end;
/* We need to initialize uClibc. If we are dynamically linked this
* may have already been completed by the shared lib loader. We call
* __uClibc_init() regardless, to be sure the right thing happens. */
@@ -180,15 +181,19 @@ __uClibc_start_main(int argc, char **argv, char **envp,
__rtld_fini = rtld_fini;
- /* If we are dynamically linked, then ldso already did this for us. */
- if (__environ==NULL) {
- /* Statically linked. */
- __environ = envp;
+ /* The environment begins right after argv. */
+ __environ = &argv[argc + 1];
+
+ /* If the first thing after argv is the arguments
+ * the the environment is empty. */
+ if ((char *) __environ == *argv) {
+ /* Make __environ point to the NULL at argv[argc] */
+ __environ = &argv[argc];
}
/* Pull stuff from the ELF header when possible */
#ifdef __ARCH_HAS_MMU__
- aux_dat = (unsigned long*)envp;
+ aux_dat = (unsigned long*)__environ;
while (*aux_dat) {
aux_dat++;
}
@@ -247,23 +252,15 @@ __uClibc_start_main(int argc, char **argv, char **envp,
/*
* Finally, invoke application's main and then exit.
*/
- exit(main(argc, argv, envp));
+ exit(main(argc, argv, __environ));
}
-
-/* __uClibc_main is the old main stub of the uClibc. This
- * function is called from crt0 (uClibc 0.9.15 and older) after
- * ALL shared libraries are initialized, and just before we call
- * the application's main() function.
- *
- * Attention: This stub does not call the .init/.fini sections of
- * the application. If you need this, please fix your uClibc port
- * so that __uClibc_start_main is called by your crt0.S with
- * _init and _fini properly set.
-*/
+#ifdef _DL_FINI_CRT_COMPAT
+extern int weak_function main(int argc, char **argv, char **envp);
void __attribute__ ((__noreturn__))
-__uClibc_main(int argc, char **argv, char ** envp)
+__uClibc_start_main(int argc, char **argv, char **envp,
+ void (*app_fini)(void), void (*app_init)(void))
{
- __uClibc_start_main(argc, argv, envp, NULL, NULL, NULL);
+ __uClibc_main(main, argc, argv, app_init, app_fini, NULL, NULL);
}
-
+#endif
diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
index 90b4f5494..89c26110c 100644
--- a/libc/misc/pthread/weaks.c
+++ b/libc/misc/pthread/weaks.c
@@ -23,7 +23,6 @@
static int __pthread_return_0 __P ((void));
static int __pthread_return_1 __P ((void));
-static void __pthread_return_void __P ((void));
/**********************************************************************/
/* Weaks for application/library use.
@@ -118,8 +117,3 @@ __pthread_return_1 (void)
{
return 1;
}
-
-static void
-__pthread_return_void (void)
-{
-}
diff --git a/libc/misc/sysvipc/ipc.h b/libc/misc/sysvipc/ipc.h
index e1b94ad12..a5d443543 100644
--- a/libc/misc/sysvipc/ipc.h
+++ b/libc/misc/sysvipc/ipc.h
@@ -2,10 +2,10 @@
#define IPC_H
#include <syscall.h>
-#ifdef __NR_ipc
-
#define __IPC_64 0x100
+#ifdef __NR_ipc
+
/* The actual system call: all functions are multiplexed by this. */
extern int __syscall_ipc __P((int __call, int __first, int __second,
int __third, void *__ptr));
diff --git a/libc/misc/sysvipc/msgq.c b/libc/misc/sysvipc/msgq.c
index 411ea3ea4..758dbaa47 100644
--- a/libc/misc/sysvipc/msgq.c
+++ b/libc/misc/sysvipc/msgq.c
@@ -6,14 +6,18 @@
#ifdef L_msgctl
#ifdef __NR_msgctl
-_syscall3(int, msgctl, int, msqid, int, cmd | __IPC_64, struct msqid_ds *, buf);
-#else
+#define __NR___libc_msgctl __NR_msgctl
+_syscall3(int, __libc_msgctl, int, msqid, int, cmd, struct msqid_ds *, buf);
+#endif
/* Message queue control operation. */
-int msgctl (int msqid, int cmd, struct msqid_ds *buf)
+int msgctl(int msqid, int cmd, struct msqid_ds *buf)
{
- return __syscall_ipc(IPCOP_msgctl ,msqid ,cmd | __IPC_64 ,0 ,buf);
-}
+#ifdef __NR_msgctl
+ return __libc_msgctl(msqid, cmd | __IPC_64, buf);
+#else
+ return __syscall_ipc(IPCOP_msgctl, msqid, cmd | __IPC_64, 0, buf);
#endif
+}
#endif
diff --git a/libc/misc/sysvipc/shm.c b/libc/misc/sysvipc/shm.c
index d21d9f54b..29f3178d6 100644
--- a/libc/misc/sysvipc/shm.c
+++ b/libc/misc/sysvipc/shm.c
@@ -48,13 +48,17 @@ void * shmat (int shmid, const void *shmaddr, int shmflg)
#ifdef L_shmctl
/* Provide operations to control over shared memory segments. */
#ifdef __NR_shmctl
-_syscall3(int, shmctl, int, shmid, int, cmd | __IPC_64, struct shmid_ds *, buf);
-#else
-int shmctl (int shmid, int cmd, struct shmid_ds *buf)
+#define __NR___libc_shmctl __NR_shmctl
+_syscall3(int, __libc_shmctl, int, shmid, int, cmd, struct shmid_ds *, buf);
+#endif
+int shmctl(int shmid, int cmd, struct shmid_ds *buf)
{
- return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64 , 0, buf);
-}
+#ifdef __NR_shmctl
+ return __libc_shmctl(shmid, cmd | __IPC_64, buf);
+#else
+ return __syscall_ipc(IPCOP_shmctl, shmid, cmd | __IPC_64, 0, buf);
#endif
+}
#endif
diff --git a/libc/misc/time/time.c b/libc/misc/time/time.c
index 7b1ae388b..f43bb8a3c 100644
--- a/libc/misc/time/time.c
+++ b/libc/misc/time/time.c
@@ -118,6 +118,15 @@
* Make lookup_tzname() static (as it should have been).
* Have strftime() get timezone information from the passed struct
* for the %z and %Z conversions when using struct tm extensions.
+ *
+ * Jul 24, 2004
+ * Fix 2 bugs in strftime related to glibc struct tm extensions.
+ * 1) Need to negate tm_gmtoff field value when used. (bug 336).
+ * 2) Deal with NULL ptr case for tm_zone field, which was causing
+ * segfaults in both the NIST/PCTS tests and the Python 2.4.1
+ * self-test suite.
+ * NOTE: We set uninitialized timezone names to "???", and this
+ * differs (intentionally) from glibc's behavior.
*/
#define _GNU_SOURCE
@@ -1066,7 +1075,7 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize,
#define RSP_TZUNLOCK ((void) 0)
#define RSP_TZNAME timeptr->tm_zone
-#define RSP_GMT_OFFSET timeptr->tm_gmtoff
+#define RSP_GMT_OFFSET (-timeptr->tm_gmtoff)
#else
@@ -1084,6 +1093,20 @@ size_t __XL(strftime)(char *__restrict s, size_t maxsize,
if (*p == 'Z') {
o = RSP_TZNAME;
+#ifdef __UCLIBC_HAS_TM_EXTENSIONS__
+ /* Sigh... blasted glibc extensions. Of course we can't
+ * count on the pointer being valid. Best we can do is
+ * handle NULL, which looks to be all that glibc does.
+ * At least that catches the memset() with 0 case.
+ * NOTE: We handle this case differently than glibc!
+ * It uses system timezone name (based on tm_isdst) in this
+ * case... although it always seems to use the embedded
+ * tm_gmtoff value. What we'll do instead is treat the
+ * timezone name as unknown/invalid and return "???". */
+ if (!o) {
+ o = "???";
+ }
+#endif
assert(o != NULL);
#if 0
if (!o) { /* PARANOIA */
@@ -1939,7 +1962,9 @@ void tzset(void)
daylight = !!_time_tzinfo[1].tzname[0];
timezone = _time_tzinfo[0].gmt_offset;
+#if defined(__UCLIBC_HAS_TZ_FILE__)
FAST_DONE:
+#endif
TZUNLOCK;
}
diff --git a/libc/stdio/_fpmaxtostr.c b/libc/stdio/_fpmaxtostr.c
index 7fd67ffb4..b9aacdca8 100644
--- a/libc/stdio/_fpmaxtostr.c
+++ b/libc/stdio/_fpmaxtostr.c
@@ -11,8 +11,8 @@
#include <locale.h>
#include <bits/uClibc_fpmax.h>
-typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
- intptr_t buf);
+typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
+ intptr_t buf);
/* Copyright (C) 2000, 2001, 2003 Manuel Novoa III
@@ -198,14 +198,13 @@ static const __fpmax_t exp16_table[] = {
#define FPO_STR_WIDTH (0x80 | ' ');
#define FPO_STR_PREC 'p'
-size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
- __fp_outfunc_t fp_outfunc)
+ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
+ __fp_outfunc_t fp_outfunc)
{
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
__fpmax_t lower_bnd;
__fpmax_t upper_bnd = 1e9;
#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- uint_fast32_t digit_block;
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
uint_fast32_t base = 10;
const __fpmax_t *power_table;
@@ -221,9 +220,8 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
int nblk2; /* This does not need to be initialized. */
const char *ts; /* This does not need to be initialized. */
#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
- int i, j;
int round, o_exp;
- int exp, exp_neg;
+ int exp;
int width, preci;
int cnt;
char *s;
@@ -304,34 +302,36 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
goto EXIT_SPECIAL;
}
+ {
+ int i, j;
#ifdef __UCLIBC_MJN3_ONLY__
#warning TODO: Clean up defines when hexadecimal float notation is unsupported.
#endif /* __UCLIBC_MJN3_ONLY__ */
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- if ((mode|0x20) == 'a') {
- lower_bnd = 0x1.0p31L;
- upper_bnd = 0x1.0p32L;
- power_table = exp16_table;
- exp = HEX_DIGITS_PER_BLOCK - 1;
- i = EXP16_TABLE_SIZE;
- j = EXP16_TABLE_MAX;
- dpb = HEX_DIGITS_PER_BLOCK;
- ndb = NUM_HEX_DIGIT_BLOCKS;
- nd = NUM_HEX_DIGITS;
- base = 16;
- } else {
- lower_bnd = 1e8;
-/* upper_bnd = 1e9; */
- power_table = exp10_table;
- exp = DIGITS_PER_BLOCK - 1;
- i = EXP10_TABLE_SIZE;
- j = EXP10_TABLE_MAX;
-/* dpb = DIGITS_PER_BLOCK; */
-/* ndb = NUM_DIGIT_BLOCKS; */
-/* base = 10; */
- }
+ if ((mode|0x20) == 'a') {
+ lower_bnd = 0x1.0p31L;
+ upper_bnd = 0x1.0p32L;
+ power_table = exp16_table;
+ exp = HEX_DIGITS_PER_BLOCK - 1;
+ i = EXP16_TABLE_SIZE;
+ j = EXP16_TABLE_MAX;
+ dpb = HEX_DIGITS_PER_BLOCK;
+ ndb = NUM_HEX_DIGIT_BLOCKS;
+ nd = NUM_HEX_DIGITS;
+ base = 16;
+ } else {
+ lower_bnd = 1e8;
+ /* upper_bnd = 1e9; */
+ power_table = exp10_table;
+ exp = DIGITS_PER_BLOCK - 1;
+ i = EXP10_TABLE_SIZE;
+ j = EXP10_TABLE_MAX;
+ /* dpb = DIGITS_PER_BLOCK; */
+ /* ndb = NUM_DIGIT_BLOCKS; */
+ /* base = 10; */
+ }
@@ -345,32 +345,35 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
#define ndb NUM_DIGIT_BLOCKS
#define nd DECIMAL_DIG
- exp = DIGITS_PER_BLOCK - 1;
- i = EXP10_TABLE_SIZE;
- j = EXP10_TABLE_MAX;
+ exp = DIGITS_PER_BLOCK - 1;
+ i = EXP10_TABLE_SIZE;
+ j = EXP10_TABLE_MAX;
#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- exp_neg = 0;
- if (x < lower_bnd) { /* Do we need to scale up or down? */
- exp_neg = 1;
- }
-
- do {
- --i;
- if (exp_neg) {
- if (x * power_table[i] < upper_bnd) {
- x *= power_table[i];
- exp -= j;
- }
- } else {
- if (x / power_table[i] >= lower_bnd) {
- x /= power_table[i];
- exp += j;
+ {
+ int exp_neg = 0;
+ if (x < lower_bnd) { /* Do we need to scale up or down? */
+ exp_neg = 1;
}
+
+ do {
+ --i;
+ if (exp_neg) {
+ if (x * power_table[i] < upper_bnd) {
+ x *= power_table[i];
+ exp -= j;
+ }
+ } else {
+ if (x / power_table[i] >= lower_bnd) {
+ x /= power_table[i];
+ exp += j;
+ }
+ }
+ j >>= 1;
+ } while (i);
}
- j >>= 1;
- } while (i);
+ }
if (x >= upper_bnd) { /* Handle bad rounding case. */
x /= power_table[0];
++exp;
@@ -378,22 +381,25 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
assert(x < upper_bnd);
GENERATE_DIGITS:
- s = buf + 2; /* Leave space for '\0' and '0'. */
- i = 0;
- do {
- digit_block = (uint_fast32_t) x;
- assert(digit_block < upper_bnd);
+ {
+ int i, j;
+ s = buf + 2; /* Leave space for '\0' and '0'. */
+ i = 0;
+ do {
+ uint_fast32_t digit_block = (uint_fast32_t) x;
+ assert(digit_block < upper_bnd);
#ifdef __UCLIBC_MJN3_ONLY__
#warning CONSIDER: Can rounding be a problem?
#endif /* __UCLIBC_MJN3_ONLY__ */
- x = (x - digit_block) * upper_bnd;
- s += dpb;
- j = 0;
- do {
- s[- ++j] = '0' + (digit_block % base);
- digit_block /= base;
- } while (j < dpb);
- } while (++i < ndb);
+ x = (x - digit_block) * upper_bnd;
+ s += dpb;
+ j = 0;
+ do {
+ s[- ++j] = '0' + (digit_block % base);
+ digit_block /= base;
+ } while (j < dpb);
+ } while (++i < ndb);
+ }
/*************************************************************************/
@@ -421,18 +427,21 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
*s++ = 0; /* Terminator for rounding and 0-triming. */
*s = '0'; /* Space to round. */
- i = 0;
- e = s + nd + 1;
- if (round < nd) {
- e = s + round + 2;
- if (*e >= '0' + (base/2)) { /* NOTE: We always round away from 0! */
- i = 1;
+ {
+ int i;
+ i = 0;
+ e = s + nd + 1;
+ if (round < nd) {
+ e = s + round + 2;
+ if (*e >= '0' + (base/2)) { /* NOTE: We always round away from 0! */
+ i = 1;
+ }
}
- }
- do { /* Handle rounding and trim trailing 0s. */
- *--e += i; /* Add the carry. */
- } while ((*e == '0') || (*e > '0' - 1 + base));
+ do { /* Handle rounding and trim trailing 0s. */
+ *--e += i; /* Add the carry. */
+ } while ((*e == '0') || (*e > '0' - 1 + base));
+ }
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
if ((mode|0x20) == 'a') {
@@ -480,80 +489,81 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
sign_str[5] = 0;
ppc = pc_fwi + 6;
- i = e - s; /* Total digits is 'i'. */
- if (o_exp >= 0) {
+ {
+ int i = e - s; /* Total digits is 'i'. */
+ if (o_exp >= 0) {
#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
- const char *p;
+ const char *p;
- if (PRINT_INFO_FLAG_VAL(info,group)
- && *(p = __UCLIBC_CURLOCALE_DATA.grouping)
- ) {
- int nblk1;
+ if (PRINT_INFO_FLAG_VAL(info,group)
+ && *(p = __UCLIBC_CURLOCALE_DATA.grouping)
+ ) {
+ int nblk1;
- nblk2 = nblk1 = *p;
- if (*++p) {
- nblk2 = *p;
- assert(!*++p);
- }
+ nblk2 = nblk1 = *p;
+ if (*++p) {
+ nblk2 = *p;
+ assert(!*++p);
+ }
- if (o_exp >= nblk1) {
- num_groups = (o_exp - nblk1) / nblk2 + 1;
- initial_group = (o_exp - nblk1) % nblk2;
+ if (o_exp >= nblk1) {
+ num_groups = (o_exp - nblk1) / nblk2 + 1;
+ initial_group = (o_exp - nblk1) % nblk2;
#ifdef __UCLIBC_HAS_WCHAR__
- if (PRINT_INFO_FLAG_VAL(info,wide)) {
- /* _fp_out_wide() will fix this up. */
- ts = fmt + THOUSEP_OFFSET;
- tslen = 1;
- } else {
+ if (PRINT_INFO_FLAG_VAL(info,wide)) {
+ /* _fp_out_wide() will fix this up. */
+ ts = fmt + THOUSEP_OFFSET;
+ tslen = 1;
+ } else {
#endif /* __UCLIBC_HAS_WCHAR__ */
- ts = __UCLIBC_CURLOCALE_DATA.thousands_sep;
- tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
+ ts = __UCLIBC_CURLOCALE_DATA.thousands_sep;
+ tslen = __UCLIBC_CURLOCALE_DATA.thousands_sep_len;
#ifdef __UCLIBC_HAS_WCHAR__
- }
+ }
#endif /* __UCLIBC_HAS_WCHAR__ */
- width -= num_groups * tslen;
+ width -= num_groups * tslen;
+ }
}
- }
#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
- ppc[0] = FPO_STR_PREC;
- ppc[2] = (intptr_t)(s);
- if (o_exp >= i) { /* all digit(s) left of decimal */
- ppc[1] = i;
- ppc += 3;
- o_exp -= i;
- i = 0;
- if (o_exp>0) { /* have 0s left of decimal */
- ppc[0] = FPO_ZERO_PAD;
+ ppc[0] = FPO_STR_PREC;
+ ppc[2] = (intptr_t)(s);
+ if (o_exp >= i) { /* all digit(s) left of decimal */
+ ppc[1] = i;
+ ppc += 3;
+ o_exp -= i;
+ i = 0;
+ if (o_exp>0) { /* have 0s left of decimal */
+ ppc[0] = FPO_ZERO_PAD;
+ ppc[1] = o_exp;
+ ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
+ ppc += 3;
+ }
+ } else if (o_exp > 0) { /* decimal between digits */
ppc[1] = o_exp;
- ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
ppc += 3;
+ s += o_exp;
+ i -= o_exp;
}
- } else if (o_exp > 0) { /* decimal between digits */
- ppc[1] = o_exp;
- ppc += 3;
- s += o_exp;
- i -= o_exp;
+ o_exp = -1;
}
- o_exp = -1;
- }
- if (PRINT_INFO_FLAG_VAL(info,alt)
- || (i)
- || ((o_mode != 'g')
+ if (PRINT_INFO_FLAG_VAL(info,alt)
+ || (i)
+ || ((o_mode != 'g')
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- && (o_mode != 'a')
+ && (o_mode != 'a')
#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- && (preci > 0))
- ) {
- ppc[0] = FPO_STR_PREC;
+ && (preci > 0))
+ ) {
+ ppc[0] = FPO_STR_PREC;
#ifdef __LOCALE_C_ONLY
- ppc[1] = 1;
- ppc[2] = (intptr_t)(fmt + DECPT_OFFSET);
+ ppc[1] = 1;
+ ppc[2] = (intptr_t)(fmt + DECPT_OFFSET);
#else /* __LOCALE_C_ONLY */
#ifdef __UCLIBC_HAS_WCHAR__
if (PRINT_INFO_FLAG_VAL(info,wide)) {
@@ -569,39 +579,41 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
#endif /* __UCLIBC_HAS_WCHAR__ */
#endif /* __LOCALE_C_ONLY */
ppc += 3;
- }
-
- if (++o_exp < 0) { /* Have 0s right of decimal. */
- ppc[0] = FPO_ZERO_PAD;
- ppc[1] = -o_exp;
- ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
- ppc += 3;
- }
- if (i) { /* Have digit(s) right of decimal. */
- ppc[0] = FPO_STR_PREC;
- ppc[1] = i;
- ppc[2] = (intptr_t)(s);
- ppc += 3;
- }
+ }
- if (((o_mode != 'g') || PRINT_INFO_FLAG_VAL(info,alt))
-#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- && !sufficient_precision
-#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- ) {
- i -= o_exp;
- if (i < preci) { /* Have 0s right of digits. */
- i = preci - i;
+ if (++o_exp < 0) { /* Have 0s right of decimal. */
ppc[0] = FPO_ZERO_PAD;
- ppc[1] = i;
+ ppc[1] = -o_exp;
ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
ppc += 3;
}
+ if (i) { /* Have digit(s) right of decimal. */
+ ppc[0] = FPO_STR_PREC;
+ ppc[1] = i;
+ ppc[2] = (intptr_t)(s);
+ ppc += 3;
+ }
+
+ if (((o_mode != 'g') || PRINT_INFO_FLAG_VAL(info,alt))
+#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
+ && !sufficient_precision
+#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
+ ) {
+ i -= o_exp;
+ if (i < preci) { /* Have 0s right of digits. */
+ i = preci - i;
+ ppc[0] = FPO_ZERO_PAD;
+ ppc[1] = i;
+ ppc[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
+ ppc += 3;
+ }
+ }
}
/* Build exponent string. */
if (mode != 'f') {
char *p = exp_buf + sizeof(exp_buf);
+ int j;
char exp_char = *exp_buf;
char exp_sign = '+';
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
@@ -631,43 +643,46 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
}
EXIT_SPECIAL:
- ppc_last = ppc;
- ppc = pc_fwi + 4; /* Need width fields starting with second. */
- do {
- width -= *ppc;
- ppc += 3;
- } while (ppc < ppc_last);
+ {
+ int i;
+ ppc_last = ppc;
+ ppc = pc_fwi + 4; /* Need width fields starting with second. */
+ do {
+ width -= *ppc;
+ ppc += 3;
+ } while (ppc < ppc_last);
- ppc = pc_fwi;
- ppc[0] = FPO_STR_WIDTH;
- ppc[1] = i = ((*sign_str) != 0);
- ppc[2] = (intptr_t) sign_str;
+ ppc = pc_fwi;
+ ppc[0] = FPO_STR_WIDTH;
+ ppc[1] = i = ((*sign_str) != 0);
+ ppc[2] = (intptr_t) sign_str;
#ifdef __UCLIBC_HAS_HEXADECIMAL_FLOATS__
- if (((mode|0x20) == 'a') && (pc_fwi[3] >= 16)) { /* Hex sign handling. */
- /* Hex and not inf or nan, so prefix with 0x. */
- char *h = sign_str + i;
- *h = '0';
- *++h = 'x' - 'p' + *exp_buf;
- *++h = 0;
- ppc[1] = (i += 2);
- }
+ if (((mode|0x20) == 'a') && (pc_fwi[3] >= 16)) { /* Hex sign handling. */
+ /* Hex and not inf or nan, so prefix with 0x. */
+ char *h = sign_str + i;
+ *h = '0';
+ *++h = 'x' - 'p' + *exp_buf;
+ *++h = 0;
+ ppc[1] = (i += 2);
+ }
#endif /* __UCLIBC_HAS_HEXADECIMAL_FLOATS__ */
- if ((width -= i) > 0) {
- if (PRINT_INFO_FLAG_VAL(info,left)) { /* Left-justified. */
- ppc_last[0] = FPO_STR_WIDTH;
- ppc_last[1] = width;
- ppc_last[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
- ppc_last += 3;
- } else if (info->pad == '0') { /* 0 padding */
- ppc[4] += width; /* Pad second field. */
- } else {
- ppc[1] += width; /* Pad first (sign) field. */
+ if ((width -= i) > 0) {
+ if (PRINT_INFO_FLAG_VAL(info,left)) { /* Left-justified. */
+ ppc_last[0] = FPO_STR_WIDTH;
+ ppc_last[1] = width;
+ ppc_last[2] = (intptr_t)(fmt + EMPTY_STRING_OFFSET);
+ ppc_last += 3;
+ } else if (info->pad == '0') { /* 0 padding */
+ ppc[4] += width; /* Pad second field. */
+ } else {
+ ppc[1] += width; /* Pad first (sign) field. */
+ }
}
- }
- cnt = 0;
+ cnt = 0;
+ }
do {
#ifdef __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__
@@ -685,7 +700,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
blk = nblk2;
} else if (len >= blk) { /* Enough digits for a group. */
/* printf("norm: len=%d blk=%d \"%.*s\"\n", len, blk, blk, gp); */
- fp_outfunc(fp, *ppc, blk, (intptr_t) gp);
+ if (fp_outfunc(fp, *ppc, blk, (intptr_t) gp) != blk) {
+ return -1;
+ }
assert(gp);
if (*gp) {
gp += blk;
@@ -695,7 +712,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
/* printf("trans: len=%d blk=%d \"%.*s\"\n", len, blk, len, gp); */
if (len) {
/* printf("len\n"); */
- fp_outfunc(fp, *ppc, len, (intptr_t) gp);
+ if (fp_outfunc(fp, *ppc, len, (intptr_t) gp) != len) {
+ return -1;
+ }
gp += len;
}
@@ -718,7 +737,9 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
}
--num_groups;
- fp_outfunc(fp, FPO_STR_PREC, tslen, (intptr_t) ts);
+ if (fp_outfunc(fp, FPO_STR_PREC, tslen, (intptr_t) ts) != tslen) {
+ return -1;
+ }
blk = nblk2;
/* printf("num_groups=%d blk=%d\n", num_groups, blk); */
@@ -727,8 +748,11 @@ size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
} else
#endif /* __UCLIBC_HAS_GLIBC_DIGIT_GROUPING__ */
-
- fp_outfunc(fp, *ppc, ppc[1], ppc[2]); /* NOTE: Remember 'else' above! */
+ { /* NOTE: Remember 'else' above! */
+ if (fp_outfunc(fp, *ppc, ppc[1], ppc[2]) != ppc[1]) {
+ return -1;
+ }
+ }
cnt += ppc[1];
ppc += 3;
diff --git a/libc/stdio/old_vfprintf.c b/libc/stdio/old_vfprintf.c
index 1b7af96f9..23cb10f94 100644
--- a/libc/stdio/old_vfprintf.c
+++ b/libc/stdio/old_vfprintf.c
@@ -448,7 +448,7 @@ int vfprintf(FILE * __restrict op, register const char * __restrict fmt,
if (*fmt == 'm') {
flag[FLAG_PLUS] = '\0';
flag[FLAG_0_PAD] = ' ';
- p = _glibc_strerror_r(errno, tmp, sizeof(tmp));
+ p = __glibc_strerror_r(errno, tmp, sizeof(tmp));
goto print;
}
#endif
diff --git a/libc/stdio/perror.c b/libc/stdio/perror.c
index 83db7689f..26a0cebd9 100644
--- a/libc/stdio/perror.c
+++ b/libc/stdio/perror.c
@@ -30,7 +30,7 @@ void perror(register const char *s)
{
char buf[64];
fprintf(stderr, "%s%s%s\n", s, sep,
- _glibc_strerror_r(errno, buf, sizeof(buf)));
+ __glibc_strerror_r(errno, buf, sizeof(buf)));
}
#endif
}
diff --git a/libc/stdio/vfprintf.c b/libc/stdio/vfprintf.c
index d3214fff0..10114f061 100644
--- a/libc/stdio/vfprintf.c
+++ b/libc/stdio/vfprintf.c
@@ -410,11 +410,11 @@ typedef struct {
only returns -1 if sets error indicator for the stream. */
#ifdef __STDIO_PRINTF_FLOAT
-typedef void (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
- intptr_t buf);
+typedef size_t (__fp_outfunc_t)(FILE *fp, intptr_t type, intptr_t len,
+ intptr_t buf);
-extern size_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
- __fp_outfunc_t fp_outfunc);
+extern ssize_t _fpmaxtostr(FILE * fp, __fpmax_t x, struct printf_info *info,
+ __fp_outfunc_t fp_outfunc);
#endif
extern int _ppfs_init(ppfs_t *ppfs, const char *fmt0); /* validates */
@@ -1185,7 +1185,7 @@ int register_printf_function(int spec, printf_function handler,
* In other words, we don't currently support glibc's 'I' flag.
* We do accept it, but it is currently ignored. */
-static void _charpad(FILE * __restrict stream, int padchar, size_t numpad);
+static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad);
#ifdef L_vfprintf
@@ -1201,16 +1201,20 @@ static void _charpad(FILE * __restrict stream, int padchar, size_t numpad);
#ifdef __STDIO_PRINTF_FLOAT
-static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
+static size_t _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
{
+ size_t r = 0;
+
if (type & 0x80) { /* Some type of padding needed. */
int buflen = strlen((const char *) buf);
if ((len -= buflen) > 0) {
- _charpad(fp, (type & 0x7f), len);
+ if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
+ return r;
+ }
}
len = buflen;
}
- OUTNSTR(fp, (const char *) buf, len);
+ return r + OUTNSTR(fp, (const char *) buf, len);
}
#endif /* __STDIO_PRINTF_FLOAT */
@@ -1226,12 +1230,12 @@ static void _fp_out_narrow(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
#define _outnwcs(stream, wstring, len) _wstdio_fwrite(wstring, len, stream)
#define FP_OUT _fp_out_wide
-static void _outnstr(FILE *stream, const char *s, size_t wclen)
+static size_t _outnstr(FILE *stream, const char *s, size_t wclen)
{
/* NOTE!!! len here is the number of wchars we want to generate!!! */
wchar_t wbuf[64];
mbstate_t mbstate;
- size_t todo, r;
+ size_t todo, r, n;
mbstate.__mask = 0;
todo = wclen;
@@ -1243,9 +1247,14 @@ static void _outnstr(FILE *stream, const char *s, size_t wclen)
: sizeof(wbuf)/sizeof(wbuf[0])),
&mbstate);
assert(((ssize_t)r) > 0);
- _outnwcs(stream, wbuf, r);
- todo -= r;
+ n = _outnwcs(stream, wbuf, r);
+ todo -= n;
+ if (n != r) {
+ break;
+ }
}
+
+ return wclen - todo;
}
#ifdef __STDIO_PRINTF_FLOAT
@@ -1259,16 +1268,19 @@ static void _outnstr(FILE *stream, const char *s, size_t wclen)
#define NUM_DIGIT_BLOCKS ((DECIMAL_DIG+DIGITS_PER_BLOCK-1)/DIGITS_PER_BLOCK)
#define BUF_SIZE ( 3 + NUM_DIGIT_BLOCKS * DIGITS_PER_BLOCK )
-static void _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
+static size_t _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
{
wchar_t wbuf[BUF_SIZE];
const char *s = (const char *) buf;
+ size_t r = 0;
int i;
if (type & 0x80) { /* Some type of padding needed */
int buflen = strlen(s);
if ((len -= buflen) > 0) {
- _charpad(fp, (type & 0x7f), len);
+ if ((r = _charpad(fp, (type & 0x7f), len)) != len) {
+ return r;
+ }
}
len = buflen;
}
@@ -1294,8 +1306,10 @@ static void _fp_out_wide(FILE *fp, intptr_t type, intptr_t len, intptr_t buf)
} while (++i < len);
- OUTNSTR(fp, wbuf, len);
+ r += OUTNSTR(fp, wbuf, len);
}
+
+ return r;
}
#endif /* __STDIO_PRINTF_FLOAT */
@@ -1385,16 +1399,19 @@ static int _ppwfs_init(register ppfs_t *ppfs, const wchar_t *fmt0)
#endif /* L_vfprintf */
-static void _charpad(FILE * __restrict stream, int padchar, size_t numpad)
+static size_t _charpad(FILE * __restrict stream, int padchar, size_t numpad)
{
+ size_t todo = numpad;
+
/* TODO -- Use a buffer to cut down on function calls... */
FMT_TYPE pad[1];
*pad = padchar;
- while (numpad) {
- OUTNSTR(stream, pad, 1);
- --numpad;
+ while (todo && (OUTNSTR(stream, pad, 1) == 1)) {
+ --todo;
}
+
+ return numpad - todo;
}
/* TODO -- Dynamically allocate work space to accomodate stack-poor archs? */
@@ -1583,13 +1600,18 @@ static int _do_one_spec(FILE * __restrict stream,
numfill = ((numfill > SLEN) ? numfill - SLEN : 0);
} else if (ppfs->conv_num <= CONV_A) { /* floating point */
#ifdef __STDIO_PRINTF_FLOAT
- *count +=
- _fpmaxtostr(stream,
- (__fpmax_t)
- (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double)
- ? *(long double *) *argptr
- : (long double) (* (double *) *argptr)),
- &ppfs->info, FP_OUT );
+ ssize_t nf;
+ nf = _fpmaxtostr(stream,
+ (__fpmax_t)
+ (PRINT_INFO_FLAG_VAL(&(ppfs->info),is_long_double)
+ ? *(long double *) *argptr
+ : (long double) (* (double *) *argptr)),
+ &ppfs->info, FP_OUT );
+ if (nf < 0) {
+ return -1;
+ }
+ *count += nf;
+
return 0;
#else /* __STDIO_PRINTF_FLOAT */
return -1; /* TODO -- try to continue? */
@@ -1708,7 +1730,7 @@ static int _do_one_spec(FILE * __restrict stream,
#ifdef __UCLIBC_HAS_PRINTF_M_SPEC__
} else if (ppfs->conv_num == CONV_m) {
- s = _glibc_strerror_r(errno, buf, sizeof(buf));
+ s = __glibc_strerror_r(errno, buf, sizeof(buf));
goto SET_STRING_LEN;
#endif
} else {
@@ -1757,18 +1779,24 @@ static int _do_one_spec(FILE * __restrict stream,
/* Now handle the output itself. */
if (!PRINT_INFO_FLAG_VAL(&(ppfs->info),left)) {
- _charpad(stream, ' ', numpad);
+ if (_charpad(stream, ' ', numpad) != numpad) {
+ return -1;
+ }
numpad = 0;
}
OUTPUT(stream, prefix + prefix_num);
- _charpad(stream, '0', numfill);
+ if (_charpad(stream, '0', numfill) != numfill) {
+ return -1;
+ }
#ifdef L_vfprintf
#ifdef __UCLIBC_HAS_WCHAR__
if (!ws) {
assert(s);
- _outnstr(stream, s, slen);
+ if (_outnstr(stream, s, slen) != slen) {
+ return -1;
+ }
} else { /* wide string */
size_t t;
mbstate.__mask = 0; /* Initialize the mbstate. */
@@ -1776,25 +1804,35 @@ static int _do_one_spec(FILE * __restrict stream,
t = (slen <= sizeof(buf)) ? slen : sizeof(buf);
t = wcsrtombs(buf, &ws, t, &mbstate);
assert (t != ((size_t)(-1)));
- _outnstr(stream, buf, t);
+ if (_outnstr(stream, buf, t) != t) {
+ return -1;
+ }
slen -= t;
}
}
#else /* __UCLIBC_HAS_WCHAR__ */
- _outnstr(stream, s, slen);
+ if (_outnstr(stream, s, slen) != slen) {
+ return -1;
+ }
#endif /* __UCLIBC_HAS_WCHAR__ */
#else /* L_vfprintf */
if (!ws) {
assert(s);
- _outnstr(stream, s, SLEN);
+ if (_outnstr(stream, s, SLEN) != SLEN) {
+ return -1;
+ }
} else {
- _outnwcs(stream, ws, SLEN);
+ if (_outnwcs(stream, ws, SLEN) != SLEN) {
+ return -1;
+ }
}
#endif /* L_vfprintf */
- _charpad(stream, ' ', numpad);
+ if (_charpad(stream, ' ', numpad) != numpad) {
+ return -1;
+ }
}
return 0;
@@ -1840,7 +1878,7 @@ int VFPRINTF (FILE * __restrict stream,
}
if (format-s) { /* output any literal text in format string */
- if ( (r = OUTNSTR(stream, s, format-s)) < 0) {
+ if ( (r = OUTNSTR(stream, s, format-s)) != (format-s)) {
count = -1;
break;
}
diff --git a/libc/stdlib/abort.c b/libc/stdlib/abort.c
index e34c86778..77c2cdc69 100644
--- a/libc/stdlib/abort.c
+++ b/libc/stdlib/abort.c
@@ -30,99 +30,120 @@ Cambridge, MA 02139, USA. */
/* Our last ditch effort to commit suicide */
-#if defined(__i386__)
+#if defined(__alpha__)
+#define ABORT_INSTRUCTION asm ("call_pal 0")
+#elif defined(__hppa__)
+#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)")
+#elif defined(__i386__)
#define ABORT_INSTRUCTION asm ("hlt")
#elif defined(__ia64__)
#define ABORT_INSTRUCTION asm ("break 0")
+#elif defined(__m68k__)
+#define ABORT_INSTRUCTION asm ("illegal")
#elif defined(__mc68000__)
#define ABORT_INSTRUCTION asm (".long 0xffffffff")
#elif defined(__mips__)
#define ABORT_INSTRUCTION asm ("break 255")
+#elif defined(__powerpc__)
+#define ABORT_INSTRUCTION asm (".long 0")
#elif defined(__s390__)
#define ABORT_INSTRUCTION asm (".word 0")
#elif defined(__sparc__)
#define ABORT_INSTRUCTION asm ("unimp 0xf00")
-#elif defined(__x86_64__)
-#define ABORT_INSTRUCTION asm ("hlt")
-#elif defined(__hppa__)
-#define ABORT_INSTRUCTION asm ("iitlbp %r0,(%r0)")
-#elif defined(__powerpc__)
-#define ABORT_INSTRUCTION asm (".long 0")
#elif defined(__SH5__)
#define ABORT_INSTRUCTION asm ("movi 0x10, r9; shori 0xff, r9; trapa r9")
#elif defined(__sh2__)
#define ABORT_INSTRUCTION asm ("trapa #32")
#elif defined(__sh__)
#define ABORT_INSTRUCTION asm ("trapa #0xff")
+#elif defined(__x86_64__)
+#define ABORT_INSTRUCTION asm ("hlt")
#else
#define ABORT_INSTRUCTION
+#warning no abort instruction define for your arch
#endif
+#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
+extern void weak_function _stdio_term(void);
+#endif
extern void _exit __P((int __status)) __attribute__ ((__noreturn__));
static int been_there_done_that = 0;
-/* Be prepared in case multiple threads try to abort(). */
+/* Be prepared in case multiple threads try to abort() */
#ifdef __UCLIBC_HAS_THREADS__
-#include <pthread.h>
+# include <pthread.h>
static pthread_mutex_t mylock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
# define LOCK __pthread_mutex_lock(&mylock)
-# define UNLOCK __pthread_mutex_unlock(&mylock);
+# define UNLOCK __pthread_mutex_unlock(&mylock)
#else
# define LOCK
# define UNLOCK
#endif
-/* Cause an abnormal program termination with core-dump. */
+/* Cause an abnormal program termination with core-dump */
void abort(void)
{
- sigset_t sigset;
-
- /* Make sure we acquire the lock before proceeding. */
- LOCK;
-
- /* Unmask SIGABRT to be sure we can get it */
- if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) {
- sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL);
- }
-
- while (1) {
- /* Try to suicide with a SIGABRT. */
- if (been_there_done_that == 0) {
- been_there_done_that++;
- UNLOCK;
- raise(SIGABRT);
- LOCK;
- }
+ sigset_t sigset;
- /* Still here? Try to remove any signal handlers. */
- if (been_there_done_that == 1) {
- struct sigaction act;
+ /* Make sure we acquire the lock before proceeding */
+ LOCK;
- been_there_done_that++;
- memset (&act, '\0', sizeof (struct sigaction));
- act.sa_handler = SIG_DFL;
- __sigfillset (&act.sa_mask);
- act.sa_flags = 0;
- sigaction (SIGABRT, &act, NULL);
+ /* Unmask SIGABRT to be sure we can get it */
+ if (__sigemptyset(&sigset) == 0 && __sigaddset(&sigset, SIGABRT) == 0) {
+ sigprocmask(SIG_UNBLOCK, &sigset, (sigset_t *) NULL);
}
- /* Still here? Try to suicide with an illegal instruction */
- if (been_there_done_that == 2) {
- been_there_done_that++;
- ABORT_INSTRUCTION;
- }
+ while (1) {
+ /* Try to suicide with a SIGABRT */
+ if (been_there_done_that == 0) {
+ been_there_done_that++;
+
+#ifdef __UCLIBC_HAS_STDIO_SHUTDOWN_ON_ABORT__
+ /* If we are using stdio, try to shut it down. At the very least,
+ * this will attemt to commit all buffered writes. It may also
+ * unboffer all writable files, or close them outright.
+ * Check the stdio routines for details. */
+ if (_stdio_term) {
+ _stdio_term();
+ }
+#endif
- /* Still here? Try to at least exit */
- if (been_there_done_that == 3) {
- been_there_done_that++;
- _exit (127);
+abort_it:
+ UNLOCK;
+ raise(SIGABRT);
+ LOCK;
+ }
+
+ /* Still here? Try to remove any signal handlers */
+ if (been_there_done_that == 1) {
+ struct sigaction act;
+
+ been_there_done_that++;
+ memset(&act, '\0', sizeof(struct sigaction));
+ act.sa_handler = SIG_DFL;
+ __sigfillset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGABRT, &act, NULL);
+
+ goto abort_it;
+ }
+
+ /* Still here? Try to suicide with an illegal instruction */
+ if (been_there_done_that == 2) {
+ been_there_done_that++;
+ ABORT_INSTRUCTION;
+ }
+
+ /* Still here? Try to at least exit */
+ if (been_there_done_that == 3) {
+ been_there_done_that++;
+ _exit(127);
+ }
+
+ /* Still here? We're screwed. Sleepy time. Good night. */
+ while (1)
+ /* Try for ever and ever */
+ ABORT_INSTRUCTION;
}
-
- /* Still here? We're screwed. Sleepy time. Good night */
- while (1)
- /* Try for ever and ever. */
- ABORT_INSTRUCTION;
- }
}
-
diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c
index d5f83ee8e..280f42cb7 100644
--- a/libc/stdlib/atexit.c
+++ b/libc/stdlib/atexit.c
@@ -239,8 +239,7 @@ void exit(int rv)
if (__app_fini != NULL)
(__app_fini)();
#endif
-#ifdef _DL_DO_FINI_IN_LIBC
-/* arches that has moved their ldso FINI handling should #define _DL_DO_FINI_IN_LIBC */
+#ifndef _DL_FINI_CRT_COMPAT
if (__rtld_fini != NULL)
(__rtld_fini)();
#endif
diff --git a/libc/stdlib/malloc-simple/alloc.c b/libc/stdlib/malloc-simple/alloc.c
index 68cd77665..ed14c37c4 100644
--- a/libc/stdlib/malloc-simple/alloc.c
+++ b/libc/stdlib/malloc-simple/alloc.c
@@ -1,6 +1,6 @@
/* alloc.c
*
- * Written by Erik Andersen <andersee@debian.org>
+ * Written by Erik Andersen <andersee@codepoet.org>
* LGPLv2
*
* Parts of the memalign code were stolen from malloc-930716.
@@ -20,31 +20,29 @@
#ifdef L_malloc
void *malloc(size_t size)
{
- void *result;
+ void *result;
- if (unlikely(size == 0)) {
+ if (unlikely(size == 0)) {
#if defined(__MALLOC_GLIBC_COMPAT__)
- size++;
+ size++;
#else
- /* Some programs will call malloc (0). Lets be strict and return NULL */
- return 0;
+ /* Some programs will call malloc (0). Lets be strict and return NULL */
+ return 0;
#endif
- }
+ }
#ifdef __ARCH_HAS_MMU__
- result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
- if (result == MAP_FAILED)
- return 0;
- * (size_t *) result = size;
- return(result + sizeof(size_t));
+# define MMAP_FLAGS MAP_PRIVATE | MAP_ANONYMOUS
#else
- result = mmap((void *) 0, size, PROT_READ | PROT_WRITE,
- MAP_SHARED | MAP_ANONYMOUS, 0, 0);
- if (result == MAP_FAILED)
- return 0;
- return(result);
+# define MMAP_FLAGS MAP_SHARED | MAP_ANONYMOUS
#endif
+
+ result = mmap((void *) 0, size + sizeof(size_t), PROT_READ | PROT_WRITE,
+ MMAP_FLAGS, 0, 0);
+ if (result == MAP_FAILED)
+ return 0;
+ * (size_t *) result = size;
+ return(result + sizeof(size_t));
}
#endif
@@ -76,27 +74,21 @@ void * calloc(size_t nmemb, size_t lsize)
#ifdef L_realloc
void *realloc(void *ptr, size_t size)
{
- void *newptr = NULL;
-
- if (!ptr)
- return malloc(size);
- if (!size) {
- free(ptr);
- return malloc(0);
- }
-
- newptr = malloc(size);
- if (newptr) {
- memcpy(newptr, ptr,
-#ifdef __ARCH_HAS_MMU__
- *((size_t *) (ptr - sizeof(size_t)))
-#else
- size
-#endif
- );
- free(ptr);
- }
- return newptr;
+ void *newptr = NULL;
+
+ if (!ptr)
+ return malloc(size);
+ if (!size) {
+ free(ptr);
+ return malloc(0);
+ }
+
+ newptr = malloc(size);
+ if (newptr) {
+ memcpy(newptr, ptr, *((size_t *) (ptr - sizeof(size_t))));
+ free(ptr);
+ }
+ return newptr;
}
#endif
@@ -104,19 +96,14 @@ void *realloc(void *ptr, size_t size)
extern int weak_function __libc_free_aligned(void *ptr);
void free(void *ptr)
{
- if (ptr == NULL)
- return;
- if (unlikely(__libc_free_aligned!=NULL)) {
- if (__libc_free_aligned(ptr)) {
- return;
+ if (unlikely(ptr == NULL))
+ return;
+ if (unlikely(__libc_free_aligned != NULL)) {
+ if (__libc_free_aligned(ptr))
+ return;
}
- }
-#ifdef __ARCH_HAS_MMU__
- ptr -= sizeof(size_t);
- munmap(ptr, * (size_t *) ptr + sizeof(size_t));
-#else
- munmap(ptr, 0);
-#endif
+ ptr -= sizeof(size_t);
+ munmap(ptr, * (size_t *) ptr + sizeof(size_t));
}
#endif
@@ -134,73 +121,67 @@ pthread_mutex_t __malloc_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
/* List of blocks allocated with memalign or valloc */
struct alignlist
{
- struct alignlist *next;
- __ptr_t aligned; /* The address that memaligned returned. */
- __ptr_t exact; /* The address that malloc returned. */
+ struct alignlist *next;
+ __ptr_t aligned; /* The address that memaligned returned. */
+ __ptr_t exact; /* The address that malloc returned. */
};
struct alignlist *_aligned_blocks;
/* Return memory to the heap. */
int __libc_free_aligned(void *ptr)
{
- struct alignlist *l;
+ struct alignlist *l;
- if (ptr == NULL)
- return 0;
+ if (ptr == NULL)
+ return 0;
- LOCK;
- for (l = _aligned_blocks; l != NULL; l = l->next) {
- if (l->aligned == ptr) {
- /* Mark the block as free */
- l->aligned = NULL;
- ptr = l->exact;
-#ifdef __ARCH_HAS_MMU__
- ptr -= sizeof(size_t);
- munmap(ptr, * (size_t *) ptr + sizeof(size_t));
-#else
- munmap(ptr, 0);
-#endif
- return 1;
+ LOCK;
+ for (l = _aligned_blocks; l != NULL; l = l->next) {
+ if (l->aligned == ptr) {
+ /* Mark the block as free */
+ l->aligned = NULL;
+ ptr = l->exact;
+ ptr -= sizeof(size_t);
+ munmap(ptr, * (size_t *) ptr + sizeof(size_t));
+ return 1;
+ }
}
- }
- UNLOCK;
- return 0;
+ UNLOCK;
+ return 0;
}
void * memalign (size_t alignment, size_t size)
{
- void * result;
- unsigned long int adj;
-
- result = malloc (size + alignment - 1);
- if (result == NULL)
- return NULL;
- adj = (unsigned long int) ((unsigned long int) ((char *) result -
- (char *) NULL)) % alignment;
- if (adj != 0)
- {
- struct alignlist *l;
- LOCK;
- for (l = _aligned_blocks; l != NULL; l = l->next)
- if (l->aligned == NULL)
- /* This slot is free. Use it. */
- break;
- if (l == NULL)
- {
- l = (struct alignlist *) malloc (sizeof (struct alignlist));
- if (l == NULL) {
- free(result);
- UNLOCK;
+ void * result;
+ unsigned long int adj;
+
+ result = malloc (size + alignment - 1);
+ if (result == NULL)
return NULL;
- }
- l->next = _aligned_blocks;
- _aligned_blocks = l;
+
+ adj = (unsigned long int) ((unsigned long int) ((char *) result -
+ (char *) NULL)) % alignment;
+ if (adj != 0) {
+ struct alignlist *l;
+ LOCK;
+ for (l = _aligned_blocks; l != NULL; l = l->next)
+ if (l->aligned == NULL)
+ /* This slot is free. Use it. */
+ break;
+ if (l == NULL) {
+ l = (struct alignlist *) malloc (sizeof (struct alignlist));
+ if (l == NULL) {
+ free(result);
+ UNLOCK;
+ return NULL;
+ }
+ l->next = _aligned_blocks;
+ _aligned_blocks = l;
+ }
+ l->exact = result;
+ result = l->aligned = (char *) result + alignment - adj;
+ UNLOCK;
}
- l->exact = result;
- result = l->aligned = (char *) result + alignment - adj;
- UNLOCK;
- }
- return result;
+ return result;
}
#endif
-
diff --git a/libc/stdlib/malloc-standard/malloc.c b/libc/stdlib/malloc-standard/malloc.c
index 51e02a240..7025e8335 100644
--- a/libc/stdlib/malloc-standard/malloc.c
+++ b/libc/stdlib/malloc-standard/malloc.c
@@ -827,6 +827,10 @@ void* malloc(size_t bytes)
mchunkptr bck; /* misc temp for linking */
void * sysmem;
+#if !defined(__MALLOC_GLIBC_COMPAT__)
+ if (!bytes) return NULL;
+#endif
+
LOCK;
av = get_malloc_state();
/*
diff --git a/libc/string/Makefile b/libc/string/Makefile
index 4150e403e..6b516c1c5 100644
--- a/libc/string/Makefile
+++ b/libc/string/Makefile
@@ -39,8 +39,8 @@ MOBJ= basename.o bcopy.o bzero.o dirname.o ffs.o memccpy.o memchr.o memcmp.o \
stpncpy.o strcasecmp.o strcasestr.o strcat.o strchrnul.o strchr.o \
strcmp.o strcpy.o strcspn.o strdup.o strlen.o strncasecmp.o strncat.o \
strncmp.o strncpy.o strndup.o strnlen.o strpbrk.o strrchr.o strsep.o \
- strspn.o strstr.o strtok.o strtok_r.o strerror.o _susv3_strerror_r.o \
- _string_syserrmsgs.o _glibc_strerror_r.o \
+ strspn.o strstr.o strtok.o strtok_r.o strerror.o __xpg_strerror_r.o \
+ _string_syserrmsgs.o __glibc_strerror_r.o \
_string_syssigmsgs.o sys_siglist.o strsignal.o psignal.o \
__xpg_basename.o strlcat.o strlcpy.o sys_errlist.o memmem.o
@@ -64,7 +64,7 @@ endif
OBJS=$(MOBJ) $(MOBJx)
ifeq ($(UCLIBC_HAS_WCHAR),y)
-OBJS += $(MOBJW) $(MOBJWx)
+ OBJS += $(MOBJW) $(MOBJWx)
endif
OBJ_LIST=../obj.string
diff --git a/libc/string/wstring.c b/libc/string/wstring.c
index ed9ebb232..6f54ae615 100644
--- a/libc/string/wstring.c
+++ b/libc/string/wstring.c
@@ -1299,7 +1299,7 @@ char *strerror(int errnum)
{
static char buf[_STRERROR_BUFSIZE];
- _susv3_strerror_r(errnum, buf, sizeof(buf));
+ __xpg_strerror_r(errnum, buf, sizeof(buf));
return buf;
}
@@ -1308,7 +1308,7 @@ char *strerror(int errnum)
/**********************************************************************/
/* SUSv3 functions. */
/**********************************************************************/
-#ifdef L__susv3_strerror_r
+#ifdef L___xpg_strerror_r
#ifdef __UCLIBC_HAS_ERRNO_MESSAGES__
#if defined(__alpha__) || defined(__mips__) || defined(__sparc__)
@@ -1450,7 +1450,7 @@ static const unsigned char estridx[] = {
#endif
-int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
register char *s;
int i, retval;
@@ -1528,7 +1528,7 @@ int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
#else /* __UCLIBC_HAS_ERRNO_MESSAGES__ */
-int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+int __xpg_strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
register char *s;
int i, retval;
@@ -1569,13 +1569,13 @@ int _susv3_strerror_r(int errnum, char *strerrbuf, size_t buflen)
/**********************************************************************/
/* GNU extension functions. */
/**********************************************************************/
-#ifdef L__glibc_strerror_r
+#ifdef L___glibc_strerror_r
-weak_alias(_glibc_strerror_r,__strerror_r);
+weak_alias(__glibc_strerror_r,__strerror_r);
-char *_glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
+char *__glibc_strerror_r(int errnum, char *strerrbuf, size_t buflen)
{
- _susv3_strerror_r(errnum, strerrbuf, buflen);
+ __xpg_strerror_r(errnum, strerrbuf, buflen);
return strerrbuf;
}
diff --git a/libc/sysdeps/linux/common/Makefile b/libc/sysdeps/linux/common/Makefile
index 5e17cc9fc..84b29ac53 100644
--- a/libc/sysdeps/linux/common/Makefile
+++ b/libc/sysdeps/linux/common/Makefile
@@ -28,6 +28,7 @@ endif
ifneq ($(strip $(UCLIBC_HAS_SSP)),y)
SRCS := $(filter-out ssp.c,$(SRCS))
endif
+ssp.o: CFLAGS += $(SSP_DISABLE_FLAGS)
OBJS = $(patsubst %.c,%.o, $(SRCS))
diff --git a/libc/sysdeps/linux/common/__syscall_fcntl.c b/libc/sysdeps/linux/common/__syscall_fcntl.c
index 62568522b..0a5812976 100644
--- a/libc/sysdeps/linux/common/__syscall_fcntl.c
+++ b/libc/sysdeps/linux/common/__syscall_fcntl.c
@@ -11,10 +11,12 @@
#include <stdarg.h>
#include <fcntl.h>
-#define __NR___syscall_fcntl __NR_fcntl
#ifdef __UCLIBC_HAS_LFS__
-static inline
+extern int __libc_fcntl64(int fd, int cmd, long arg);
#endif
+
+#define __NR___syscall_fcntl __NR_fcntl
+static inline
_syscall3(int, __syscall_fcntl, int, fd, int, cmd, long, arg);
int __libc_fcntl(int fd, int cmd, ...)
@@ -22,13 +24,18 @@ int __libc_fcntl(int fd, int cmd, ...)
long arg;
va_list list;
+ va_start(list, cmd);
+ arg = va_arg(list, long);
+ va_end(list);
+
if (cmd == F_GETLK64 || cmd == F_SETLK64 || cmd == F_SETLKW64) {
+#ifdef __UCLIBC_HAS_LFS__
+ return __libc_fcntl64(fd, cmd, arg);
+#else
__set_errno(ENOSYS);
return -1;
+#endif
}
- va_start(list, cmd);
- arg = va_arg(list, long);
- va_end(list);
return (__syscall_fcntl(fd, cmd, arg));
}
diff --git a/libc/sysdeps/linux/common/bits/errno.h b/libc/sysdeps/linux/common/bits/errno.h
index d31dca8aa..cb9c2ee43 100644
--- a/libc/sysdeps/linux/common/bits/errno.h
+++ b/libc/sysdeps/linux/common/bits/errno.h
@@ -37,7 +37,7 @@ extern int errno;
/* Function to get address of global `errno' variable. */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));
-# if defined _LIBC && !defined(__set_errno)
+# if defined _LIBC
/* We wouldn't need a special macro anymore but it is history. */
# define __set_errno(val) ((errno) = (val))
# endif /* _LIBC */
diff --git a/libc/sysdeps/linux/common/bits/ipc.h b/libc/sysdeps/linux/common/bits/ipc.h
index 7cd2fd0c5..f1a043fe5 100644
--- a/libc/sysdeps/linux/common/bits/ipc.h
+++ b/libc/sysdeps/linux/common/bits/ipc.h
@@ -38,19 +38,19 @@
/* Special key values. */
#define IPC_PRIVATE ((__key_t) 0) /* Private key. */
+
/* Data structure used to pass permission information to IPC operations. */
struct ipc_perm
{
- __key_t __key; /* Key. */
- __uid_t uid; /* Owner's user ID. */
- __gid_t gid; /* Owner's group ID. */
- __uid_t cuid; /* Creator's user ID. */
- __gid_t cgid; /* Creator's group ID. */
- unsigned short int mode; /* Read/write permission. */
+ __key_t __key; /* Key. */
+ __uid_t uid; /* Owner's user ID. */
+ __gid_t gid; /* Owner's group ID. */
+ __uid_t cuid; /* Creator's user ID. */
+ __gid_t cgid; /* Creator's group ID. */
+ unsigned short int mode; /* Read/write permission. */
unsigned short int __pad1;
- unsigned short int __seq; /* Sequence number. */
+ unsigned short int __seq; /* Sequence number. */
unsigned short int __pad2;
unsigned long int __unused1;
unsigned long int __unused2;
};
-
diff --git a/libc/sysdeps/linux/common/bits/sem.h b/libc/sysdeps/linux/common/bits/sem.h
index f900136f0..6193501e2 100644
--- a/libc/sysdeps/linux/common/bits/sem.h
+++ b/libc/sysdeps/linux/common/bits/sem.h
@@ -36,15 +36,16 @@
/* Data structure describing a set of semaphores. */
-struct semid_ds {
- struct ipc_perm sem_perm; /* permissions .. see ipc.h */
- __kernel_time_t sem_otime; /* last semop time */
- __kernel_time_t sem_ctime; /* last change time */
- struct sem *sem_base; /* ptr to first semaphore in array */
- struct sem_queue *sem_pending; /* pending operations to be processed */
- struct sem_queue **sem_pending_last; /* last pending operation */
- struct sem_undo *undo; /* undo requests on this array */
- unsigned short sem_nsems; /* no. of semaphores in array */
+struct semid_ds
+{
+ struct ipc_perm sem_perm; /* operation permission struct */
+ __time_t sem_otime; /* last semop() time */
+ unsigned long int __unused1;
+ __time_t sem_ctime; /* last time changed by semctl() */
+ unsigned long int __unused2;
+ unsigned long int sem_nsems; /* number of semaphores in set */
+ unsigned long int __unused3;
+ unsigned long int __unused4;
};
/* The user should define a union like the following to use it for arguments
diff --git a/libc/sysdeps/linux/common/bits/sigthread.h b/libc/sysdeps/linux/common/bits/sigthread.h
index 960bde18a..0a634ac68 100644
--- a/libc/sysdeps/linux/common/bits/sigthread.h
+++ b/libc/sysdeps/linux/common/bits/sigthread.h
@@ -1,18 +1,18 @@
/* Signal handling function for threaded programs.
- Copyright (C) 1998, 1999, 2000, 2002 Free Software Foundation, Inc.
+ Copyright (C) 1998, 1999, 2000 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
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 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.
+ Library General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
+ You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If not,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
@@ -33,6 +33,6 @@ extern int pthread_sigmask (int __how,
__sigset_t *__restrict __oldmask)__THROW;
/* Send signal SIGNO to the given thread. */
-extern int pthread_kill (pthread_t __threadid, int __signo) __THROW;
+extern int pthread_kill (pthread_t __thread_id, int __signo) __THROW;
#endif /* bits/sigthread.h */
diff --git a/libc/sysdeps/linux/common/bits/stat.h b/libc/sysdeps/linux/common/bits/stat.h
index 3ecec4a47..3e8e77f65 100644
--- a/libc/sysdeps/linux/common/bits/stat.h
+++ b/libc/sysdeps/linux/common/bits/stat.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,95,96,97,98,99,2000,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1992, 1995-2001, 2002 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
@@ -63,11 +63,11 @@ struct stat
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
#endif
__time_t st_atime; /* Time of last access. */
- unsigned long int __unused1;
+ unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
- unsigned long int __unused2;
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
- unsigned long int __unused3;
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
#ifndef __USE_FILE_OFFSET64
unsigned long int __unused4;
unsigned long int __unused5;
@@ -94,11 +94,11 @@ struct stat64
__blkcnt64_t st_blocks; /* Number 512-byte blocks allocated. */
__time_t st_atime; /* Time of last access. */
- unsigned long int __unused1;
+ unsigned long int st_atimensec; /* Nscecs of last access. */
__time_t st_mtime; /* Time of last modification. */
- unsigned long int __unused2;
+ unsigned long int st_mtimensec; /* Nsecs of last modification. */
__time_t st_ctime; /* Time of last status change. */
- unsigned long int __unused3;
+ unsigned long int st_ctimensec; /* Nsecs of last status change. */
__ino64_t st_ino; /* File serial number. */
};
#endif
@@ -107,6 +107,8 @@ struct stat64
/* Tell code we have these members. */
#define _STATBUF_ST_BLKSIZE
#define _STATBUF_ST_RDEV
+/* Nanosecond resolution time values are supported. */
+#define _STATBUF_ST_NSEC
/* Encoding of the file mode. */
diff --git a/libc/sysdeps/linux/common/ioperm.c b/libc/sysdeps/linux/common/ioperm.c
index 8afba049e..874577a64 100644
--- a/libc/sysdeps/linux/common/ioperm.c
+++ b/libc/sysdeps/linux/common/ioperm.c
@@ -8,12 +8,12 @@
*/
#include "syscalls.h"
-# if defined __ARCH_HAS_MMU__ && defined __NR_ioperm
+#if defined __ARCH_HAS_MMU__ && defined __NR_ioperm
_syscall3(int, ioperm, unsigned long, from, unsigned long, num, int, turn_on);
-# else
+#else
int ioperm(unsigned long from, unsigned long num, int turn_on)
{
__set_errno(ENOSYS);
return -1;
}
-# endif
+#endif
diff --git a/libc/sysdeps/linux/common/pread_write.c b/libc/sysdeps/linux/common/pread_write.c
index bf04be41f..05eff4bc9 100644
--- a/libc/sysdeps/linux/common/pread_write.c
+++ b/libc/sysdeps/linux/common/pread_write.c
@@ -186,7 +186,9 @@ weak_alias (__libc_pread64, pread64)
#ifndef __NR_pwrite
ssize_t __libc_pwrite(int fd, const void *buf, size_t count, off_t offset)
{
- return(__fake_pread_write(fd, buf, count, offset, 1));
+ /* we won't actually be modifying the buffer,
+ *just cast it to get rid of warnings */
+ return(__fake_pread_write(fd, (void*)buf, count, offset, 1));
}
weak_alias (__libc_pwrite, pwrite)
diff --git a/libc/sysdeps/linux/common/ssp.c b/libc/sysdeps/linux/common/ssp.c
index ecfc67e5e..31833cbb9 100644
--- a/libc/sysdeps/linux/common/ssp.c
+++ b/libc/sysdeps/linux/common/ssp.c
@@ -20,6 +20,10 @@
# include <config.h>
#endif
+#ifdef __SSP__
+# error ssp.c has to be built w/ -fno-stack-protector
+#endif
+
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
@@ -30,29 +34,38 @@
#include <sys/syslog.h>
#include <sys/time.h>
#ifdef __SSP_USE_ERANDOM__
-#include <sys/sysctl.h>
+# include <sys/sysctl.h>
#endif
#ifdef __PROPOLICE_BLOCK_SEGV__
-#define SSP_SIGTYPE SIGSEGV
+# define SSP_SIGTYPE SIGSEGV
#elif __PROPOLICE_BLOCK_KILL__
-#define SSP_SIGTYPE SIGKILL
+# define SSP_SIGTYPE SIGKILL
#else
-#define SSP_SIGTYPE SIGABRT
+# define SSP_SIGTYPE SIGABRT
#endif
-/* prototypes */
-extern int __libc_open (__const char *file, int oflag, mode_t mode);
-extern ssize_t __libc_read(int fd, void *buf, size_t count);
-extern int __libc_close (int fd);
-
unsigned long __guard = 0UL;
+/* Use of __* functions from the rest of glibc here avoids
+ * initialisation problems for executables preloaded with
+ * libraries that overload the associated standard library
+ * functions.
+ */
+#ifdef __UCLIBC__
+extern int __libc_open(__const char *file, int flags, ...);
+extern ssize_t __libc_read(int fd, void *buf, size_t count);
+extern int __libc_close(int fd);
+#else
+# define __libc_open(file, flags) __open(file, flags)
+# define __libc_read(fd, buf, count) __read(fd, buf, count)
+# define __libc_close(fd) __close(fd)
+#endif
+
void __guard_setup(void) __attribute__ ((constructor));
void __guard_setup(void)
{
size_t size;
- struct timeval tv;
if (__guard != 0UL)
return;
@@ -61,18 +74,20 @@ void __guard_setup(void)
__guard = 0xFF0A0D00UL;
#ifndef __SSP_QUICK_CANARY__
-#ifdef __SSP_USE_ERANDOM__
- int mib[3];
- /* Random is another depth in Linux, hence an array of 3. */
- mib[0] = CTL_KERN;
- mib[1] = KERN_RANDOM;
- mib[2] = RANDOM_ERANDOM;
-
- size = sizeof(unsigned long);
- if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1))
- if (__guard != 0UL)
- return;
-#endif
+# ifdef __SSP_USE_ERANDOM__
+ {
+ int mib[3];
+ /* Random is another depth in Linux, hence an array of 3. */
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_RANDOM;
+ mib[2] = RANDOM_ERANDOM;
+
+ size = sizeof(unsigned long);
+ if (__sysctl(mib, 3, &__guard, &size, NULL, 0) != (-1))
+ if (__guard != 0UL)
+ return;
+ }
+# endif /* ifdef __SSP_USE_ERANDOM__ */
/*
* Attempt to open kernel pseudo random device if one exists before
* opening urandom to avoid system entropy depletion.
@@ -80,9 +95,9 @@ void __guard_setup(void)
{
int fd;
-#ifdef __SSP_USE_ERANDOM__
+# ifdef __SSP_USE_ERANDOM__
if ((fd = __libc_open("/dev/erandom", O_RDONLY)) == (-1))
-#endif
+# endif
fd = __libc_open("/dev/urandom", O_RDONLY);
if (fd != (-1)) {
size = __libc_read(fd, (char *) &__guard, sizeof(__guard));
@@ -91,13 +106,15 @@ void __guard_setup(void)
return;
}
}
-#endif
+#endif /* ifndef __SSP_QUICK_CANARY__ */
/* Everything failed? Or we are using a weakened model of the
* terminator canary */
-
- gettimeofday(&tv, NULL);
- __guard ^= tv.tv_usec ^ tv.tv_sec;
+ {
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ __guard ^= tv.tv_usec ^ tv.tv_sec;
+ }
}
void __stack_smash_handler(char func[], int damaged __attribute__ ((unused)));
diff --git a/libc/sysdeps/linux/common/umount.c b/libc/sysdeps/linux/common/umount.c
index d8e890d8b..158aefc5f 100644
--- a/libc/sysdeps/linux/common/umount.c
+++ b/libc/sysdeps/linux/common/umount.c
@@ -9,26 +9,33 @@
#include "syscalls.h"
-#ifdef __NR_umount /* Some newer archs only have umount2 */
+
+/* arch provides umount() syscall */
+#ifdef __NR_umount
+
#include <sys/mount.h>
_syscall1(int, umount, const char *, specialfile);
+
+/* arch provides umount2() syscall */
#elif defined __NR_umount2
-/* No umount syscall, but umount2 is available.... Try to
- * emulate umount() using umount2() */
#define __NR___syscall_umount2 __NR_umount2
-static inline _syscall2(int, umount2, const char *, special_file, int, flags);
+static inline _syscall2(int, __syscall_umount2, const char *, special_file, int, flags);
int umount(const char *special_file)
{
return (__syscall_umount2(special_file, 0));
}
+
+/* arch doesn't provide any umount syscall !? */
#else
+
int umount(const char *special_file)
{
__set_errno(ENOSYS);
return -1;
}
+
#endif
diff --git a/libc/sysdeps/linux/common/xstatconv.c b/libc/sysdeps/linux/common/xstatconv.c
index fc25c43db..df6ebaa2b 100644
--- a/libc/sysdeps/linux/common/xstatconv.c
+++ b/libc/sysdeps/linux/common/xstatconv.c
@@ -34,42 +34,53 @@
void __xstat_conv(struct kernel_stat *kbuf, struct stat *buf)
{
- /* Convert to current kernel version of `struct stat'. */
- buf->st_dev = kbuf->st_dev;
- buf->st_ino = kbuf->st_ino;
- buf->st_mode = kbuf->st_mode;
- buf->st_nlink = kbuf->st_nlink;
- buf->st_uid = kbuf->st_uid;
- buf->st_gid = kbuf->st_gid;
- buf->st_rdev = kbuf->st_rdev;
- buf->st_size = kbuf->st_size;
- buf->st_blksize = kbuf->st_blksize;
- buf->st_blocks = kbuf->st_blocks;
- buf->st_atime = kbuf->st_atime;
- buf->st_mtime = kbuf->st_mtime;
- buf->st_ctime = kbuf->st_ctime;
+ /* Convert to current kernel version of `struct stat'. */
+ buf->st_dev = kbuf->st_dev;
+ buf->st_ino = kbuf->st_ino;
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+#ifdef STAT_HAVE_NSEC
+ buf->st_atimensec = kbuf->st_atime_nsec;
+ buf->st_mtimensec = kbuf->st_mtime_nsec;
+ buf->st_ctimensec = kbuf->st_ctime_nsec;
+#endif
}
-#if defined __UCLIBC_HAS_LFS__
+#if defined(__UCLIBC_HAS_LFS__)
+
void __xstat64_conv(struct kernel_stat64 *kbuf, struct stat64 *buf)
{
- /* Convert to current kernel version of `struct stat64'. */
- buf->st_dev = kbuf->st_dev;
- buf->st_ino = kbuf->st_ino;
+ /* Convert to current kernel version of `struct stat64'. */
+ buf->st_dev = kbuf->st_dev;
+ buf->st_ino = kbuf->st_ino;
#ifdef _HAVE_STAT64___ST_INO
- buf->__st_ino = kbuf->__st_ino;
+ buf->__st_ino = kbuf->__st_ino;
#endif
- buf->st_mode = kbuf->st_mode;
- buf->st_nlink = kbuf->st_nlink;
- buf->st_uid = kbuf->st_uid;
- buf->st_gid = kbuf->st_gid;
- buf->st_rdev = kbuf->st_rdev;
- buf->st_size = kbuf->st_size;
- buf->st_blksize = kbuf->st_blksize;
- buf->st_blocks = kbuf->st_blocks;
- buf->st_atime = kbuf->st_atime;
- buf->st_mtime = kbuf->st_mtime;
- buf->st_ctime = kbuf->st_ctime;
-}
+ buf->st_mode = kbuf->st_mode;
+ buf->st_nlink = kbuf->st_nlink;
+ buf->st_uid = kbuf->st_uid;
+ buf->st_gid = kbuf->st_gid;
+ buf->st_rdev = kbuf->st_rdev;
+ buf->st_size = kbuf->st_size;
+ buf->st_blksize = kbuf->st_blksize;
+ buf->st_blocks = kbuf->st_blocks;
+ buf->st_atime = kbuf->st_atime;
+ buf->st_mtime = kbuf->st_mtime;
+ buf->st_ctime = kbuf->st_ctime;
+#ifdef STAT_HAVE_NSEC
+ buf->st_atimensec = kbuf->st_atime_nsec;
+ buf->st_mtimensec = kbuf->st_mtime_nsec;
+ buf->st_ctimensec = kbuf->st_ctime_nsec;
#endif
+}
+#endif /* __UCLIBC_HAS_LFS__ */
diff --git a/libc/sysdeps/linux/mips/__syscall_error.c b/libc/sysdeps/linux/mips/__syscall_error.c
index 9ab65ed79..de65a1f39 100644
--- a/libc/sysdeps/linux/mips/__syscall_error.c
+++ b/libc/sysdeps/linux/mips/__syscall_error.c
@@ -1,4 +1,4 @@
-/* Wrapper around clone system call.
+/* Wrapper for setting errno.
Copyright (C) 1997, 1998, 1999, 2000 Free Software Foundation, Inc.
This file is part of the GNU C Library.
@@ -18,12 +18,12 @@
02111-1307 USA. */
#include <errno.h>
+#include <features.h>
/* This routine is jumped to by all the syscall handlers, to stash
* an error number into errno. */
-int __syscall_error (int err_no)
+int attribute_hidden __syscall_error(int err_no)
{
- __set_errno (err_no);
+ __set_errno(err_no);
return -1;
}
-
diff --git a/libc/sysdeps/linux/mips/bits/msq.h b/libc/sysdeps/linux/mips/bits/msq.h
index c2c1dd2e8..2b0d38ec8 100644
--- a/libc/sysdeps/linux/mips/bits/msq.h
+++ b/libc/sysdeps/linux/mips/bits/msq.h
@@ -21,6 +21,7 @@
#endif
#include <bits/types.h>
+#include <bits/wordsize.h>
/* Define options for message queue functions. */
#define MSG_NOERROR 010000 /* no error if message is too big */
@@ -38,16 +39,34 @@ typedef unsigned long int msglen_t;
struct msqid_ds
{
struct ipc_perm msg_perm; /* structure describing operation permission */
+#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
+ unsigned long __unused1;
+#endif
__time_t msg_stime; /* time of last msgsnd command */
+#if (__WORDSIZE == 32) && defined(__MIPSEL__)
+ unsigned long __unused1;
+#endif
+#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
+ unsigned long __unused2;
+#endif
__time_t msg_rtime; /* time of last msgrcv command */
+#if (__WORDSIZE == 32) && defined(__MIPSEL__)
+ unsigned long __unused2;
+#endif
+#if (__WORDSIZE == 32) && !defined(__MIPSEL__)
+ unsigned long __unused3;
+#endif
__time_t msg_ctime; /* time of last change */
+#if (__WORDSIZE == 32) && defined(__MIPSEL__)
+ unsigned long __unused3;
+#endif
unsigned long int __msg_cbytes; /* current number of bytes on queue */
msgqnum_t msg_qnum; /* number of messages currently on queue */
msglen_t msg_qbytes; /* max number of bytes allowed on queue */
__pid_t msg_lspid; /* pid of last msgsnd() */
__pid_t msg_lrpid; /* pid of last msgrcv() */
- unsigned long int __unused1;
- unsigned long int __unused2;
+ unsigned long int __unused4;
+ unsigned long int __unused5;
};
#ifdef __USE_MISC
diff --git a/libc/sysdeps/linux/mips/bsd-setjmp.S b/libc/sysdeps/linux/mips/bsd-setjmp.S
index 51af9c891..49a904d29 100644
--- a/libc/sysdeps/linux/mips/bsd-setjmp.S
+++ b/libc/sysdeps/linux/mips/bsd-setjmp.S
@@ -34,8 +34,8 @@
.type setjmp,@function
setjmp:
-#ifdef __PIC__
.set noreorder
+#ifdef __PIC__
.cpload t9
.set reorder
la t9, __sigsetjmp
diff --git a/libc/sysdeps/linux/mips/clone.S b/libc/sysdeps/linux/mips/clone.S
index 3b879040a..079d2bef2 100644
--- a/libc/sysdeps/linux/mips/clone.S
+++ b/libc/sysdeps/linux/mips/clone.S
@@ -72,6 +72,11 @@ __clone:
/* Something bad happened -- no child created */
error:
addiu sp,32
+
+ /* uClibc change -- start */
+ move a0,v0 /* Pass return val to C function. */
+ /* uClibc change -- stop */
+
#ifdef __PIC__
la t9,__syscall_error
jr t9
diff --git a/utils/Makefile b/utils/Makefile
index 03a5cfc2d..dec011780 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -54,14 +54,14 @@ ldconfig: ldconfig.c
$(STRIPTOOL) -x -R .note -R .comment $@
ldd: ldd.c
- $(CC) $(CFLAGS) $(PIEFLAG) $(LDPIEFLAG) -Wl,-s \
+ $(CC) $(CFLAGS) $(PIEFLAG) -Wl,-s \
-DUCLIBC_RUNTIME_PREFIX=\"$(RUNTIME_PREFIX)\" \
-DUCLIBC_LDSO=$(UCLIBC_LDSO) -I. -I../ldso/include \
$^ -o $@
$(STRIPTOOL) -x -R .note -R .comment $@
iconv: ../libc/misc/wchar/wchar.c
- $(CC) $(CFLAGS) $(PIEFLAG) $(LDPIEFLAG) -Wl,-s \
+ $(CC) $(CFLAGS) $(PIEFLAG) -Wl,-s \
-DL_iconv_main \
$^ -o $@
$(STRIPTOOL) -x -R .note -R .comment $@