am 13bd3716: am bb897fa9: Merge "libc_init_static: apply relro earlier."
* commit '13bd37160ee340ddcf7e1fb57251b124e0ec69c1':
libc_init_static: apply relro earlier.
diff --git a/libc/Android.mk b/libc/Android.mk
index c98d2ff..4bf996b 100644
--- a/libc/Android.mk
+++ b/libc/Android.mk
@@ -805,6 +805,9 @@
LOCAL_WHOLE_STATIC_LIBRARIES := libbionic_ssp libc_bionic libc_netbsd
LOCAL_SYSTEM_SHARED_LIBRARIES :=
+# TODO: split out the asflags.
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+
include $(BUILD_STATIC_LIBRARY)
diff --git a/libc/netbsd/resolv/res_cache.c b/libc/netbsd/resolv/res_cache.c
index 838e084..afc9a36 100644
--- a/libc/netbsd/resolv/res_cache.c
+++ b/libc/netbsd/resolv/res_cache.c
@@ -572,8 +572,6 @@
static int
_dnsPacket_checkQR( DnsPacket* packet )
{
- int len;
-
if (!_dnsPacket_checkQName(packet))
return 0;
@@ -832,8 +830,6 @@
static unsigned
_dnsPacket_hashQR( DnsPacket* packet, unsigned hash )
{
- int len;
-
hash = _dnsPacket_hashQName(packet, hash);
hash = _dnsPacket_hashBytes(packet, 4, hash); /* TYPE and CLASS */
return hash;
@@ -1020,8 +1016,58 @@
} Entry;
/**
- * Parse the answer records and find the smallest
- * TTL among the answer records.
+ * Find the TTL for a negative DNS result. This is defined as the minimum
+ * of the SOA records TTL and the MINIMUM-TTL field (RFC-2308).
+ *
+ * Return 0 if not found.
+ */
+static u_long
+answer_getNegativeTTL(ns_msg handle) {
+ int n, nscount;
+ u_long result = 0;
+ ns_rr rr;
+
+ nscount = ns_msg_count(handle, ns_s_ns);
+ for (n = 0; n < nscount; n++) {
+ if ((ns_parserr(&handle, ns_s_ns, n, &rr) == 0) && (ns_rr_type(rr) == ns_t_soa)) {
+ const u_char *rdata = ns_rr_rdata(rr); // find the data
+ const u_char *edata = rdata + ns_rr_rdlen(rr); // add the len to find the end
+ int len;
+ u_long ttl, rec_result = ns_rr_ttl(rr);
+
+ // find the MINIMUM-TTL field from the blob of binary data for this record
+ // skip the server name
+ len = dn_skipname(rdata, edata);
+ if (len == -1) continue; // error skipping
+ rdata += len;
+
+ // skip the admin name
+ len = dn_skipname(rdata, edata);
+ if (len == -1) continue; // error skipping
+ rdata += len;
+
+ if (edata - rdata != 5*NS_INT32SZ) continue;
+ // skip: serial number + refresh interval + retry interval + expiry
+ rdata += NS_INT32SZ * 4;
+ // finally read the MINIMUM TTL
+ ttl = ns_get32(rdata);
+ if (ttl < rec_result) {
+ rec_result = ttl;
+ }
+ // Now that the record is read successfully, apply the new min TTL
+ if (n == 0 || rec_result < result) {
+ result = rec_result;
+ }
+ }
+ }
+ return result;
+}
+
+/**
+ * Parse the answer records and find the appropriate
+ * smallest TTL among the records. This might be from
+ * the answer records if found or from the SOA record
+ * if it's a negative result.
*
* The returned TTL is the number of seconds to
* keep the answer in the cache.
@@ -1041,14 +1087,20 @@
if (ns_initparse(answer, answerlen, &handle) >= 0) {
// get number of answer records
ancount = ns_msg_count(handle, ns_s_an);
- for (n = 0; n < ancount; n++) {
- if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
- ttl = ns_rr_ttl(rr);
- if (n == 0 || ttl < result) {
- result = ttl;
+
+ if (ancount == 0) {
+ // a response with no answers? Cache this negative result.
+ result = answer_getNegativeTTL(handle);
+ } else {
+ for (n = 0; n < ancount; n++) {
+ if (ns_parserr(&handle, ns_s_an, n, &rr) == 0) {
+ ttl = ns_rr_ttl(rr);
+ if (n == 0 || ttl < result) {
+ result = ttl;
+ }
+ } else {
+ XLOG("ns_parserr failed ancount no = %d. errno = %s\n", n, strerror(errno));
}
- } else {
- XLOG("ns_parserr failed ancount no = %d. errno = %s\n", n, strerror(errno));
}
}
} else {
@@ -1197,6 +1249,7 @@
struct resolv_cache_info* next;
char* nameservers[MAXNS +1];
struct addrinfo* nsaddrinfo[MAXNS + 1];
+ char* domains;
} CacheInfo;
#define HTABLE_VALID(x) ((x) != NULL && (x) != HTABLE_DELETED)
@@ -1252,7 +1305,7 @@
} else {
struct timespec ts = {0,0};
ts.tv_sec = _time_now() + PENDING_REQUEST_TIMEOUT;
- int rv = pthread_cond_timedwait(&ri->cond, &cache->lock, &ts);
+ pthread_cond_timedwait(&ri->cond, &cache->lock, &ts);
}
}
@@ -1306,7 +1359,6 @@
_cache_flush_locked( Cache* cache )
{
int nn;
- time_t now = _time_now();
for (nn = 0; nn < cache->max_entries; nn++)
{
@@ -1442,6 +1494,7 @@
remove("/data/reslog.txt");
}
else {
+ errno = 0; // else debug is introducing error signals
XLOG("_dump_answer: can't open file\n");
}
}
@@ -1577,9 +1630,7 @@
int answersize,
int *answerlen )
{
- DnsPacket pack[1];
Entry key[1];
- int index;
Entry** lookup;
Entry* e;
time_t now;
@@ -1752,8 +1803,6 @@
static struct resolv_cache* _find_named_cache_locked(const char* ifname);
/* gets a resolv_cache_info associated with an interface name, or NULL if not found */
static struct resolv_cache_info* _find_cache_info_locked(const char* ifname);
-/* free dns name server list of a resolv_cache_info structure */
-static void _free_nameservers(struct resolv_cache_info* cache_info);
/* look up the named cache, and creates one if needed */
static struct resolv_cache* _get_res_cache_for_iface_locked(const char* ifname);
/* empty the named cache */
@@ -1989,7 +2038,8 @@
}
void
-_resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers)
+_resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers,
+ const char *domains)
{
int i, rt, index;
struct addrinfo hints;
@@ -2023,6 +2073,7 @@
cache_info->nsaddrinfo[index] = NULL;
}
}
+ cache_info->domains = strdup(domains);
}
pthread_mutex_unlock(&_res_cache_list_lock);
}
diff --git a/libc/private/bionic_time.h b/libc/private/bionic_time.h
index ee82254..464ab0f 100644
--- a/libc/private/bionic_time.h
+++ b/libc/private/bionic_time.h
@@ -49,7 +49,12 @@
const char * date_fmt;
};
-extern size_t strftime_tz(char *s, size_t max, const char *format, const struct tm *tm, const struct strftime_locale* lc);
+/*
+ * Note: you should consider these extensions deprecated and use managed code or icu4c instead.
+ */
+extern size_t strftime_tz(char* s, size_t max, const char* format, const struct tm* tm, const struct strftime_locale* lc);
+extern time_t mktime_tz(struct tm* const tmp, char const* tz);
+extern void localtime_tz(const time_t* const timep, struct tm* tmp, const char* tz);
#endif /* _BIONIC_STRFTIME_TZ_DECLARED */
diff --git a/libc/private/resolv_iface.h b/libc/private/resolv_iface.h
index f562687..3fe586e 100644
--- a/libc/private/resolv_iface.h
+++ b/libc/private/resolv_iface.h
@@ -48,7 +48,8 @@
extern void _resolv_set_default_iface(const char* ifname);
/* set name servers for an interface */
-extern void _resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers);
+extern void _resolv_set_nameservers_for_iface(const char* ifname, char** servers, int numservers,
+ const char *domains);
/* tell resolver of the address of an interface */
extern void _resolv_set_addr_of_iface(const char* ifname, struct in_addr* addr);
diff --git a/libc/tzcode/localtime.c b/libc/tzcode/localtime.c
index 6ed36c8..447907e 100644
--- a/libc/tzcode/localtime.c
+++ b/libc/tzcode/localtime.c
@@ -212,9 +212,9 @@
static const char * getrule P((const char * strp, struct rule * rulep));
static void gmtload P((struct state * sp));
static struct tm * gmtsub P((const time_t * timep, long offset,
- struct tm * tmp));
+ struct tm * tmp, const struct state * sp)); // android-changed: added sp.
static struct tm * localsub P((const time_t * timep, long offset,
- struct tm * tmp));
+ struct tm * tmp, const struct state * sp)); // android-changed: added sp.
static int increment_overflow P((int * number, int delta));
static int leaps_thru_end_of P((int y));
static int long_increment_overflow P((long * number, int delta));
@@ -225,16 +225,16 @@
static void settzname P((void));
static time_t time1 P((struct tm * tmp,
struct tm * (*funcp) P((const time_t *,
- long, struct tm *)),
- long offset));
+ long, struct tm *, const struct state *)), // android-changed: added state*.
+ long offset, const struct state * sp)); // android-changed: added sp.
static time_t time2 P((struct tm *tmp,
struct tm * (*funcp) P((const time_t *,
- long, struct tm*)),
- long offset, int * okayp));
+ long, struct tm*, const struct state *)), // android-changed: added state*.
+ long offset, int * okayp, const struct state * sp)); // android-changed: added sp.
static time_t time2sub P((struct tm *tmp,
struct tm * (*funcp) P((const time_t *,
- long, struct tm*)),
- long offset, int * okayp, int do_norm_secs));
+ long, struct tm*, const struct state *)), // android-changed: added state*.
+ long offset, int * okayp, int do_norm_secs, const struct state * sp)); // android-change: added sp.
static struct tm * timesub P((const time_t * timep, long offset,
const struct state * sp, struct tm * tmp));
static int tmcomp P((const struct tm * atmp,
@@ -1290,21 +1290,25 @@
/*ARGSUSED*/
static struct tm *
-localsub(timep, offset, tmp)
+localsub(timep, offset, tmp, sp) // android-changed: added sp.
const time_t * const timep;
const long offset;
struct tm * const tmp;
+const struct state * sp; // android-added: added sp.
{
- register struct state * sp;
register const struct ttinfo * ttisp;
register int i;
register struct tm * result;
const time_t t = *timep;
- sp = lclptr;
+ // BEGIN android-changed: support user-supplied sp.
+ if (sp == NULL) {
+ sp = lclptr;
+ }
+ // END android-changed
#ifdef ALL_STATE
if (sp == NULL)
- return gmtsub(timep, offset, tmp);
+ return gmtsub(timep, offset, tmp, sp); // android-changed: added sp.
#endif /* defined ALL_STATE */
if ((sp->goback && t < sp->ats[0]) ||
(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
@@ -1331,7 +1335,7 @@
if (newt < sp->ats[0] ||
newt > sp->ats[sp->timecnt - 1])
return NULL; /* "cannot happen" */
- result = localsub(&newt, offset, tmp);
+ result = localsub(&newt, offset, tmp, sp); // android-changed: added sp.
if (result == tmp) {
register time_t newy;
@@ -1401,7 +1405,7 @@
_tzLock();
tzset_locked();
- result = localsub(timep, 0L, tmp);
+ result = localsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
_tzUnlock();
return result;
@@ -1412,13 +1416,16 @@
*/
static struct tm *
-gmtsub(timep, offset, tmp)
+gmtsub(timep, offset, tmp, sp) // android-changed: added sp.
const time_t * const timep;
const long offset;
struct tm * const tmp;
+const struct state * sp; // android-changed: added sp.
{
register struct tm * result;
+ (void) sp; // android-added: unused.
+
if (!gmt_is_set) {
gmt_is_set = TRUE;
#ifdef ALL_STATE
@@ -1469,7 +1476,7 @@
struct tm* result;
_tzLock();
- result = gmtsub(timep, 0L, tmp);
+ result = gmtsub(timep, 0L, tmp, NULL); // android-changed: extra parameter.
_tzUnlock();
return result;
@@ -1482,7 +1489,7 @@
const time_t * const timep;
const long offset;
{
- return gmtsub(timep, offset, &tmGlobal);
+ return gmtsub(timep, offset, &tmGlobal, NULL); // android-changed: extra parameter.
}
#endif /* 0 */
#endif /* defined STD_INSPIRED */
@@ -1755,14 +1762,14 @@
}
static time_t
-time2sub(tmp, funcp, offset, okayp, do_norm_secs)
+time2sub(tmp, funcp, offset, okayp, do_norm_secs, sp) // android-changed: added sp
struct tm * const tmp;
-struct tm * (* const funcp) P((const time_t*, long, struct tm*));
+struct tm * (* const funcp) P((const time_t*, long, struct tm*, const struct state*)); // android-changed: added state*
const long offset;
int * const okayp;
const int do_norm_secs;
+const struct state * sp; // android-changed: added sp
{
- register const struct state * sp;
register int dir;
register int i, j;
register int saved_seconds;
@@ -1864,7 +1871,7 @@
t = lo;
else if (t > hi)
t = hi;
- if ((*funcp)(&t, offset, &mytm) == NULL) {
+ if ((*funcp)(&t, offset, &mytm, sp) == NULL) { // android-changed: added sp.
/*
** Assume that t is too extreme to be represented in
** a struct tm; arrange things so that it is less
@@ -1902,9 +1909,13 @@
/*
** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*/
- sp = (const struct state *)
- (((void *) funcp == (void *) localsub) ?
- lclptr : gmtptr);
+ // BEGIN android-changed: support user-supplied sp
+ if (sp == NULL) {
+ sp = (const struct state *)
+ (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+ }
+ // END android-changed
#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
@@ -1917,7 +1928,7 @@
continue;
newt = t + sp->ttis[j].tt_gmtoff -
sp->ttis[i].tt_gmtoff;
- if ((*funcp)(&newt, offset, &mytm) == NULL)
+ if ((*funcp)(&newt, offset, &mytm, sp) == NULL) // android-changed: added sp.
continue;
if (tmcomp(&mytm, &yourtm) != 0)
continue;
@@ -1937,17 +1948,19 @@
if ((newt < t) != (saved_seconds < 0))
return WRONG;
t = newt;
- if ((*funcp)(&t, offset, tmp))
+ if ((*funcp)(&t, offset, tmp, sp)) // android-changed: added sp.
*okayp = TRUE;
return t;
}
+// BEGIN android-changed: added sp.
static time_t
-time2(tmp, funcp, offset, okayp)
+time2(tmp, funcp, offset, okayp, sp)
struct tm * const tmp;
-struct tm * (* const funcp) P((const time_t*, long, struct tm*));
+struct tm * (* const funcp) P((const time_t*, long, struct tm*, const struct state*));
const long offset;
int * const okayp;
+const struct state * sp;
{
time_t t;
@@ -1956,18 +1969,19 @@
** (in case tm_sec contains a value associated with a leap second).
** If that fails, try with normalization of seconds.
*/
- t = time2sub(tmp, funcp, offset, okayp, FALSE);
- return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+ t = time2sub(tmp, funcp, offset, okayp, FALSE, sp);
+ return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE, sp);
}
+// END android-changed
static time_t
-time1(tmp, funcp, offset)
+time1(tmp, funcp, offset, sp) // android-changed: added sp.
struct tm * const tmp;
-struct tm * (* const funcp) P((const time_t *, long, struct tm *));
+struct tm * (* const funcp) P((const time_t *, long, struct tm *, const struct state *));
const long offset;
+const struct state * sp; // android-changed: added sp.
{
register time_t t;
- register const struct state * sp;
register int samei, otheri;
register int sameind, otherind;
register int i;
@@ -1978,7 +1992,7 @@
if (tmp->tm_isdst > 1)
tmp->tm_isdst = 1;
- t = time2(tmp, funcp, offset, &okay);
+ t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp.
#ifdef PCTS
/*
** PCTS code courtesy Grant Sullivan.
@@ -2001,8 +2015,12 @@
/*
** The (void *) casts are the benefit of SunOS 3.3 on Sun 2's.
*/
- sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
- lclptr : gmtptr);
+ // BEGIN android-changed: support user-supplied sp.
+ if (sp == NULL) {
+ sp = (const struct state *) (((void *) funcp == (void *) localsub) ?
+ lclptr : gmtptr);
+ }
+ // BEGIN android-changed
#ifdef ALL_STATE
if (sp == NULL)
return WRONG;
@@ -2026,7 +2044,7 @@
tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
sp->ttis[samei].tt_gmtoff;
tmp->tm_isdst = !tmp->tm_isdst;
- t = time2(tmp, funcp, offset, &okay);
+ t = time2(tmp, funcp, offset, &okay, sp); // android-changed: added sp.
if (okay)
return t;
tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
@@ -2044,11 +2062,40 @@
time_t result;
_tzLock();
tzset_locked();
- result = time1(tmp, localsub, 0L);
+ result = time1(tmp, localsub, 0L, NULL); // android-changed: extra parameter.
_tzUnlock();
return result;
}
+// BEGIN android-added
+time_t
+mktime_tz(tmp, tz)
+struct tm * const tmp;
+char const * tz;
+{
+ struct state st;
+ if (tzload(tz, &st, TRUE) != 0) {
+ // TODO: not sure what's best here, but for now, we fall back to gmt.
+ gmtload(&st);
+ }
+ return time1(tmp, localsub, 0L, &st);
+}
+
+void
+localtime_tz(timep, tmp, tz)
+const time_t * const timep;
+struct tm * tmp;
+const char* tz;
+{
+ struct state st;
+ if (tzload(tz, &st, TRUE) != 0) {
+ // TODO: not sure what's best here, but for now, we fall back to gmt.
+ gmtload(&st);
+ }
+ localsub(timep, 0L, tmp, &st);
+}
+// END android-added
+
#ifdef STD_INSPIRED
time_t
@@ -2067,7 +2114,7 @@
tmp->tm_isdst = 0;
_tzLock();
- result = time1(tmp, gmtsub, 0L);
+ result = time1(tmp, gmtsub, 0L, NULL); // android-changed: extra parameter.
_tzUnlock();
return result;
@@ -2083,7 +2130,7 @@
tmp->tm_isdst = 0;
_tzLock();
- result = time1(tmp, gmtsub, offset);
+ result = time1(tmp, gmtsub, offset, NULL); // android-changed: extra parameter.
_tzUnlock();
return result;
diff --git a/linker/Android.mk b/linker/Android.mk
index 5fccf9b..7c197f1 100644
--- a/linker/Android.mk
+++ b/linker/Android.mk
@@ -67,6 +67,9 @@
# just for this module
LOCAL_NO_CRT := true
+# TODO: split out the asflags.
+LOCAL_ASFLAGS := $(LOCAL_CFLAGS)
+
include $(BUILD_SYSTEM)/dynamic_binary.mk
# See build/core/executable.mk