diff options
51 files changed, 452 insertions, 634 deletions
diff --git a/.gitignore b/.gitignore index 5a5ea87a5..415166b7e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ *.pyc *.*~ -libc/kernel/original diff --git a/docs/fdsan.md b/docs/fdsan.md index 0e6783de1..e0cf80ab2 100644 --- a/docs/fdsan.md +++ b/docs/fdsan.md @@ -2,6 +2,8 @@ [TOC] +fdsan is a file descriptor sanitizer added to Android in API level 29. + ### Background *What problem is fdsan trying to solve? Why should I care?* diff --git a/docs/fdtrack.md b/docs/fdtrack.md index 5bc98602d..7cf6e1fe5 100644 --- a/docs/fdtrack.md +++ b/docs/fdtrack.md @@ -1,5 +1,9 @@ ## fdtrack +[TOC] + +fdtrack is a file descriptor leak checker added to Android in API level 30. + fdtrack consists of two parts: a set of hooks in bionic to register a callback that's invoked on file descriptor operations, and a library that implements a hook to perform and store backtraces for file descriptor creation. diff --git a/libc/Android.bp b/libc/Android.bp index 16f1af32b..5b31104da 100644 --- a/libc/Android.bp +++ b/libc/Android.bp @@ -89,6 +89,7 @@ cc_defaults { header_libs: [ "libc_headers", "gwp_asan_headers", + "liblog_headers", // needed by bionic/libc/async_safe/include ], export_header_lib_headers: [ "libc_headers", @@ -274,7 +275,7 @@ cc_library_static { defaults: ["libc_defaults"], srcs: [ - "dns/**/*.c", + "dns/**/*.c*", "upstream-netbsd/lib/libc/isc/ev_streams.c", "upstream-netbsd/lib/libc/isc/ev_timers.c", @@ -2329,9 +2330,9 @@ llndk_library { export_preprocessed_headers: ["include"], native_bridge_supported: true, export_include_dirs: [ + "kernel/uapi", "kernel/android/scsi", "kernel/android/uapi", - "kernel/uapi", ], arch: { arm: { diff --git a/libc/dns/include/resolv_private.h b/libc/dns/include/resolv_private.h index 77b03bfe0..305455597 100644 --- a/libc/dns/include/resolv_private.h +++ b/libc/dns/include/resolv_private.h @@ -51,8 +51,7 @@ * Id: resolv.h,v 1.7.2.11.4.2 2004/06/25 00:41:05 marka Exp */ -#ifndef _RESOLV_PRIVATE_H_ -#define _RESOLV_PRIVATE_H_ +#pragma once #include <sys/cdefs.h> @@ -63,6 +62,8 @@ #include <net/if.h> #include <time.h> +__BEGIN_DECLS + // Linux defines MAXHOSTNAMELEN as 64, while the domain name limit in // RFC 1034 and RFC 1035 is 255 octets. #ifdef MAXHOSTNAMELEN @@ -293,8 +294,6 @@ union res_sockaddr_union { /* 0x00010000 */ /* Things involving an internal (static) resolver context. */ -__BEGIN_DECLS - __LIBC_HIDDEN__ extern struct __res_state *__res_get_state(void); __LIBC_HIDDEN__ extern void __res_put_state(struct __res_state *); @@ -307,8 +306,6 @@ extern struct __res_state *__res_state(void); #define _res (*__res_state()) #endif -__END_DECLS - #ifndef __BIND_NOSTATIC #define fp_nquery __fp_nquery #define fp_query __fp_query @@ -319,7 +316,6 @@ __END_DECLS #define res_isourserver __res_isourserver #define res_querydomain __res_querydomain #define res_send __res_send -#define res_sendsigned __res_sendsigned #ifdef BIND_RES_POSIX3 #define dn_expand __dn_expand @@ -329,7 +325,6 @@ __END_DECLS #define res_mkquery __res_mkquery #endif -__BEGIN_DECLS void fp_nquery(const u_char *, int, FILE *); void fp_query(const u_char *, FILE *); const char * hostalias(const char *); @@ -343,8 +338,6 @@ int res_query(const char *, int, int, u_char *, int); int res_querydomain(const char *, const char *, int, int, u_char *, int); int res_search(const char *, int, int, u_char *, int); int res_send(const u_char *, int, u_char *, int); -int res_sendsigned(const u_char *, int, ns_tsig_key *, u_char *, int); -__END_DECLS #endif #if !defined(SHARED_LIBBIND) || defined(LIB) @@ -424,7 +417,6 @@ __LIBC_HIDDEN__ extern const struct res_sym __p_rcode_syms[]; #define res_send_setrhook __res_send_setrhook #define res_servicename __res_servicename #define res_servicenumber __res_servicenumber -__BEGIN_DECLS int res_hnok(const char *); int res_ownok(const char *); int res_mailok(const char *); @@ -532,5 +524,3 @@ int ns_name_map(ns_nname_ct, size_t, ns_namemap_t, int); int ns_name_labels(ns_nname_ct, size_t); __END_DECLS - -#endif /* !_RESOLV_PRIVATE_H_ */ diff --git a/libc/dns/include/resolv_static.h b/libc/dns/include/resolv_static.h index 8f2a095c5..83a435a7c 100644 --- a/libc/dns/include/resolv_static.h +++ b/libc/dns/include/resolv_static.h @@ -1,7 +1,7 @@ -#ifndef _RESOLV_STATIC_H -#define _RESOLV_STATIC_H +#pragma once #include <netdb.h> +#include <sys/cdefs.h> /* this structure contains all the variables that were declared * 'static' in the original NetBSD resolver code. @@ -15,18 +15,20 @@ #define MAXALIASES 35 #define MAXADDRS 35 -typedef struct res_static { - char* h_addr_ptrs[MAXADDRS + 1]; - char* host_aliases[MAXALIASES]; - char hostbuf[8*1024]; - u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */ - FILE* hostf; - int stayopen; - const char* servent_ptr; - struct servent servent; - struct hostent host; -} *res_static; +__BEGIN_DECLS -extern res_static __res_get_static(void); +struct res_static { + char* h_addr_ptrs[MAXADDRS + 1]; + char* host_aliases[MAXALIASES]; + char hostbuf[8 * 1024]; + u_int32_t host_addr[16 / sizeof(u_int32_t)]; /* IPv4 or IPv6 */ + FILE* hostf; + int stayopen; + const char* servent_ptr; + struct servent servent; + struct hostent host; +}; -#endif /* _RESOLV_STATIC_H */ +struct res_static* __res_get_static(void); + +__END_DECLS diff --git a/libc/dns/net/gethnamaddr.c b/libc/dns/net/gethnamaddr.c index f8212a295..add124f52 100644 --- a/libc/dns/net/gethnamaddr.c +++ b/libc/dns/net/gethnamaddr.c @@ -1537,7 +1537,7 @@ struct hostent * gethostbyname(const char *name) { struct hostent *result = NULL; - res_static rs = __res_get_static(); /* Use res_static to provide thread-safety. */ + struct res_static* rs = __res_get_static(); gethostbyname_r(name, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &result, &h_errno); return result; @@ -1547,7 +1547,7 @@ struct hostent * gethostbyname2(const char *name, int af) { struct hostent *result = NULL; - res_static rs = __res_get_static(); /* Use res_static to provide thread-safety. */ + struct res_static* rs = __res_get_static(); gethostbyname2_r(name, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &result, &h_errno); return result; @@ -1583,7 +1583,7 @@ android_gethostbynamefornetcontext(const char *name, int af, res_state res = __res_get_state(); if (res == NULL) return NULL; - res_static rs = __res_get_static(); /* Use res_static to provide thread-safety. */ + struct res_static* rs = __res_get_static(); hp = gethostbyname_internal(name, af, res, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &h_errno, netcontext); __res_put_state(res); @@ -1615,7 +1615,7 @@ __LIBC_HIDDEN__ struct hostent* android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af, const struct android_net_context *netcontext) { - res_static rs = __res_get_static(); /* Use res_static to provide thread-safety. */ + struct res_static* rs = __res_get_static(); return android_gethostbyaddrfornetcontext_proxy_internal(addr, len, af, &rs->host, rs->hostbuf, sizeof(rs->hostbuf), &h_errno, netcontext); } @@ -1623,7 +1623,7 @@ android_gethostbyaddrfornetcontext_proxy(const void* addr, socklen_t len, int af struct hostent * gethostent(void) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (!rs->hostf) { sethostent_r(&rs->hostf); if (!rs->hostf) { diff --git a/libc/dns/net/getservent.c b/libc/dns/net/getservent.c index 03add59eb..6a50d23ce 100644 --- a/libc/dns/net/getservent.c +++ b/libc/dns/net/getservent.c @@ -35,7 +35,7 @@ #include "resolv_static.h" #include "services.h" -struct servent* getservent_r(res_static rs) { +struct servent* getservent_r(struct res_static* rs) { const char* p; const char* q; int namelen; @@ -109,17 +109,17 @@ void setservent(int stayopen) { } void endservent(void) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (rs) rs->servent_ptr = NULL; } struct servent* getservent(void) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); return rs ? getservent_r(rs) : NULL; } struct servent* getservbyname(const char* name, const char* proto) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (rs == NULL) return NULL; const char* old_servent_ptr = rs->servent_ptr; @@ -135,7 +135,7 @@ struct servent* getservbyname(const char* name, const char* proto) { } struct servent* getservbyport(int port, const char* proto) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (rs == NULL) return NULL; const char* old_servent_ptr = rs->servent_ptr; diff --git a/libc/dns/net/sethostent.c b/libc/dns/net/sethostent.c index b2b0132c5..483105a95 100644 --- a/libc/dns/net/sethostent.c +++ b/libc/dns/net/sethostent.c @@ -65,14 +65,14 @@ void /*ARGSUSED*/ sethostent(int stayopen) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (rs) sethostent_r(&rs->hostf); } void endhostent(void) { - res_static rs = __res_get_static(); + struct res_static* rs = __res_get_static(); if (rs) endhostent_r(&rs->hostf); } diff --git a/libc/dns/resolv/res_data.c b/libc/dns/resolv/res_data.c deleted file mode 100644 index 4f8df6930..000000000 --- a/libc/dns/resolv/res_data.c +++ /dev/null @@ -1,295 +0,0 @@ -/* $NetBSD: res_data.c,v 1.8 2004/06/09 18:07:03 christos Exp $ */ - -/* - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1995-1999 by Internet Software Consortium. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <sys/cdefs.h> -#if defined(LIBC_SCCS) && !defined(lint) -#ifdef notdef -static const char rcsid[] = "Id: res_data.c,v 1.1.206.2 2004/03/16 12:34:18 marka Exp"; -#else -__RCSID("$NetBSD: res_data.c,v 1.8 2004/06/09 18:07:03 christos Exp $"); -#endif -#endif /* LIBC_SCCS and not lint */ - - - -#include <sys/types.h> -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/time.h> - -#include <netinet/in.h> -#include <arpa/inet.h> -#include <arpa/nameser.h> - -#include <ctype.h> -#include <netdb.h> -#include "resolv_private.h" -#include <pthread.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <unistd.h> - - -__LIBC_HIDDEN__ -const char * const _res_opcodes[] = { - "QUERY", - "IQUERY", - "CQUERYM", - "CQUERYU", /* experimental */ - "NOTIFY", /* experimental */ - "UPDATE", - "6", - "7", - "8", - "9", - "10", - "11", - "12", - "13", - "ZONEINIT", - "ZONEREF", -}; - -#ifdef BIND_UPDATE -const char * const _res_sectioncodes[] = { - "ZONE", - "PREREQUISITES", - "UPDATE", - "ADDITIONAL", -}; -#endif - -#ifndef __BIND_NOSTATIC -extern struct __res_state _nres; - -/* Proto. */ - -int res_ourserver_p(const res_state, const struct sockaddr *); - -static pthread_once_t once_control = PTHREAD_ONCE_INIT; - -static void init_once(void) { - extern int __res_vinit(res_state, int); -#ifdef COMPAT__RES - /* - * Compatibility with program that were accessing _res directly - * to set options. We keep another struct res that is the same - * size as the original res structure, and then copy fields to - * it so that we achieve the same initialization - */ - extern void *__res_get_old_state(void); - extern void __res_put_old_state(void *); - res_state ores = __res_get_old_state(); - - if (ores->options != 0) - _nres.options = ores->options; - if (ores->retrans != 0) - _nres.retrans = ores->retrans; - if (ores->retry != 0) - _nres.retry = ores->retry; -#endif - - /* - * These three fields used to be statically initialized. This made - * it hard to use this code in a shared library. It is necessary, - * now that we're doing dynamic initialization here, that we preserve - * the old semantics: if an application modifies one of these three - * fields of _res before res_init() is called, res_init() will not - * alter them. Of course, if an application is setting them to - * _zero_ before calling res_init(), hoping to override what used - * to be the static default, we can't detect it and unexpected results - * will follow. Zero for any of these fields would make no sense, - * so one can safely assume that the applications were already getting - * unexpected results. - * - * _nres.options is tricky since some apps were known to diddle the bits - * before res_init() was first called. We can't replicate that semantic - * with dynamic initialization (they may have turned bits off that are - * set in RES_DEFAULT). Our solution is to declare such applications - * "broken". They could fool us by setting RES_INIT but none do (yet). - */ - if (!_nres.retrans) - _nres.retrans = RES_TIMEOUT; - if (!_nres.retry) - _nres.retry = 4; - if (!(_nres.options & RES_INIT)) - _nres.options = RES_DEFAULT; - - /* - * This one used to initialize implicitly to zero, so unless the app - * has set it to something in particular, we can randomize it now. - */ - if (!_nres.id) - _nres.id = res_randomid(); - - __res_vinit(&_nres, 1); -#ifdef COMPAT__RES - __res_put_old_state(&_nres); -#endif -} - -int -res_init(void) { - pthread_once(&once_control, init_once); - return 0; -} - -static res_state get_static_res_state() { - pthread_once(&once_control, init_once); - return &_nres; -} - -void -p_query(const u_char *msg) { - fp_query(msg, stdout); -} - -void -fp_query(const u_char *msg, FILE *file) { - fp_nquery(msg, PACKETSZ, file); -} - -void -fp_nquery(const u_char *msg, int len, FILE *file) { - res_pquery(get_static_res_state(), msg, len, file); -} - -int -res_mkquery(int op, /* opcode of query */ - const char *dname, /* domain name */ - int class, int type, /* class and type of query */ - const u_char *data, /* resource record data */ - int datalen, /* length of data */ - const u_char *newrr_in, /* new rr for modify or append */ - u_char *buf, /* buffer to put query */ - int buflen) /* size of buffer */ -{ - return (res_nmkquery(get_static_res_state(), op, dname, class, type, - data, datalen, - newrr_in, buf, buflen)); -} - -#ifdef _LIBRESOLV -int -res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) { - return (res_nmkupdate(get_static_res_state(), rrecp_in, buf, buflen)); -} -#endif - -int -res_query(const char *name, /* domain name */ - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen) /* size of answer buffer */ -{ - return (res_nquery(get_static_res_state(), name, class, type, answer, anslen)); -} - -void -res_send_setqhook(res_send_qhook hook) { - _nres.qhook = hook; -} - -void -res_send_setrhook(res_send_rhook hook) { - _nres.rhook = hook; -} - -int -res_isourserver(const struct sockaddr_in *inp) { - return (res_ourserver_p(&_nres, (const struct sockaddr *)(const void *)inp)); -} - -int -res_send(const u_char *buf, int buflen, u_char *ans, int anssiz) { - return (res_nsend(get_static_res_state(), buf, buflen, ans, anssiz)); -} - -#ifdef _LIBRESOLV -int -res_sendsigned(const u_char *buf, int buflen, ns_tsig_key *key, - u_char *ans, int anssiz) -{ - return (res_nsendsigned(get_static_res_state(), buf, buflen, key, ans, anssiz)); -} -#endif - -void -res_close(void) { - res_nclose(&_nres); -} - -#ifdef _LIBRESOLV -int -res_update(ns_updrec *rrecp_in) { - return (res_nupdate(get_static_res_state(), rrecp_in, NULL)); -} -#endif - -int -res_search(const char *name, /* domain name */ - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen) /* size of answer */ -{ - return (res_nsearch(get_static_res_state(), name, class, type, answer, anslen)); -} - -int -res_querydomain(const char *name, - const char *domain, - int class, int type, /* class and type of query */ - u_char *answer, /* buffer to put answer */ - int anslen) /* size of answer */ -{ - return (res_nquerydomain(get_static_res_state(), name, domain, - class, type, - answer, anslen)); -} - -int -res_opt(int a, u_char *b, int c, int d) -{ - return res_nopt(&_nres, a, b, c, d); -} - -const char * -hostalias(const char *name) { - return NULL; -} - -#ifdef ultrix -int -local_hostname_length(const char *hostname) { - int len_host, len_domain; - - if (!*_nres.defdname) - res_init(); - len_host = strlen(hostname); - len_domain = strlen(_nres.defdname); - if (len_host > len_domain && - !strcasecmp(hostname + len_host - len_domain, _nres.defdname) && - hostname[len_host - len_domain - 1] == '.') - return (len_host - len_domain - 1); - return (0); -} -#endif /*ultrix*/ - -#endif diff --git a/libc/dns/resolv/res_data.cpp b/libc/dns/resolv/res_data.cpp new file mode 100644 index 000000000..22d9f7b16 --- /dev/null +++ b/libc/dns/resolv/res_data.cpp @@ -0,0 +1,157 @@ +/* $NetBSD: res_data.c,v 1.8 2004/06/09 18:07:03 christos Exp $ */ + +/* + * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") + * Copyright (c) 1995-1999 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT + * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include "resolv_private.h" + +#include <pthread.h> + +extern "C" int res_ourserver_p(const res_state, const struct sockaddr*); +extern "C" int __res_vinit(res_state, int); + +class GlobalStateAccessor { + public: + GlobalStateAccessor() { + pthread_mutex_lock(&mutex); + if (!initialized) { + init(); + initialized = true; + } + } + + ~GlobalStateAccessor() { + pthread_mutex_unlock(&mutex); + } + + __res_state* get() { + return &state; + } + + int init(); + + private: + static __res_state state; + static bool initialized; + static pthread_mutex_t mutex; +}; +__res_state GlobalStateAccessor::state; +bool GlobalStateAccessor::initialized = false; +pthread_mutex_t GlobalStateAccessor::mutex = PTHREAD_MUTEX_INITIALIZER; + +int GlobalStateAccessor::init() { + // These three fields used to be statically initialized. This made + // it hard to use this code in a shared library. It is necessary, + // now that we're doing dynamic initialization here, that we preserve + // the old semantics: if an application modifies one of these three + // fields of _res before res_init() is called, res_init() will not + // alter them. Of course, if an application is setting them to + // _zero_ before calling res_init(), hoping to override what used + // to be the static default, we can't detect it and unexpected results + // will follow. Zero for any of these fields would make no sense, + // so one can safely assume that the applications were already getting + // unexpected results. + // g_nres.options is tricky since some apps were known to diddle the bits + // before res_init() was first called. We can't replicate that semantic + // with dynamic initialization (they may have turned bits off that are + // set in RES_DEFAULT). Our solution is to declare such applications + // "broken". They could fool us by setting RES_INIT but none do (yet). + if (!state.retrans) state.retrans = RES_TIMEOUT; + if (!state.retry) state.retry = 4; + if (!(state.options & RES_INIT)) state.options = RES_DEFAULT; + + // This one used to initialize implicitly to zero, so unless the app + // has set it to something in particular, we can randomize it now. + if (!state.id) state.id = res_randomid(); + + return __res_vinit(&state, 1); +} + +int res_init(void) { + GlobalStateAccessor gsa; + return gsa.init(); +} + +void p_query(const u_char* msg) { + fp_query(msg, stdout); +} + +void fp_query(const u_char* msg, FILE* file) { + fp_nquery(msg, PACKETSZ, file); +} + +void fp_nquery(const u_char* msg, int len, FILE* file) { + GlobalStateAccessor gsa; + res_pquery(gsa.get(), msg, len, file); +} + +int +res_mkquery(int op, const char* dname, int klass, int type, const u_char* data, + int datalen, const u_char* newrr_in, u_char* buf, int buflen) { + GlobalStateAccessor gsa; + return res_nmkquery(gsa.get(), op, dname, klass, type, data, datalen, newrr_in, buf, buflen); +} + +int res_query(const char* name, int klass, int type, u_char* answer, int anslen) { + GlobalStateAccessor gsa; + return res_nquery(gsa.get(), name, klass, type, answer, anslen); +} + +void res_send_setqhook(res_send_qhook hook) { + GlobalStateAccessor gsa; + gsa.get()->qhook = hook; +} + +void res_send_setrhook(res_send_rhook hook) { + GlobalStateAccessor gsa; + gsa.get()->rhook = hook; +} + +int res_isourserver(const struct sockaddr_in* inp) { + GlobalStateAccessor gsa; + return res_ourserver_p(gsa.get(), reinterpret_cast<const sockaddr*>(inp)); +} + +int res_send(const u_char* buf, int buflen, u_char* ans, int anssiz) { + GlobalStateAccessor gsa; + return res_nsend(gsa.get(), buf, buflen, ans, anssiz); +} + +void res_close(void) { + GlobalStateAccessor gsa; + res_nclose(gsa.get()); +} + +int res_search(const char* name, int klass, int type, u_char* answer, int anslen) { + GlobalStateAccessor gsa; + return res_nsearch(gsa.get(), name, klass, type, answer, anslen); +} + +int res_querydomain(const char* name, const char* domain, int klass, int type, u_char* answer, + int anslen) { + GlobalStateAccessor gsa; + return res_nquerydomain(gsa.get(), name, domain, klass, type, answer, anslen); +} + +int res_opt(int a, u_char* b, int c, int d) { + GlobalStateAccessor gsa; + return res_nopt(gsa.get(), a, b, c, d); +} + +const char* hostalias(const char* name) { + return NULL; +} diff --git a/libc/dns/resolv/res_debug.c b/libc/dns/resolv/res_debug.c index 5f889cb23..4fe75534d 100644 --- a/libc/dns/resolv/res_debug.c +++ b/libc/dns/resolv/res_debug.c @@ -126,9 +126,27 @@ __RCSID("$NetBSD: res_debug.c,v 1.13 2012/06/25 22:32:45 abs Exp $"); #include <strings.h> #include <time.h> -extern const char * const _res_opcodes[]; extern const char * const _res_sectioncodes[]; +__LIBC_HIDDEN__ const char* const _res_opcodes[] = { + "QUERY", + "IQUERY", + "CQUERYM", + "CQUERYU", /* experimental */ + "NOTIFY", /* experimental */ + "UPDATE", + "6", + "7", + "8", + "9", + "10", + "11", + "12", + "13", + "ZONEINIT", + "ZONEREF", +}; + #ifndef _LIBC /* * Print the current options. diff --git a/libc/dns/resolv/res_state.c b/libc/dns/resolv/res_state.c index 94124ff9b..d1f5c248f 100644 --- a/libc/dns/resolv/res_state.c +++ b/libc/dns/resolv/res_state.c @@ -68,7 +68,7 @@ _res_thread_alloc(void) } static void -_res_static_done( res_static rs ) +_res_static_done(struct res_static* rs) { /* fortunately, there is nothing to do here, since the * points in h_addr_ptrs and host_aliases should all @@ -135,25 +135,6 @@ _res_thread_get(void) return rt; } -__LIBC_HIDDEN__ -struct __res_state _nres; - -#if 0 -struct resolv_cache* -__get_res_cache(void) -{ - _res_thread* rt = _res_thread_get(); - - if (!rt) - return NULL; - - if (!rt->_cache) { - rt->_cache = _resolv_cache_create(); - } - return rt->_cache; -} -#endif - int* __get_h_errno(void) { @@ -177,9 +158,7 @@ __res_put_state(res_state res __unused) /* nothing to do */ } -res_static -__res_get_static(void) -{ +struct res_static* __res_get_static(void) { _res_thread* rt = _res_thread_get(); return rt ? rt->_rstatic : NULL; diff --git a/libc/kernel/tools/clean_header.py b/libc/kernel/tools/clean_header.py index 2c2d001a2..cfd301ad2 100755 --- a/libc/kernel/tools/clean_header.py +++ b/libc/kernel/tools/clean_header.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 #------------------------------------------------------------------------------ # Description of the header clean process @@ -127,7 +127,7 @@ def cleanupFile(dst_file, src_file, rel_path, no_update = True): if __name__ == "__main__": def usage(): - print """\ + print("""\ usage: %s [options] <header_path> options: @@ -142,7 +142,7 @@ if __name__ == "__main__": -d<path> specify path of cleaned kernel headers <header_path> must be in a subdirectory of 'original' - """ % os.path.basename(sys.argv[0]) + """ % os.path.basename(sys.argv[0])) sys.exit(1) try: @@ -211,9 +211,8 @@ if __name__ == "__main__": else: r = "added" - print "cleaning: %-*s -> %-*s (%s)" % (35, path, 35, path, r) + print("cleaning: %-*s -> %-*s (%s)" % (35, path, 35, path, r)) - - b.updateGitFiles() + b.updateFiles() sys.exit(0) diff --git a/libc/kernel/tools/cpp.py b/libc/kernel/tools/cpp.py index 8538eb006..54886413e 100755 --- a/libc/kernel/tools/cpp.py +++ b/libc/kernel/tools/cpp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 """A glorified C pre-processor parser.""" import ctypes @@ -14,7 +14,7 @@ if top is None: utils.panic('ANDROID_BUILD_TOP not set.\n') # Set up the env vars for libclang. -site.addsitedir(os.path.join(top, 'external/clang/bindings/python')) +site.addsitedir(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib64/python3/site-packages/')) import clang.cindex from clang.cindex import conf @@ -28,7 +28,7 @@ from clang.cindex import TranslationUnit # Set up LD_LIBRARY_PATH to include libclang.so, libLLVM.so, and etc. # Note that setting LD_LIBRARY_PATH with os.putenv() sometimes doesn't help. -clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/sdk/tools/linux/lib64/libclang_android.so')) +clang.cindex.Config.set_library_file(os.path.join(top, 'prebuilts/clang/host/linux-x86/clang-stable/lib64/libclang.so')) from defaults import * @@ -254,7 +254,7 @@ class CppTokenizer(object): token_group = TokenGroup(self._tu, tokens_memory, tokens_count) tokens = [] - for i in xrange(0, count): + for i in range(0, count): token = Token(self._tu, token_group, int_data=tokens_array[i].int_data, ptr_data=tokens_array[i].ptr_data, @@ -394,10 +394,10 @@ class CppExpr(object): self._index = 0 if debugCppExpr: - print "CppExpr: trying to parse %s" % repr(tokens) + print("CppExpr: trying to parse %s" % repr(tokens)) self.expr = self.parseExpression(0) if debugCppExpr: - print "CppExpr: got " + repr(self.expr) + print("CppExpr: got " + repr(self.expr)) if self._index != self._num_tokens: self.throw(BadExpectedToken, "crap at end of input (%d != %d): %s" % (self._index, self._num_tokens, repr(tokens))) @@ -405,9 +405,9 @@ class CppExpr(object): def throw(self, exception, msg): if self._index < self._num_tokens: tok = self.tokens[self._index] - print "%d:%d: %s" % (tok.location.line, tok.location.column, msg) + print("%d:%d: %s" % (tok.location.line, tok.location.column, msg)) else: - print "EOF: %s" % msg + print("EOF: %s" % msg) raise exception(msg) def expectId(self, id): @@ -722,7 +722,7 @@ class CppExpr(object): if op == "defined": op, name = e - if macros.has_key(name): + if name in macros: if macros[name] == kCppUndefinedMacro: return ("int", 0) else: @@ -739,7 +739,7 @@ class CppExpr(object): elif op == "ident": op, name = e - if macros.has_key(name): + if name in macros: try: value = int(macros[name]) expanded = ("int", value) @@ -1179,11 +1179,11 @@ class BlockList(object): def dump(self): """Dump all the blocks in current BlockList.""" - print '##### BEGIN #####' + print('##### BEGIN #####') for i, b in enumerate(self.blocks): - print '### BLOCK %d ###' % i - print b - print '##### END #####' + print('### BLOCK %d ###' % i) + print(b) + print('##### END #####') def optimizeIf01(self): """Remove the code between #if 0 .. #endif in a BlockList.""" @@ -1510,7 +1510,7 @@ class BlockParser(object): while i < len(tokens) and tokens[i].location in extent: t = tokens[i] if debugBlockParser: - print ' ' * 2, t.id, t.kind, t.cursor.kind + print(' ' * 2, t.id, t.kind, t.cursor.kind) if (detect_change and t.cursor.extent != extent and t.cursor.kind == CursorKind.PREPROCESSING_DIRECTIVE): break diff --git a/libc/kernel/tools/kernel.py b/libc/kernel/tools/kernel.py index b6418a8c6..69d516b4f 100644 --- a/libc/kernel/tools/kernel.py +++ b/libc/kernel/tools/kernel.py @@ -4,7 +4,7 @@ # list here the macros that you know are always defined/undefined when including # the kernel headers # -import sys, cpp, re, os.path, string, time +import sys, cpp, re, os.path, time from defaults import * verboseSearch = 0 @@ -56,7 +56,7 @@ class HeaderScanner: # <mtd/*> # re_combined_str=\ - r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % string.join(kernel_dirs,"|") + r"^.*<((%s)/[\d\w_\+\.\-/]*)>.*$" % "|".join(kernel_dirs) re_combined = re.compile(re_combined_str) @@ -100,7 +100,7 @@ class HeaderScanner: if from_file: if verboseFind: - print "=== %s uses %s" % (from_file, header) + print("=== %s uses %s" % (from_file, header)) self.headers[header].add(from_file) def parseFile(self, path, arch=None, kernel_root=None): @@ -114,7 +114,7 @@ class HeaderScanner: try: f = open(path, "rt") except: - print "!!! can't read '%s'" % path + print("!!! can't read '%s'" % path) return hasIncludes = False @@ -125,10 +125,10 @@ class HeaderScanner: break if not hasIncludes: - if verboseSearch: print "::: " + path + if verboseSearch: print("::: " + path) return - if verboseSearch: print "*** " + path + if verboseSearch: print("*** " + path) list = cpp.BlockParser().parseFile(path) if list: @@ -205,7 +205,6 @@ class KernelHeaderFinder: if len(kernel_root) > 0 and kernel_root[-1] != "/": kernel_root += "/" - #print "using kernel_root %s" % kernel_root self.archs = archs self.searched = set(headers) self.kernel_root = kernel_root @@ -300,8 +299,8 @@ class ConfigParser: self.items = {} self.duplicates = False - def parseLine(self,line): - line = string.strip(line) + def parseLine(self, line): + line = line.strip() # skip empty and comment lines if len(line) == 0 or line[0] == "#": diff --git a/libc/kernel/tools/update_all.py b/libc/kernel/tools/update_all.py index cef24dd4c..620624808 100755 --- a/libc/kernel/tools/update_all.py +++ b/libc/kernel/tools/update_all.py @@ -1,11 +1,11 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -import sys, cpp, kernel, glob, os, re, getopt, clean_header, subprocess, shutil +import sys, cpp, kernel, glob, os, re, getopt, clean_header, shutil from defaults import * from utils import * def Usage(): - print """\ + print("""\ usage: %(progname)s [kernel-original-path] [kernel-modified-path] this program is used to update all the auto-generated clean headers @@ -21,14 +21,14 @@ def Usage(): - the clean headers will be placed in 'bionic/libc/kernel/arch-<arch>/asm', 'bionic/libc/kernel/android', etc.. -""" % { "progname" : os.path.basename(sys.argv[0]) } +""" % { "progname" : os.path.basename(sys.argv[0]) }) sys.exit(0) def ProcessFiles(updater, original_dir, modified_dir, src_rel_dir, update_rel_dir): # Delete the old headers before updating to the new headers. update_dir = os.path.join(get_kernel_dir(), update_rel_dir) shutil.rmtree(update_dir) - os.mkdir(update_dir, 0755) + os.mkdir(update_dir, 0o755) src_dir = os.path.normpath(os.path.join(original_dir, src_rel_dir)) src_dir_len = len(src_dir) + 1 @@ -62,7 +62,7 @@ def ProcessFiles(updater, original_dir, modified_dir, src_rel_dir, update_rel_di else: state = "added" update_path = os.path.join(update_rel_dir, rel_path) - print "cleaning %s -> %s (%s)" % (src_str, update_path, state) + print("cleaning %s -> %s (%s)" % (src_str, update_path, state)) # This lets us support regular system calls like __NR_write and also weird @@ -149,9 +149,10 @@ ProcessFiles(updater, original_dir, modified_dir, "uapi", "uapi"), # Now process the special files. ProcessFiles(updater, original_dir, modified_dir, "scsi", os.path.join("android", "scsi", "scsi")) -updater.updateGitFiles() +# Copy all of the files. +updater.updateFiles() # Now re-generate the <bits/glibc-syscalls.h> from the new uapi headers. updater = BatchFileUpdater() GenerateGlibcSyscallsHeader(updater) -updater.updateGitFiles() +updater.updateFiles() diff --git a/libc/kernel/tools/utils.py b/libc/kernel/tools/utils.py index 1b06b1b48..3b4828b5a 100644 --- a/libc/kernel/tools/utils.py +++ b/libc/kernel/tools/utils.py @@ -1,6 +1,5 @@ # common python utility routines for the Bionic tool scripts -import commands import logging import os import string @@ -146,19 +145,3 @@ class BatchFileUpdater: for dst in sorted(deletes): os.remove(dst) - - def updateGitFiles(self): - adds, deletes, edits = self.getChanges() - - if adds: - for dst in sorted(adds): - self._writeFile(dst) - commands.getoutput("git add " + " ".join(adds)) - - if deletes: - commands.getoutput("git rm " + " ".join(deletes)) - - if edits: - for dst in sorted(edits): - self._writeFile(dst) - commands.getoutput("git add " + " ".join(edits)) diff --git a/libc/tools/check-symbols-glibc.py b/libc/tools/check-symbols-glibc.py index d8d198262..613aa88ee 100755 --- a/libc/tools/check-symbols-glibc.py +++ b/libc/tools/check-symbols-glibc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # # Copyright (C) 2015 The Android Open Source Project # @@ -231,33 +231,33 @@ posix = posix - in_posix_and_glibc_but_dead_or_useless glibc = glibc - in_posix_and_glibc_but_dead_or_useless if not only_unwanted: - #print 'glibc:' + #print('glibc:') #for symbol in sorted(glibc): - # print symbol - #print + # print(symbol) + #print() - #print 'bionic:' + #print('bionic:') #for symbol in sorted(bionic): - # print symbol - #print + # print(symbol) + #print() - print 'in glibc (but not posix) but not bionic:' + print('in glibc (but not posix) but not bionic:') for symbol in sorted((glibc - posix).difference(bionic)): - print symbol - print + print(symbol) + print() - print 'in posix (and implemented in glibc) but not bionic:' + print('in posix (and implemented in glibc) but not bionic:') for symbol in sorted((posix.intersection(glibc)).difference(bionic)): - print symbol - print + print(symbol) + print() - print 'in bionic but not glibc:' + print('in bionic but not glibc:') allowed_stuff = (bsd_stuff | FORTIFY_stuff | linux_stuff | macro_stuff | std_stuff | weird_stuff | libresolv_stuff | known) for symbol in sorted((bionic - allowed_stuff).difference(glibc)): if symbol in ndk_ignored: symbol += '*' - print symbol + print(symbol) sys.exit(0) diff --git a/libc/tools/check-symbols.py b/libc/tools/check-symbols.py deleted file mode 100755 index 656891790..000000000 --- a/libc/tools/check-symbols.py +++ /dev/null @@ -1,87 +0,0 @@ -#!/usr/bin/env python - -import glob -import os -import re -import string -import subprocess -import sys - -toolchain = os.environ['ANDROID_TOOLCHAIN'] -arch = re.sub(r'.*/linux-x86/([^/]+)/.*', r'\1', toolchain) - -sys.stderr.write('Checking symbols for arch "%s"...\n' % arch) - -def GetSymbols(library, functions_or_variables): - global api - global arch - - api = '9' - if library == 'libm' and arch == 'arm': - api = '3' - - # There were no 64-bit ABIs before API level 21. - if '64' in arch: - api = '21' - - # What GCC calls aarch64, Android calls arm64. - if arch == 'aarch64': - arch = 'arm64' - - path = '%s/development/ndk/platforms/android-%s/arch-%s/symbols/%s.so.%s.txt' % (os.environ['ANDROID_BUILD_TOP'], api, arch, library, functions_or_variables) - symbols = set() - for line in open(path, 'r'): - symbols.add(line.rstrip()) - #sys.stdout.write('%d %s in %s for %s\n' % (len(symbols), functions_or_variables, library, arch)) - return symbols - -def CheckSymbols(library, functions_or_variables): - expected_symbols = GetSymbols(library, functions_or_variables) - - lib_dir = 'lib' - if '64' in arch: - lib_dir = 'lib64' - - so_file = '%s/system/%s/%s.so' % (os.environ['ANDROID_PRODUCT_OUT'], lib_dir, library) - - # Example readelf output: - # 264: 0001623c 4 FUNC GLOBAL DEFAULT 8 cabsf - # 266: 00016244 4 FUNC GLOBAL DEFAULT 8 dremf - # 267: 00019018 4 OBJECT GLOBAL DEFAULT 11 __fe_dfl_env - # 268: 00000000 0 FUNC GLOBAL DEFAULT UND __aeabi_dcmplt - - - r = re.compile(r' +\d+: [0-9a-f]+ +\d+ (FUNC|OBJECT) +\S+ +\S+ +\d+ (\S+)') - - actual_symbols = set() - for line in subprocess.check_output(['readelf', '-W', '--dyn-syms', so_file]).split('\n'): - m = r.match(line) - if m: - symbol = string.split(m.group(2), '@')[0] - if m.group(1) == 'FUNC' and functions_or_variables == 'functions': - actual_symbols.add(symbol) - elif m.group(1) == 'OBJECT' and functions_or_variables == 'variables': - actual_symbols.add(symbol) - #else: - #print 'ignoring: ' % line - - missing = expected_symbols - actual_symbols - if len(missing) > 0: - sys.stderr.write('%d missing %s in %s for %s:\n' % (len(missing), functions_or_variables, library, arch)) - for miss in sorted(missing): - sys.stderr.write(' %s\n' % miss) - - extra = actual_symbols - expected_symbols - if len(extra) > 0: - sys.stderr.write('%d extra %s in %s for %s:\n' % (len(extra), functions_or_variables, library, arch)) - for s in sorted(extra): - sys.stderr.write(' %s\n' % s) - - return len(missing) == 0 - -CheckSymbols("libc", "functions") -CheckSymbols("libc", "variables") -CheckSymbols("libm", "functions") -CheckSymbols("libm", "variables") - -sys.exit(0) diff --git a/libc/tools/generate_notice.py b/libc/tools/generate_notice.py index e0e6b3215..e004d74e9 100755 --- a/libc/tools/generate_notice.py +++ b/libc/tools/generate_notice.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Run with directory arguments from any directory, with no special setup # required. @@ -38,6 +38,9 @@ def is_interesting(path_str: str) -> bool: return False if path.name in {"notice", "readme", "pylintrc"}: return False + # Backup files for some editors. + if path.match("*~"): + return False return True diff --git a/libc/tools/genfunctosyscallnrs.py b/libc/tools/genfunctosyscallnrs.py index 26642f9ae..fa488447a 100755 --- a/libc/tools/genfunctosyscallnrs.py +++ b/libc/tools/genfunctosyscallnrs.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import logging diff --git a/libc/tools/genseccomp.py b/libc/tools/genseccomp.py index a78f6c140..33bf47074 100755 --- a/libc/tools/genseccomp.py +++ b/libc/tools/genseccomp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 import argparse import logging diff --git a/libc/tools/genserv.py b/libc/tools/genserv.py index 84a139d25..acbfea2f0 100755 --- a/libc/tools/genserv.py +++ b/libc/tools/genserv.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # import sys, os, string, re diff --git a/libc/tools/gensyscalls.py b/libc/tools/gensyscalls.py index d8d43029f..baaa52d25 100755 --- a/libc/tools/gensyscalls.py +++ b/libc/tools/gensyscalls.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This tool is used to generate the assembler system call stubs, # the header files listing all available system calls, and the @@ -434,13 +434,13 @@ def main(arch, syscall_file): for syscall in parser.syscalls: syscall["__NR_name"] = make__NR_name(syscall["name"]) - if syscall.has_key("arm"): + if "arm" in syscall: syscall["asm-arm"] = add_footer(32, arm_eabi_genstub(syscall), syscall) - if syscall.has_key("arm64"): + if "arm64" in syscall: syscall["asm-arm64"] = add_footer(64, arm64_genstub(syscall), syscall) - if syscall.has_key("x86"): + if "x86" in syscall: if syscall["socketcall_id"] >= 0: syscall["asm-x86"] = add_footer(32, x86_genstub_socketcall(syscall), syscall) else: @@ -449,13 +449,13 @@ def main(arch, syscall_file): E("socketcall_id for dispatch syscalls is only supported for x86 in '%s'" % t) return - if syscall.has_key("x86_64"): + if "x86_64" in syscall: syscall["asm-x86_64"] = add_footer(64, x86_64_genstub(syscall), syscall) print("/* Generated by gensyscalls.py. Do not edit. */\n") print("#include <private/bionic_asm.h>\n") for syscall in parser.syscalls: - if syscall.has_key("asm-%s" % arch): + if ("asm-%s" % arch) in syscall: print(syscall["asm-%s" % arch]) if arch == 'arm64': diff --git a/libc/tools/ndk_missing_symbols.py b/libc/tools/ndk_missing_symbols.py index a9f92b183..eff697219 100755 --- a/libc/tools/ndk_missing_symbols.py +++ b/libc/tools/ndk_missing_symbols.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 # # Copyright (C) 2015 The Android Open Source Project # diff --git a/libc/tools/symbols.py b/libc/tools/symbols.py index 3f40aad99..145753421 100644 --- a/libc/tools/symbols.py +++ b/libc/tools/symbols.py @@ -41,7 +41,8 @@ def GetFromElf(elf_file, sym_type='--dyn-syms'): symbols = set() - output = subprocess.check_output(['readelf', sym_type, '-W', elf_file]) + output = subprocess.check_output(['readelf', sym_type, '-W', elf_file], + text=True) for line in output.split('\n'): if ' HIDDEN ' in line or ' UND ' in line: continue @@ -76,6 +77,10 @@ def GetFromAndroidSo(files): if not os.path.isdir(lib_dir): lib_dir = os.path.join(out_dir, 'system/lib') + lib_dir = os.path.join(out_dir, 'apex/com.android.runtime/lib64/bionic/') + if not os.path.isdir(lib_dir): + lib_dir = os.path.join(out_dir, 'apex/com.android.runtime/lib/bionic/') + results = set() for f in files: results |= GetFromElf(os.path.join(lib_dir, f)) diff --git a/libc/tools/test_genseccomp.py b/libc/tools/test_genseccomp.py index 8bd351732..b833c2709 100755 --- a/libc/tools/test_genseccomp.py +++ b/libc/tools/test_genseccomp.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Unit tests for genseccomp.py import textwrap diff --git a/libc/upstream-netbsd/android/include/netbsd-compat.h b/libc/upstream-netbsd/android/include/netbsd-compat.h index ea630b273..5dd086e41 100644 --- a/libc/upstream-netbsd/android/include/netbsd-compat.h +++ b/libc/upstream-netbsd/android/include/netbsd-compat.h @@ -17,7 +17,7 @@ #pragma once #define _BSD_SOURCE -#define _GNU_SOURCE +#define _GNU_SOURCE 1 // NetBSD uses _DIAGASSERT to null-check arguments and the like, // but it's clear from the number of mistakes in their assertions diff --git a/tests/Android.bp b/tests/Android.bp index 02a33eec4..476b8f5fb 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -567,6 +567,9 @@ cc_defaults { "-Wno-strlcpy-strlcat-size", "-Wno-strncat-size", ], + static_libs: [ + "libbase", + ], } cc_defaults { @@ -575,6 +578,9 @@ cc_defaults { "-U_FORTIFY_SOURCE", ], srcs: ["fortify_test_main.cpp"], + static_libs: [ + "libbase", + ], tidy: false, target: { host: { @@ -839,7 +845,6 @@ cc_defaults { ], static_libs: [ // The order of these libraries matters, do not shuffle them. - "libbase", "libmeminfo", "libziparchive", "libz", diff --git a/tests/BionicDeathTest.h b/tests/BionicDeathTest.h deleted file mode 100644 index f70839a0f..000000000 --- a/tests/BionicDeathTest.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2014 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#pragma once - -#include <signal.h> - -#include <gtest/gtest.h> - -#if !defined(__BIONIC__) -#define sigaction64 sigaction -#endif - -class BionicDeathTest : public testing::Test { - protected: - virtual void SetUp() { - // Suppress debuggerd stack traces. Too slow. - for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) { - struct sigaction64 action = { .sa_handler = SIG_DFL }; - sigaction64(signo, &action, &previous_); - } - } - - virtual void TearDown() { - for (int signo : { SIGABRT, SIGBUS, SIGSEGV, SIGSYS }) { - sigaction64(signo, &previous_, nullptr); - } - } - - private: - struct sigaction64 previous_; -}; diff --git a/tests/arpa_inet_test.cpp b/tests/arpa_inet_test.cpp index a368b8fcc..8dec2e303 100644 --- a/tests/arpa_inet_test.cpp +++ b/tests/arpa_inet_test.cpp @@ -158,3 +158,95 @@ TEST(arpa_inet, inet_ntop_overflow) { ASSERT_STREQ("::1", inet_ntop(AF_INET6, &ss6, s6, INET6_ADDRSTRLEN)); ASSERT_STREQ("::1", inet_ntop(AF_INET6, &ss6, s6, 2*INET6_ADDRSTRLEN)); } + +TEST(arpa_inet, inet_nsap_addr) { + // inet_nsap_addr() doesn't seem to be documented anywhere, but it's basically + // text to binary for arbitrarily-long strings like "0xdeadbeef". Any + // '.', '+', or '/' characters are ignored as punctuation. The return value is + // the length in bytes, or 0 for all errors. + u_char buf[32]; + + // Missing "0x" prefix. + ASSERT_EQ(0U, inet_nsap_addr("123", buf, sizeof(buf))); + ASSERT_EQ(0U, inet_nsap_addr("012", buf, sizeof(buf))); + + // 1 byte. + ASSERT_EQ(1U, inet_nsap_addr("0x12", buf, sizeof(buf))); + ASSERT_EQ(0x12, buf[0]); + + // 10 bytes. + ASSERT_EQ(10U, inet_nsap_addr("0x1234567890abcdef0011", buf, sizeof(buf))); + ASSERT_EQ(0x12, buf[0]); + ASSERT_EQ(0x34, buf[1]); + ASSERT_EQ(0x56, buf[2]); + ASSERT_EQ(0x78, buf[3]); + ASSERT_EQ(0x90, buf[4]); + ASSERT_EQ(0xab, buf[5]); + ASSERT_EQ(0xcd, buf[6]); + ASSERT_EQ(0xef, buf[7]); + ASSERT_EQ(0x00, buf[8]); + ASSERT_EQ(0x11, buf[9]); + + // Ignored punctuation. + ASSERT_EQ(10U, inet_nsap_addr("0x1122.3344+5566/7788/99aa", buf, sizeof(buf))); + ASSERT_EQ(0x11, buf[0]); + ASSERT_EQ(0x22, buf[1]); + ASSERT_EQ(0x33, buf[2]); + ASSERT_EQ(0x44, buf[3]); + ASSERT_EQ(0x55, buf[4]); + ASSERT_EQ(0x66, buf[5]); + ASSERT_EQ(0x77, buf[6]); + ASSERT_EQ(0x88, buf[7]); + ASSERT_EQ(0x99, buf[8]); + ASSERT_EQ(0xaa, buf[9]); + + // Truncated. + ASSERT_EQ(4U, inet_nsap_addr("0xdeadbeef666666666666", buf, 4)); + // Overwritten... + ASSERT_EQ(0xde, buf[0]); + ASSERT_EQ(0xad, buf[1]); + ASSERT_EQ(0xbe, buf[2]); + ASSERT_EQ(0xef, buf[3]); + // Same as before... + ASSERT_EQ(0x55, buf[4]); + ASSERT_EQ(0x66, buf[5]); + ASSERT_EQ(0x77, buf[6]); + ASSERT_EQ(0x88, buf[7]); + ASSERT_EQ(0x99, buf[8]); + ASSERT_EQ(0xaa, buf[9]); + + // Case insensitivity. + ASSERT_EQ(6U, inet_nsap_addr("0xaAbBcCdDeEfF", buf, 6)); + ASSERT_EQ(0xaa, buf[0]); + ASSERT_EQ(0xbb, buf[1]); + ASSERT_EQ(0xcc, buf[2]); + ASSERT_EQ(0xdd, buf[3]); + ASSERT_EQ(0xee, buf[4]); + ASSERT_EQ(0xff, buf[5]); + + // Punctuation isn't allowed within a byte. + ASSERT_EQ(0U, inet_nsap_addr("0x1.122", buf, sizeof(buf))); + // Invalid punctuation. + ASSERT_EQ(0U, inet_nsap_addr("0x11,22", buf, sizeof(buf))); + // Invalid hex digit. + ASSERT_EQ(0U, inet_nsap_addr("0x11.g2", buf, sizeof(buf))); + ASSERT_EQ(0U, inet_nsap_addr("0x11.2g", buf, sizeof(buf))); + // Invalid half-byte. + ASSERT_EQ(0U, inet_nsap_addr("0x11.2", buf, sizeof(buf))); +} + +TEST(arpa_inet, inet_nsap_ntoa) { + // inet_nsap_ntoa() doesn't seem to be documented anywhere, but it's basically + // binary to text for arbitrarily-long byte buffers. + // The return value is a pointer to the buffer. No errors are possible. + const unsigned char bytes[] = {0x01, 0x00, 0x02, 0x0e, 0xf0, 0x20}; + char dst[32]; + ASSERT_EQ(dst, inet_nsap_ntoa(6, bytes, dst)); + ASSERT_STREQ(dst, "0x01.0002.0EF0.20"); +} + +TEST(arpa_inet, inet_nsap_ntoa__nullptr) { + // If you don't provide a destination, a static buffer is provided for you. + const unsigned char bytes[] = {0x01, 0x00, 0x02, 0x0e, 0xf0, 0x20}; + ASSERT_STREQ("0x01.0002.0EF0.20", inet_nsap_ntoa(6, bytes, nullptr)); +} diff --git a/tests/assert_test.cpp b/tests/assert_test.cpp index 714e22a59..769852abf 100644 --- a/tests/assert_test.cpp +++ b/tests/assert_test.cpp @@ -19,9 +19,9 @@ #undef NDEBUG #include <assert.h> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> -using assert_DeathTest = BionicDeathTest; +using assert_DeathTest = SilentDeathTest; TEST(assert, assert_true) { assert(true); diff --git a/tests/cfi_test.cpp b/tests/cfi_test.cpp index d3cd8d1b8..9a6ed9ac6 100644 --- a/tests/cfi_test.cpp +++ b/tests/cfi_test.cpp @@ -15,12 +15,13 @@ */ #include <dlfcn.h> -#include <gtest/gtest.h> #include <sys/stat.h> #include <vector> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> +#include <gtest/gtest.h> + #include "gtest_globals.h" #include "utils.h" @@ -35,7 +36,7 @@ void __cfi_slowpath_diag(uint64_t CallSiteTypeId, void* Ptr, void* DiagData); size_t __cfi_shadow_size(); } -using cfi_test_DeathTest = BionicDeathTest; +using cfi_test_DeathTest = SilentDeathTest; static void f() {} diff --git a/tests/clang_fortify_tests.cpp b/tests/clang_fortify_tests.cpp index 035517083..5768f1fb3 100644 --- a/tests/clang_fortify_tests.cpp +++ b/tests/clang_fortify_tests.cpp @@ -94,14 +94,14 @@ #include <wchar.h> #ifndef COMPILATION_TESTS +#include <android-base/silent_death_test.h> #include <gtest/gtest.h> -#include "BionicDeathTest.h" #define CONCAT2(x, y) x##y #define CONCAT(x, y) CONCAT2(x, y) #define FORTIFY_TEST_NAME CONCAT(CONCAT(clang_fortify_test_, _FORTIFY_SOURCE), _DeathTest) -using FORTIFY_TEST_NAME = BionicDeathTest; +using FORTIFY_TEST_NAME = SilentDeathTest; template <typename Fn> __attribute__((noreturn)) static void ExitAfter(Fn&& f) { diff --git a/tests/dl_test.cpp b/tests/dl_test.cpp index 6c9bf3fb5..766f27a0b 100644 --- a/tests/dl_test.cpp +++ b/tests/dl_test.cpp @@ -27,9 +27,10 @@ #include <stdint.h> #include <sys/stat.h> -#include <string> -#include <iostream> #include <fstream> +#include <iostream> +#include <regex> +#include <string> #include "gtest_globals.h" #include <android-base/file.h> @@ -382,7 +383,8 @@ static void RelocationsTest(const char* lib, const char* expectation) { ExecTestHelper eth; eth.SetArgs({ "readelf", "-SW", path.c_str(), nullptr }); eth.Run([&]() { execvpe("readelf", eth.GetArgs(), eth.GetEnv()); }, 0, nullptr); - ASSERT_TRUE(eth.GetOutput().find(expectation) != std::string::npos) << eth.GetOutput(); + + ASSERT_TRUE(std::regex_search(eth.GetOutput(), std::regex(expectation))) << eth.GetOutput(); // Can we load it? void* handle = dlopen(lib, RTLD_NOW); @@ -395,31 +397,29 @@ static void RelocationsTest(const char* lib, const char* expectation) { } TEST(dl, relocations_RELR) { - RelocationsTest("librelocations-RELR.so", - ".relr.dyn RELR"); + RelocationsTest("librelocations-RELR.so", "\\.relr\\.dyn * RELR"); } TEST(dl, relocations_ANDROID_RELR) { - RelocationsTest("librelocations-ANDROID_RELR.so", - ".relr.dyn ANDROID_RELR"); + RelocationsTest("librelocations-ANDROID_RELR.so", "\\.relr\\.dyn * ANDROID_RELR"); } TEST(dl, relocations_ANDROID_REL) { RelocationsTest("librelocations-ANDROID_REL.so", #if __LP64__ - ".rela.dyn ANDROID_RELA" + "\\.rela\\.dyn * ANDROID_RELA" #else - ".rel.dyn ANDROID_REL" + "\\.rel\\.dyn * ANDROID_REL" #endif - ); + ); } TEST(dl, relocations_fat) { RelocationsTest("librelocations-fat.so", #if __LP64__ - ".rela.dyn RELA" + "\\.rela\\.dyn * RELA" #else - ".rel.dyn REL" + "\\.rel\\.dyn * REL" #endif - ); + ); } diff --git a/tests/error_test.cpp b/tests/error_test.cpp index e03c8d44f..e114f064c 100644 --- a/tests/error_test.cpp +++ b/tests/error_test.cpp @@ -30,7 +30,9 @@ #include <error.h> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> + +using error_DeathTest = SilentDeathTest; static size_t g_test_error_print_progname_invocation_count; diff --git a/tests/fdsan_test.cpp b/tests/fdsan_test.cpp index c294ff353..016970ffb 100644 --- a/tests/fdsan_test.cpp +++ b/tests/fdsan_test.cpp @@ -16,8 +16,6 @@ #include <gtest/gtest.h> -#include "BionicDeathTest.h" - #include <dirent.h> #include <errno.h> #include <fcntl.h> @@ -32,6 +30,7 @@ #include <unordered_map> +#include <android-base/silent_death_test.h> #include <android-base/unique_fd.h> #define FDSAN_TEST(test_name) TEST_F(FdsanTest, test_name) @@ -49,12 +48,12 @@ struct fdsan : public ::testing::Test { } }; -struct fdsan_DeathTest : public BionicDeathTest { +struct fdsan_DeathTest : public SilentDeathTest { #if defined(__BIONIC__) void SetUp() override { android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_FATAL); signal(BIONIC_SIGNAL_DEBUGGER, SIG_DFL); // Disable debuggerd. - BionicDeathTest::SetUp(); + SilentDeathTest::SetUp(); } #endif }; diff --git a/tests/fortify_test.cpp b/tests/fortify_test.cpp index 3ca0223b2..4abee67dc 100644 --- a/tests/fortify_test.cpp +++ b/tests/fortify_test.cpp @@ -15,7 +15,6 @@ */ #include <gtest/gtest.h> -#include "BionicDeathTest.h" #include <fcntl.h> #include <malloc.h> @@ -28,6 +27,8 @@ #include <sys/types.h> #include <time.h> +#include <android-base/silent_death_test.h> + #if __BIONIC__ #define ASSERT_FORTIFY(expr) ASSERT_EXIT(expr, testing::KilledBySignal(SIGABRT), "FORTIFY") #else @@ -40,7 +41,7 @@ #define DEATHTEST_EVALUATOR(name) DEATHTEST_PASTER(name) #define DEATHTEST DEATHTEST_EVALUATOR(TEST_NAME) -class DEATHTEST : public BionicDeathTest {}; +using DEATHTEST = SilentDeathTest; #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE == 2 struct foo { diff --git a/tests/pidfd_test.cpp b/tests/pidfd_test.cpp index 7c691ef16..b9fadb4a0 100644 --- a/tests/pidfd_test.cpp +++ b/tests/pidfd_test.cpp @@ -14,6 +14,8 @@ * limitations under the License. */ +#include <gtest/gtest.h> + #include <errno.h> #include <fcntl.h> #include <signal.h> @@ -24,16 +26,13 @@ #include <sys/pidfd.h> #endif +#include <android-base/silent_death_test.h> #include <android-base/unique_fd.h> -#include <gtest/gtest.h> - -#include "BionicDeathTest.h" - using android::base::unique_fd; using namespace std::chrono_literals; -using pidfd_DeathTest = BionicDeathTest; +using pidfd_DeathTest = SilentDeathTest; TEST(pidfd, pidfd_open) { #if defined(__BIONIC__) diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 1cbe3de35..1a00460bc 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -38,14 +38,14 @@ #include <android-base/macros.h> #include <android-base/parseint.h> #include <android-base/scopeguard.h> +#include <android-base/silent_death_test.h> #include <android-base/strings.h> #include "private/bionic_constants.h" -#include "BionicDeathTest.h" #include "SignalUtils.h" #include "utils.h" -using pthread_DeathTest = BionicDeathTest; +using pthread_DeathTest = SilentDeathTest; TEST(pthread, pthread_key_create) { pthread_key_t key; diff --git a/tests/semaphore_test.cpp b/tests/semaphore_test.cpp index ed0fcf17e..f3f60208d 100644 --- a/tests/semaphore_test.cpp +++ b/tests/semaphore_test.cpp @@ -17,17 +17,18 @@ #include <semaphore.h> #include <errno.h> -#include <gtest/gtest.h> #include <limits.h> #include <pthread.h> #include <time.h> #include <unistd.h> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> +#include <gtest/gtest.h> + #include "SignalUtils.h" #include "private/bionic_constants.h" -using semaphore_DeathTest = BionicDeathTest; +using semaphore_DeathTest = SilentDeathTest; TEST(semaphore, sem_init) { sem_t s; diff --git a/tests/setjmp_test.cpp b/tests/setjmp_test.cpp index ec1badcf2..ee126eb11 100644 --- a/tests/setjmp_test.cpp +++ b/tests/setjmp_test.cpp @@ -21,10 +21,11 @@ #include <sys/syscall.h> #include <unistd.h> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> + #include "SignalUtils.h" -using setjmp_DeathTest = BionicDeathTest; +using setjmp_DeathTest = SilentDeathTest; TEST(setjmp, setjmp_smoke) { int value; diff --git a/tests/stack_protector_test.cpp b/tests/stack_protector_test.cpp index 9fe7bb105..a95e0373c 100644 --- a/tests/stack_protector_test.cpp +++ b/tests/stack_protector_test.cpp @@ -19,7 +19,6 @@ */ #include <gtest/gtest.h> -#include "BionicDeathTest.h" #include <pthread.h> #include <stdint.h> @@ -27,6 +26,8 @@ #include <unistd.h> #include <set> +#include <android-base/silent_death_test.h> + #include "private/bionic_tls.h" extern "C" pid_t gettid(); // glibc defines this but doesn't declare it anywhere. @@ -99,7 +100,7 @@ TEST(stack_protector, global_guard) { #endif } -class stack_protector_DeathTest : public BionicDeathTest {}; +using stack_protector_DeathTest = SilentDeathTest; TEST_F(stack_protector_DeathTest, modify_stack_protector) { // In another file to prevent inlining, which removes stack protection. diff --git a/tests/stdio_test.cpp b/tests/stdio_test.cpp index 5491589a5..5736e1787 100644 --- a/tests/stdio_test.cpp +++ b/tests/stdio_test.cpp @@ -33,10 +33,10 @@ #include <vector> #include <android-base/file.h> +#include <android-base/silent_death_test.h> #include <android-base/test_utils.h> #include <android-base/unique_fd.h> -#include "BionicDeathTest.h" #include "utils.h" // This #include is actually a test too. We have to duplicate the @@ -56,8 +56,8 @@ using namespace std::string_literals; -using stdio_DeathTest = BionicDeathTest; -using stdio_nofortify_DeathTest = BionicDeathTest; +using stdio_DeathTest = SilentDeathTest; +using stdio_nofortify_DeathTest = SilentDeathTest; static void SetFileTo(const char* path, const char* content) { FILE* fp; diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp index 90ef8619f..6c7966d72 100644 --- a/tests/stdlib_test.cpp +++ b/tests/stdlib_test.cpp @@ -31,9 +31,9 @@ #include <android-base/file.h> #include <android-base/macros.h> +#include <android-base/silent_death_test.h> #include <gtest/gtest.h> -#include "BionicDeathTest.h" #include "math_data_test.h" #include "utils.h" @@ -447,7 +447,7 @@ static void TestBug57421_main() { // Even though this isn't really a death test, we have to say "DeathTest" here so gtest knows to // run this test (which exits normally) in its own process. -class stdlib_DeathTest : public BionicDeathTest {}; +using stdlib_DeathTest = SilentDeathTest; TEST_F(stdlib_DeathTest, getenv_after_main_thread_exits) { // https://code.google.com/p/android/issues/detail?id=57421 diff --git a/tests/system_properties_test.cpp b/tests/system_properties_test.cpp index 6d696c79f..aa8fef4dc 100644 --- a/tests/system_properties_test.cpp +++ b/tests/system_properties_test.cpp @@ -15,7 +15,6 @@ */ #include <gtest/gtest.h> -#include "BionicDeathTest.h" #include <errno.h> #include <sys/wait.h> @@ -25,6 +24,7 @@ #include <thread> #include <android-base/file.h> +#include <android-base/silent_death_test.h> using namespace std::literals; @@ -425,7 +425,7 @@ bool KilledByFault::operator()(int exit_status) const { WTERMSIG(exit_status) == SIGABRT); } -class properties_DeathTest : public BionicDeathTest {}; +using properties_DeathTest = SilentDeathTest; TEST_F(properties_DeathTest, read_only) { #if defined(__BIONIC__) diff --git a/tests/threads_test.cpp b/tests/threads_test.cpp index 5fafff38d..c1e9b123a 100644 --- a/tests/threads_test.cpp +++ b/tests/threads_test.cpp @@ -60,7 +60,8 @@ static int exit_arg(void* arg) { #include <thread> -#include "BionicDeathTest.h" +#include <android-base/silent_death_test.h> + #include "SignalUtils.h" TEST(threads, call_once) { @@ -361,7 +362,7 @@ TEST(threads, thrd_create__thrd_exit) { #endif } -class threads_DeathTest : public BionicDeathTest {}; +using threads_DeathTest = SilentDeathTest; TEST(threads_DeathTest, thrd_exit_main_thread) { #if !defined(HAVE_THREADS_H) diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp index 595ba90c4..7d1e6128b 100644 --- a/tests/unistd_test.cpp +++ b/tests/unistd_test.cpp @@ -16,7 +16,6 @@ #include <gtest/gtest.h> -#include "BionicDeathTest.h" #include "SignalUtils.h" #include "utils.h" @@ -37,6 +36,7 @@ #include <chrono> #include <android-base/file.h> +#include <android-base/silent_death_test.h> #include <android-base/strings.h> #include "private/get_cpu_count_from_string.h" @@ -53,6 +53,8 @@ #define UNISTD_DEATHTEST unistd_DeathTest #endif +using UNISTD_DEATHTEST = SilentDeathTest; + using namespace std::chrono_literals; static void* get_brk() { @@ -711,8 +713,6 @@ TEST(UNISTD_TEST, hwasan_vfork) { } } -class UNISTD_DEATHTEST : public BionicDeathTest {}; - TEST_F(UNISTD_DEATHTEST, abort) { ASSERT_EXIT(abort(), testing::KilledBySignal(SIGABRT), ""); } diff --git a/tools/generate-version-script.py b/tools/generate-version-script.py index acfe21859..def621e1f 100755 --- a/tools/generate-version-script.py +++ b/tools/generate-version-script.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # This tool is used to generate the version scripts for libc, libm, libdl, # and libstdc++ for every architecture. diff --git a/tools/versioner/run_tests.py b/tools/versioner/run_tests.py index f3bb6db89..396f895f1 100755 --- a/tools/versioner/run_tests.py +++ b/tools/versioner/run_tests.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python2 +#!/usr/bin/env python3 import os import subprocess |