From fb02ec25e9058af056cfd77f8d071b8be1270642 Mon Sep 17 00:00:00 2001 From: Scott Turner Date: Sat, 16 Jan 2010 10:23:18 -0500 Subject: [PATCH 1/6] Reversed order of const and static to hush warning from compiler. --- libm/bsdsrc/b_exp.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libm/bsdsrc/b_exp.c b/libm/bsdsrc/b_exp.c index 32873b98f..107bc8929 100644 --- a/libm/bsdsrc/b_exp.c +++ b/libm/bsdsrc/b_exp.c @@ -76,16 +76,16 @@ static char sccsid[] = "@(#)exp.c 8.1 (Berkeley) 6/4/93"; #include "mathimpl.h" -const static double p1 = 0x1.555555555553ep-3; -const static double p2 = -0x1.6c16c16bebd93p-9; -const static double p3 = 0x1.1566aaf25de2cp-14; -const static double p4 = -0x1.bbd41c5d26bf1p-20; -const static double p5 = 0x1.6376972bea4d0p-25; -const static double ln2hi = 0x1.62e42fee00000p-1; -const static double ln2lo = 0x1.a39ef35793c76p-33; -const static double lnhuge = 0x1.6602b15b7ecf2p9; -const static double lntiny = -0x1.77af8ebeae354p9; -const static double invln2 = 0x1.71547652b82fep0; +static const double p1 = 0x1.555555555553ep-3; +static const double p2 = -0x1.6c16c16bebd93p-9; +static const double p3 = 0x1.1566aaf25de2cp-14; +static const double p4 = -0x1.bbd41c5d26bf1p-20; +static const double p5 = 0x1.6376972bea4d0p-25; +static const double ln2hi = 0x1.62e42fee00000p-1; +static const double ln2lo = 0x1.a39ef35793c76p-33; +static const double lnhuge = 0x1.6602b15b7ecf2p9; +static const double lntiny = -0x1.77af8ebeae354p9; +static const double invln2 = 0x1.71547652b82fep0; #if 0 double exp(x) From 72d3489612b77d4544e500a2a2a1783914ee56b7 Mon Sep 17 00:00:00 2001 From: Scott Turner Date: Sat, 16 Jan 2010 10:39:00 -0500 Subject: [PATCH 2/6] Reduce compiler anxiety. Warning from compiler: target arm C: libm <= bionic/libm/src/e_atan2.c bionic/libm/src/e_atan2.c: In function 'atan2': bionic/libm/src/e_atan2.c:71: warning: suggest parentheses around arithmetic in operand of '|' target arm C: libm <= bionic/libm/src/e_atan2f.c --- libm/src/e_atan2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libm/src/e_atan2.c b/libm/src/e_atan2.c index 073f81b4c..56c05a5d9 100644 --- a/libm/src/e_atan2.c +++ b/libm/src/e_atan2.c @@ -68,7 +68,7 @@ __ieee754_atan2(double y, double x) if(((ix|((lx|-lx)>>31))>0x7ff00000)|| ((iy|((ly|-ly)>>31))>0x7ff00000)) /* x or y is NaN */ return x+y; - if((hx-0x3ff00000|lx)==0) return atan(y); /* x=1.0 */ + if(((hx-0x3ff00000) | lx)==0) return atan(y); /* x=1.0 */ m = ((hy>>31)&1)|((hx>>30)&2); /* 2*sign(x)+sign(y) */ /* when y = 0 */ From aba3ee7d322f30735433e2e6ae98fa3d849a1c7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Goddard=20Rosa?= Date: Sat, 30 Jan 2010 22:29:59 -0200 Subject: [PATCH 3/6] string: tidy up strndup() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It decreases code size: text data bss dec hex filename 161 0 0 161 a1 strndup-BEFORE.o 153 0 0 153 99 strndup-AFTER.o Signed-off-by: André Goddard Rosa --- libc/string/strndup.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/libc/string/strndup.c b/libc/string/strndup.c index da9a55f45..9dca79c43 100644 --- a/libc/string/strndup.c +++ b/libc/string/strndup.c @@ -31,12 +31,14 @@ char* strndup(const char* s, size_t n) { size_t slen = (size_t)strlen(s); - int len = slen < n ? slen : n; - char* copy = malloc(len+1); + char* copy; + if (slen < n) + n = slen; + copy = malloc(n+1); if (copy) { - memcpy( copy, s, len ); - copy[len] = 0; + memcpy(copy, s, n); + copy[n] = 0; } return copy; } From c1f8dd9f0b0fe4d3953edefd2d6172573f6b7504 Mon Sep 17 00:00:00 2001 From: Scott Turner Date: Sat, 16 Jan 2010 11:30:44 -0500 Subject: [PATCH 4/6] Sometimes the compiler is very right! Found bug in bessel routines for float. Original compiler error: target arm C: libm <= bionic/libm/src/e_j0f.c bionic/libm/src/e_j0f.c: In function 'j0f': bionic/libm/src/e_j0f.c:66: warning: comparison between signed and unsigned integer expressions bionic/libm/src/e_j0f.c: In function 'y0f': bionic/libm/src/e_j0f.c:140: warning: comparison between signed and unsigned integer expressions target arm C: libm <= bionic/libm/src/e_j1.c It's subtle but ix is masked with 0x7f000000 so it can never ever have a value greater than 0x80000000. So I switched to using the unmasked hx and added a cast as a reward to the compiler for being right. I checked the original routines that e_j0f.c was ported from (in e_j0.c) and the double's don't use 0x80000000 so this issue didn't exist there. Let that be a warning to those that just slap on casts to shut up the compiler, sometimes it's sniffed out a bug for you. :-) Similar fixes in the other functions. Change-Id: I7a776e5d4721fc3a9e3bd89179b67e9af3a2ebfa --- libm/src/e_j0f.c | 7 ++++--- libm/src/e_j1f.c | 3 ++- libm/src/e_jnf.c | 2 +- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libm/src/e_j0f.c b/libm/src/e_j0f.c index b872406bb..6b566bf91 100644 --- a/libm/src/e_j0f.c +++ b/libm/src/e_j0f.c @@ -1,5 +1,6 @@ /* e_j0f.c -- float version of e_j0.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Bugs in __ieee754_j0f and __ieee754_y0f fixed by Scott Turner 01/16/2010 */ /* @@ -63,7 +64,7 @@ __ieee754_j0f(float x) * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ - if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(x); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*cc)/sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*cc-v*ss)/sqrtf(x); @@ -107,7 +108,7 @@ __ieee754_y0f(float x) int32_t hx,ix; GET_FLOAT_WORD(hx,x); - ix = 0x7fffffff&hx; + ix = hx&0x7fffffff; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ if(ix>=0x7f800000) return one/(x+x*x); if(ix==0) return -one/zero; @@ -137,7 +138,7 @@ __ieee754_y0f(float x) if ((s*c)0x80000000) z = (invsqrtpi*ss)/sqrtf(x); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*ss)/sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*ss+v*cc)/sqrtf(x); diff --git a/libm/src/e_j1f.c b/libm/src/e_j1f.c index 539399e4f..ea057748d 100644 --- a/libm/src/e_j1f.c +++ b/libm/src/e_j1f.c @@ -1,5 +1,6 @@ /* e_j1f.c -- float version of e_j1.c. * Conversion to float by Ian Lance Taylor, Cygnus Support, ian@cygnus.com. + * Bug in __ieee754_j1f fixed by Scott Turner 1/16/2010 */ /* @@ -64,7 +65,7 @@ __ieee754_j1f(float x) * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x) * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x) */ - if(ix>0x80000000) z = (invsqrtpi*cc)/sqrtf(y); + if(((uint32_t)hx)>0x80000000) z = (invsqrtpi*cc)/sqrtf(y); else { u = ponef(y); v = qonef(y); z = invsqrtpi*(u*cc-v*ss)/sqrtf(y); diff --git a/libm/src/e_jnf.c b/libm/src/e_jnf.c index 029dba65b..a61fb6817 100644 --- a/libm/src/e_jnf.c +++ b/libm/src/e_jnf.c @@ -186,7 +186,7 @@ __ieee754_ynf(int n, float x) b = __ieee754_y1f(x); /* quit if b is -inf */ GET_FLOAT_WORD(ib,b); - for(i=1;i Date: Thu, 31 Dec 2009 12:09:10 -0600 Subject: [PATCH 5/6] Added support for LD_PRELOAD The LD_PRELOAD environment variable allows the user to specify a list of libraries which should be unconditionally loaded before any others. This makes possible some useful tricks, such as library interposers. Change-Id: I433d775ab08ef63a5fbe7b21f87a5642954fc32f --- linker/linker.c | 65 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/linker/linker.c b/linker/linker.c index 451e96c2b..8dde9410b 100644 --- a/linker/linker.c +++ b/linker/linker.c @@ -58,6 +58,9 @@ #define LDPATH_BUFSIZE 512 #define LDPATH_MAX 8 +#define LDPRELOAD_BUFSIZE 512 +#define LDPRELOAD_MAX 8 + /* >>> IMPORTANT NOTE - READ ME BEFORE MODIFYING <<< * * Do NOT use malloc() and friends or pthread_*() code here. @@ -112,6 +115,11 @@ static inline int validate_soinfo(soinfo *si) static char ldpaths_buf[LDPATH_BUFSIZE]; static const char *ldpaths[LDPATH_MAX + 1]; +static char ldpreloads_buf[LDPRELOAD_BUFSIZE]; +static const char *ldpreload_names[LDPRELOAD_MAX + 1]; + +static soinfo *preloads[LDPRELOAD_MAX + 1]; + int debug_verbosity; static int pid; @@ -451,6 +459,7 @@ _do_lookup(soinfo *si, const char *name, unsigned *base) Elf32_Sym *s; unsigned *d; soinfo *lsi = si; + int i; /* Look for symbols in the local scope first (the object who is * searching). This happens with C++ templates on i386 for some @@ -459,6 +468,14 @@ _do_lookup(soinfo *si, const char *name, unsigned *base) if(s != NULL) goto done; + /* Next, look for it in the preloads list */ + for(i = 0; preloads[i] != NULL; i++) { + lsi = preloads[i]; + s = _do_lookup_in_so(lsi, name, &elf_hash); + if(s != NULL) + goto done; + } + for(d = si->dynamic; *d; d += 2) { if(d[0] == DT_NEEDED){ lsi = (soinfo *)d[1]; @@ -1866,6 +1883,23 @@ static int link_image(soinfo *si, unsigned wr_offset) goto fail; } + /* if this is the main executable, then load all of the preloads now */ + if(si->flags & FLAG_EXE) { + int i; + memset(preloads, 0, sizeof(preloads)); + for(i = 0; ldpreload_names[i] != NULL; i++) { + soinfo *lsi = find_library(ldpreload_names[i]); + if(lsi == 0) { + strlcpy(tmp_err_buf, linker_get_error(), sizeof(tmp_err_buf)); + DL_ERR("%5d could not load needed library '%s' for '%s' (%s)", + pid, ldpreload_names[i], si->name, tmp_err_buf); + goto fail; + } + lsi->refcount++; + preloads[i] = lsi; + } + } + for(d = si->dynamic; *d; d += 2) { if(d[0] == DT_NEEDED){ DEBUG("%5d %s needs %s\n", pid, si->name, si->strtab + d[1]); @@ -1982,6 +2016,30 @@ static void parse_library_path(char *path, char *delim) } } +static void parse_preloads(char *path, char *delim) +{ + size_t len; + char *ldpreloads_bufp = ldpreloads_buf; + int i = 0; + + len = strlcpy(ldpreloads_buf, path, sizeof(ldpreloads_buf)); + + while (i < LDPRELOAD_MAX && (ldpreload_names[i] = strsep(&ldpreloads_bufp, delim))) { + if (*ldpreload_names[i] != '\0') { + ++i; + } + } + + /* Forget the last path if we had to truncate; this occurs if the 2nd to + * last char isn't '\0' (i.e. not originally a delim). */ + if (i > 0 && len >= sizeof(ldpreloads_buf) && + ldpreloads_buf[sizeof(ldpreloads_buf) - 2] != '\0') { + ldpreload_names[i - 1] = NULL; + } else { + ldpreload_names[i] = NULL; + } +} + int main(int argc, char **argv) { return 0; @@ -2001,6 +2059,7 @@ unsigned __linker_init(unsigned **elfdata) soinfo *si; struct link_map * map; char *ldpath_env = NULL; + char *ldpreload_env = NULL; /* Setup a temporary TLS area that is used to get a working * errno for system calls. @@ -2032,6 +2091,8 @@ unsigned __linker_init(unsigned **elfdata) debug_verbosity = atoi(((char*) vecs[0]) + 6); } else if(!strncmp((char*) vecs[0], "LD_LIBRARY_PATH=", 16)) { ldpath_env = (char*) vecs[0] + 16; + } else if(!strncmp((char*) vecs[0], "LD_PRELOAD=", 11)) { + ldpreload_env = (char*) vecs[0] + 11; } vecs++; } @@ -2095,6 +2156,10 @@ unsigned __linker_init(unsigned **elfdata) if (ldpath_env && getuid() == geteuid() && getgid() == getegid()) parse_library_path(ldpath_env, ":"); + if (ldpreload_env && getuid() == geteuid() && getgid() == getegid()) { + parse_preloads(ldpreload_env, " :"); + } + if(link_image(si, 0)) { char errmsg[] = "CANNOT LINK EXECUTABLE\n"; write(2, __linker_dl_err_buf, strlen(__linker_dl_err_buf)); From 051ea9bc07809a2638e5f022ae10330e23530f64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Goddard=20Rosa?= Date: Sat, 30 Jan 2010 22:45:07 -0200 Subject: [PATCH 6/6] stdio: simplify __fremovelock() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ... by removing extraneous NULL check, as free() already does it. Signed-off-by: André Goddard Rosa Change-Id: I0445f35c7ad0a049a0e4aee1fbe002ed2f13b94b --- libc/stdio/flockfile.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libc/stdio/flockfile.c b/libc/stdio/flockfile.c index a81879efc..bfb081cde 100644 --- a/libc/stdio/flockfile.c +++ b/libc/stdio/flockfile.c @@ -205,8 +205,6 @@ __fremovelock(FILE* fp) lock->file = NULL; } lock_table_unlock(t); - - if (lock != NULL) - free(lock); + free(lock); } }