Merge "Revert "Remove text-relocation support for lp32""
diff --git a/README.md b/README.md
index 2c42b3b..79bb72a 100644
--- a/README.md
+++ b/README.md
@@ -208,19 +208,17 @@
The host tests require that you have `lunch`ed either an x86 or x86_64 target.
$ mma
- # 64-bit tests for 64-bit targets, 32-bit otherwise.
- $ mm bionic-unit-tests-run-on-host
- # Only exists for 64-bit targets.
$ mm bionic-unit-tests-run-on-host32
+ $ mm bionic-unit-tests-run-on-host64 # For 64-bit *targets* only.
### Against glibc
As a way to check that our tests do in fact test the correct behavior (and not
just the behavior we think is correct), it is possible to run the tests against
-the host's glibc.
+the host's glibc. The executables are already in your path.
$ mma
- $ bionic-unit-tests-glibc32 # already in your path
+ $ bionic-unit-tests-glibc32
$ bionic-unit-tests-glibc64
diff --git a/libc/bionic/libgen.cpp b/libc/bionic/libgen.cpp
index b98f504..2f29d7b 100644
--- a/libc/bionic/libgen.cpp
+++ b/libc/bionic/libgen.cpp
@@ -36,6 +36,9 @@
#include "private/ThreadLocalBuffer.h"
+static ThreadLocalBuffer<char, MAXPATHLEN> g_basename_tls_buffer;
+static ThreadLocalBuffer<char, MAXPATHLEN> g_dirname_tls_buffer;
+
__LIBC64_HIDDEN__ int basename_r(const char* path, char* buffer, size_t buffer_size) {
const char* startp = NULL;
const char* endp = NULL;
@@ -147,17 +150,14 @@
return result;
}
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(basename);
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(dirname);
-
char* basename(const char* path) {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, basename, MAXPATHLEN);
- int rc = basename_r(path, basename_tls_buffer, basename_tls_buffer_size);
- return (rc < 0) ? NULL : basename_tls_buffer;
+ char* buf = g_basename_tls_buffer.get();
+ int rc = basename_r(path, buf, g_basename_tls_buffer.size());
+ return (rc < 0) ? NULL : buf;
}
char* dirname(const char* path) {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, dirname, MAXPATHLEN);
- int rc = dirname_r(path, dirname_tls_buffer, dirname_tls_buffer_size);
- return (rc < 0) ? NULL : dirname_tls_buffer;
+ char* buf = g_dirname_tls_buffer.get();
+ int rc = dirname_r(path, buf, g_dirname_tls_buffer.size());
+ return (rc < 0) ? NULL : buf;
}
diff --git a/libc/bionic/mntent.cpp b/libc/bionic/mntent.cpp
index 4afacda..d169e29 100644
--- a/libc/bionic/mntent.cpp
+++ b/libc/bionic/mntent.cpp
@@ -31,14 +31,13 @@
#include "private/ThreadLocalBuffer.h"
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(getmntent_mntent);
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(getmntent_strings);
+static ThreadLocalBuffer<mntent> g_getmntent_mntent_tls_buffer;
+static ThreadLocalBuffer<char, BUFSIZ> g_getmntent_strings_tls_buffer;
mntent* getmntent(FILE* fp) {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(mntent*, getmntent_mntent, sizeof(mntent));
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, getmntent_strings, BUFSIZ);
- return getmntent_r(fp, getmntent_mntent_tls_buffer,
- getmntent_strings_tls_buffer, getmntent_strings_tls_buffer_size);
+ return getmntent_r(fp, g_getmntent_mntent_tls_buffer.get(),
+ g_getmntent_strings_tls_buffer.get(),
+ g_getmntent_strings_tls_buffer.size());
}
mntent* getmntent_r(FILE* fp, struct mntent* e, char* buf, int buf_len) {
diff --git a/libc/bionic/pty.cpp b/libc/bionic/pty.cpp
index 8847147..1a37847 100644
--- a/libc/bionic/pty.cpp
+++ b/libc/bionic/pty.cpp
@@ -38,8 +38,8 @@
#include "private/ThreadLocalBuffer.h"
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(ptsname);
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(ttyname);
+static ThreadLocalBuffer<char, 32> g_ptsname_tls_buffer;
+static ThreadLocalBuffer<char, 64> g_ttyname_tls_buffer;
int getpt() {
return posix_openpt(O_RDWR|O_NOCTTY);
@@ -54,9 +54,9 @@
}
char* ptsname(int fd) {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, ptsname, 32);
- int error = ptsname_r(fd, ptsname_tls_buffer, ptsname_tls_buffer_size);
- return (error == 0) ? ptsname_tls_buffer : NULL;
+ char* buf = g_ptsname_tls_buffer.get();
+ int error = ptsname_r(fd, buf, g_ptsname_tls_buffer.size());
+ return (error == 0) ? buf : NULL;
}
int ptsname_r(int fd, char* buf, size_t len) {
@@ -80,9 +80,9 @@
}
char* ttyname(int fd) {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, ttyname, 64);
- int error = ttyname_r(fd, ttyname_tls_buffer, ttyname_tls_buffer_size);
- return (error == 0) ? ttyname_tls_buffer : NULL;
+ char* buf = g_ttyname_tls_buffer.get();
+ int error = ttyname_r(fd, buf, g_ttyname_tls_buffer.size());
+ return (error == 0) ? buf : NULL;
}
int ttyname_r(int fd, char* buf, size_t len) {
diff --git a/libc/bionic/strerror.cpp b/libc/bionic/strerror.cpp
index d1518ff..f74194f 100644
--- a/libc/bionic/strerror.cpp
+++ b/libc/bionic/strerror.cpp
@@ -31,16 +31,16 @@
extern "C" const char* __strerror_lookup(int);
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(strerror);
+static ThreadLocalBuffer<char, NL_TEXTMAX> g_strerror_tls_buffer;
char* strerror(int error_number) {
// Just return the original constant in the easy cases.
char* result = const_cast<char*>(__strerror_lookup(error_number));
- if (result != NULL) {
+ if (result != nullptr) {
return result;
}
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, strerror, NL_TEXTMAX);
- strerror_r(error_number, strerror_tls_buffer, strerror_tls_buffer_size);
- return strerror_tls_buffer;
+ result = g_strerror_tls_buffer.get();
+ strerror_r(error_number, result, g_strerror_tls_buffer.size());
+ return result;
}
diff --git a/libc/bionic/strsignal.cpp b/libc/bionic/strsignal.cpp
index 9f0193a..c389ddd 100644
--- a/libc/bionic/strsignal.cpp
+++ b/libc/bionic/strsignal.cpp
@@ -32,7 +32,7 @@
extern "C" const char* __strsignal_lookup(int);
extern "C" const char* __strsignal(int, char*, size_t);
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(strsignal);
+static ThreadLocalBuffer<char, NL_TEXTMAX> g_strsignal_tls_buffer;
char* strsignal(int signal_number) {
// Just return the original constant in the easy cases.
@@ -41,6 +41,6 @@
return result;
}
- LOCAL_INIT_THREAD_LOCAL_BUFFER(char*, strsignal, NL_TEXTMAX);
- return const_cast<char*>(__strsignal(signal_number, strsignal_tls_buffer, strsignal_tls_buffer_size));
+ return const_cast<char*>(__strsignal(signal_number, g_strsignal_tls_buffer.get(),
+ g_strsignal_tls_buffer.size()));
}
diff --git a/libc/bionic/stubs.cpp b/libc/bionic/stubs.cpp
index f9a31b9..c971d1b 100644
--- a/libc/bionic/stubs.cpp
+++ b/libc/bionic/stubs.cpp
@@ -35,6 +35,7 @@
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#include "private/android_filesystem_config.h"
@@ -49,25 +50,12 @@
// functions to share state, but <grp.h> functions can't clobber <passwd.h>
// functions' state and vice versa.
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(group);
-
struct group_state_t {
group group_;
char* group_members_[2];
char group_name_buffer_[32];
};
-static group_state_t* __group_state() {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(group_state_t*, group, sizeof(group_state_t));
- if (group_tls_buffer != NULL) {
- memset(group_tls_buffer, 0, sizeof(group_state_t));
- group_tls_buffer->group_.gr_mem = group_tls_buffer->group_members_;
- }
- return group_tls_buffer;
-}
-
-GLOBAL_INIT_THREAD_LOCAL_BUFFER(passwd);
-
struct passwd_state_t {
passwd passwd_;
char name_buffer_[32];
@@ -75,9 +63,16 @@
char sh_buffer_[32];
};
-static passwd_state_t* __passwd_state() {
- LOCAL_INIT_THREAD_LOCAL_BUFFER(passwd_state_t*, passwd, sizeof(passwd_state_t));
- return passwd_tls_buffer;
+static ThreadLocalBuffer<group_state_t> g_group_tls_buffer;
+static ThreadLocalBuffer<passwd_state_t> g_passwd_tls_buffer;
+
+static group_state_t* __group_state() {
+ group_state_t* result = g_group_tls_buffer.get();
+ if (result != nullptr) {
+ memset(result, 0, sizeof(group_state_t));
+ result->group_.gr_mem = result->group_members_;
+ }
+ return result;
}
static int do_getpw_r(int by_name, const char* name, uid_t uid,
@@ -361,7 +356,7 @@
}
passwd* getpwuid(uid_t uid) { // NOLINT: implementing bad function.
- passwd_state_t* state = __passwd_state();
+ passwd_state_t* state = g_passwd_tls_buffer.get();
if (state == NULL) {
return NULL;
}
@@ -374,7 +369,7 @@
}
passwd* getpwnam(const char* login) { // NOLINT: implementing bad function.
- passwd_state_t* state = __passwd_state();
+ passwd_state_t* state = g_passwd_tls_buffer.get();
if (state == NULL) {
return NULL;
}
diff --git a/libc/dns/resolv/res_state.c b/libc/dns/resolv/res_state.c
index 459f073..afccd99 100644
--- a/libc/dns/resolv/res_state.c
+++ b/libc/dns/resolv/res_state.c
@@ -39,8 +39,6 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
-#include "private/ThreadLocalBuffer.h"
-
/* Set to 1 to enable debug traces */
#define DEBUG 0
@@ -105,7 +103,11 @@
free(rt);
}
-BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(_res_key, _res_thread_free);
+static pthread_key_t _res_key;
+
+__attribute__((constructor)) static void __res_key_init() {
+ pthread_key_create(&_res_key, _res_thread_free);
+}
static _res_thread*
_res_thread_get(void)
diff --git a/libc/kernel/uapi/linux/can/netlink.h b/libc/kernel/uapi/linux/can/netlink.h
index 96a90ff..a1c3159 100644
--- a/libc/kernel/uapi/linux/can/netlink.h
+++ b/libc/kernel/uapi/linux/can/netlink.h
@@ -79,33 +79,35 @@
#define CAN_CTRLMODE_BERR_REPORTING 0x10
#define CAN_CTRLMODE_FD 0x20
#define CAN_CTRLMODE_PRESUME_ACK 0x40
-struct can_device_stats {
+#define CAN_CTRLMODE_FD_NON_ISO 0x80
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct can_device_stats {
__u32 bus_error;
__u32 error_warning;
__u32 error_passive;
- __u32 bus_off;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 bus_off;
__u32 arbitration_lost;
__u32 restarts;
};
-enum {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum {
IFLA_CAN_UNSPEC,
IFLA_CAN_BITTIMING,
IFLA_CAN_BITTIMING_CONST,
- IFLA_CAN_CLOCK,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ IFLA_CAN_CLOCK,
IFLA_CAN_STATE,
IFLA_CAN_CTRLMODE,
IFLA_CAN_RESTART_MS,
- IFLA_CAN_RESTART,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ IFLA_CAN_RESTART,
IFLA_CAN_BERR_COUNTER,
IFLA_CAN_DATA_BITTIMING,
IFLA_CAN_DATA_BITTIMING_CONST,
- __IFLA_CAN_MAX
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __IFLA_CAN_MAX
};
#define IFLA_CAN_MAX (__IFLA_CAN_MAX - 1)
#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
diff --git a/libc/kernel/uapi/linux/in6.h b/libc/kernel/uapi/linux/in6.h
index 15bde3d..e54bc33 100644
--- a/libc/kernel/uapi/linux/in6.h
+++ b/libc/kernel/uapi/linux/in6.h
@@ -128,84 +128,87 @@
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_TLV_JUMBO 194
#define IPV6_TLV_HAO 201
+#if __UAPI_DEF_IPV6_OPTIONS
#define IPV6_ADDRFORM 1
-#define IPV6_2292PKTINFO 2
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_2292PKTINFO 2
#define IPV6_2292HOPOPTS 3
#define IPV6_2292DSTOPTS 4
#define IPV6_2292RTHDR 5
-#define IPV6_2292PKTOPTIONS 6
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_2292PKTOPTIONS 6
#define IPV6_CHECKSUM 7
#define IPV6_2292HOPLIMIT 8
#define IPV6_NEXTHOP 9
-#define IPV6_AUTHHDR 10
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_AUTHHDR 10
#define IPV6_FLOWINFO 11
#define IPV6_UNICAST_HOPS 16
#define IPV6_MULTICAST_IF 17
-#define IPV6_MULTICAST_HOPS 18
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_MULTICAST_HOPS 18
#define IPV6_MULTICAST_LOOP 19
#define IPV6_ADD_MEMBERSHIP 20
#define IPV6_DROP_MEMBERSHIP 21
-#define IPV6_ROUTER_ALERT 22
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_ROUTER_ALERT 22
#define IPV6_MTU_DISCOVER 23
#define IPV6_MTU 24
#define IPV6_RECVERR 25
-#define IPV6_V6ONLY 26
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_V6ONLY 26
#define IPV6_JOIN_ANYCAST 27
#define IPV6_LEAVE_ANYCAST 28
#define IPV6_PMTUDISC_DONT 0
-#define IPV6_PMTUDISC_WANT 1
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_PMTUDISC_WANT 1
#define IPV6_PMTUDISC_DO 2
#define IPV6_PMTUDISC_PROBE 3
#define IPV6_PMTUDISC_INTERFACE 4
-#define IPV6_PMTUDISC_OMIT 5
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_PMTUDISC_OMIT 5
#define IPV6_FLOWLABEL_MGR 32
#define IPV6_FLOWINFO_SEND 33
#define IPV6_IPSEC_POLICY 34
-#define IPV6_XFRM_POLICY 35
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define IPV6_XFRM_POLICY 35
+#endif
#define IPV6_RECVPKTINFO 49
#define IPV6_PKTINFO 50
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_RECVHOPLIMIT 51
#define IPV6_HOPLIMIT 52
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_RECVHOPOPTS 53
#define IPV6_HOPOPTS 54
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_RTHDRDSTOPTS 55
#define IPV6_RECVRTHDR 56
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_RTHDR 57
#define IPV6_RECVDSTOPTS 58
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_DSTOPTS 59
#define IPV6_RECVPATHMTU 60
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_PATHMTU 61
#define IPV6_DONTFRAG 62
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_RECVTCLASS 66
#define IPV6_TCLASS 67
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_AUTOFLOWLABEL 70
#define IPV6_ADDR_PREFERENCES 72
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_PREFER_SRC_TMP 0x0001
#define IPV6_PREFER_SRC_PUBLIC 0x0002
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_PREFER_SRC_PUBTMP_DEFAULT 0x0100
#define IPV6_PREFER_SRC_COA 0x0004
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_PREFER_SRC_HOME 0x0400
#define IPV6_PREFER_SRC_CGA 0x0008
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_PREFER_SRC_NONCGA 0x0800
#define IPV6_MINHOPCOUNT 73
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_ORIGDSTADDR 74
#define IPV6_RECVORIGDSTADDR IPV6_ORIGDSTADDR
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define IPV6_TRANSPARENT 75
#define IPV6_UNICAST_IF 76
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#endif
diff --git a/libc/kernel/uapi/linux/libc-compat.h b/libc/kernel/uapi/linux/libc-compat.h
index 7854520..b66ebe2 100644
--- a/libc/kernel/uapi/linux/libc-compat.h
+++ b/libc/kernel/uapi/linux/libc-compat.h
@@ -32,29 +32,33 @@
#define __UAPI_DEF_IPV6_MREQ 0
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define __UAPI_DEF_IPPROTO_V6 0
+#define __UAPI_DEF_IPV6_OPTIONS 0
#else
#define __UAPI_DEF_IN6_ADDR 1
-#define __UAPI_DEF_IN6_ADDR_ALT 1
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IN6_ADDR_ALT 1
#define __UAPI_DEF_SOCKADDR_IN6 1
#define __UAPI_DEF_IPV6_MREQ 1
#define __UAPI_DEF_IPPROTO_V6 1
-#endif
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IPV6_OPTIONS 1
+#endif
#ifdef _SYS_XATTR_H
#define __UAPI_DEF_XATTR 0
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#else
#define __UAPI_DEF_XATTR 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#endif
#else
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define __UAPI_DEF_IN6_ADDR 1
#define __UAPI_DEF_IN6_ADDR_ALT 1
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define __UAPI_DEF_SOCKADDR_IN6 1
#define __UAPI_DEF_IPV6_MREQ 1
-#define __UAPI_DEF_IPPROTO_V6 1
-#define __UAPI_DEF_XATTR 1
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+#define __UAPI_DEF_IPPROTO_V6 1
+#define __UAPI_DEF_IPV6_OPTIONS 1
+#define __UAPI_DEF_XATTR 1
#endif
+/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#endif
diff --git a/libc/kernel/uapi/linux/target_core_user.h b/libc/kernel/uapi/linux/target_core_user.h
index ce6d26d..7e0cf43 100644
--- a/libc/kernel/uapi/linux/target_core_user.h
+++ b/libc/kernel/uapi/linux/target_core_user.h
@@ -21,75 +21,71 @@
#include <linux/types.h>
#include <linux/uio.h>
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
-#ifndef __packed
-#define __packed __attribute__((packed))
-#endif
#define TCMU_VERSION "1.0"
-/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
#define TCMU_MAILBOX_VERSION 1
#define ALIGN_SIZE 64
struct tcmu_mailbox {
- __u16 version;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u16 version;
__u16 flags;
__u32 cmdr_off;
__u32 cmdr_size;
- __u32 cmd_head;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 cmd_head;
__u32 cmd_tail __attribute__((__aligned__(ALIGN_SIZE)));
} __packed;
enum tcmu_opcode {
- TCMU_OP_PAD = 0,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ TCMU_OP_PAD = 0,
TCMU_OP_CMD,
};
struct tcmu_cmd_entry_hdr {
- __u32 len_op;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __u32 len_op;
} __packed;
#define TCMU_OP_MASK 0x7
#define TCMU_SENSE_BUFFERSIZE 96
-struct tcmu_cmd_entry {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+struct tcmu_cmd_entry {
struct tcmu_cmd_entry_hdr hdr;
uint16_t cmd_id;
uint16_t __pad1;
- union {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ union {
struct {
uint64_t cdb_off;
uint64_t iov_cnt;
- struct iovec iov[0];
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ struct iovec iov[0];
} req;
struct {
uint8_t scsi_status;
- uint8_t __pad1;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ uint8_t __pad1;
uint16_t __pad2;
uint32_t __pad3;
char sense_buffer[TCMU_SENSE_BUFFERSIZE];
- } rsp;
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ } rsp;
};
} __packed;
#define TCMU_OP_ALIGN_SIZE sizeof(uint64_t)
-enum tcmu_genl_cmd {
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+enum tcmu_genl_cmd {
TCMU_CMD_UNSPEC,
TCMU_CMD_ADDED_DEVICE,
TCMU_CMD_REMOVED_DEVICE,
- __TCMU_CMD_MAX,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ __TCMU_CMD_MAX,
};
#define TCMU_CMD_MAX (__TCMU_CMD_MAX - 1)
enum tcmu_genl_attr {
- TCMU_ATTR_UNSPEC,
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+ TCMU_ATTR_UNSPEC,
TCMU_ATTR_DEVICE,
TCMU_ATTR_MINOR,
__TCMU_ATTR_MAX,
-};
/* WARNING: DO NOT EDIT, AUTO-GENERATED CODE - SEE TOP FOR INSTRUCTIONS */
+};
#define TCMU_ATTR_MAX (__TCMU_ATTR_MAX - 1)
#endif
diff --git a/libc/kernel/uapi/linux/version.h b/libc/kernel/uapi/linux/version.h
index cb6842a..a6c6a2f 100644
--- a/libc/kernel/uapi/linux/version.h
+++ b/libc/kernel/uapi/linux/version.h
@@ -16,5 +16,5 @@
***
****************************************************************************
****************************************************************************/
-#define LINUX_VERSION_CODE 201219
+#define LINUX_VERSION_CODE 201226
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
diff --git a/libc/private/ThreadLocalBuffer.h b/libc/private/ThreadLocalBuffer.h
index cc47317..5e43665 100644
--- a/libc/private/ThreadLocalBuffer.h
+++ b/libc/private/ThreadLocalBuffer.h
@@ -32,32 +32,30 @@
#include <malloc.h>
#include <pthread.h>
-// libstdc++ currently contains __cxa_guard_acquire and __cxa_guard_release,
-// so we make do with macros instead of a C++ class.
-// TODO: move __cxa_guard_acquire and __cxa_guard_release into libc.
+// TODO: use __thread instead?
-// We used to use pthread_once to initialize the keys, but life is more predictable
-// if we allocate them all up front when the C library starts up, via __constructor__.
-#define BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(key_name, key_destructor) \
- static pthread_key_t key_name; \
- __attribute__((constructor)) static void __bionic_tls_ ## key_name ## _key_init() { \
- pthread_key_create(&key_name, key_destructor); \
+template <typename T, size_t Size = sizeof(T)>
+class ThreadLocalBuffer {
+ public:
+ ThreadLocalBuffer() {
+ // We used to use pthread_once to initialize the keys, but life is more predictable
+ // if we allocate them all up front when the C library starts up, via __constructor__.
+ pthread_key_create(&key_, free);
}
-#define GLOBAL_INIT_THREAD_LOCAL_BUFFER(name) \
- static void __bionic_tls_ ## name ## _key_destroy(void* buffer) { \
- free(buffer); \
- } \
- BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR(__bionic_tls_ ## name ## _key, __bionic_tls_ ## name ## _key_destroy)
+ T* get() {
+ T* result = reinterpret_cast<T*>(pthread_getspecific(key_));
+ if (result == nullptr) {
+ result = reinterpret_cast<T*>(calloc(1, Size));
+ pthread_setspecific(key_, result);
+ }
+ return result;
+ }
-// Leaves "name_tls_buffer" and "name_tls_buffer_size" defined and initialized.
-#define LOCAL_INIT_THREAD_LOCAL_BUFFER(type, name, byte_count) \
- type name ## _tls_buffer = \
- reinterpret_cast<type>(pthread_getspecific(__bionic_tls_ ## name ## _key)); \
- if (name ## _tls_buffer == NULL) { \
- name ## _tls_buffer = reinterpret_cast<type>(calloc(1, byte_count)); \
- pthread_setspecific(__bionic_tls_ ## name ## _key, name ## _tls_buffer); \
- } \
- const size_t name ## _tls_buffer_size __attribute__((unused)) = byte_count
+ size_t size() { return Size; }
+
+ private:
+ pthread_key_t key_;
+};
#endif // _BIONIC_THREAD_LOCAL_BUFFER_H_included
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 1ab8d4a..414d171 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -72,22 +72,26 @@
/*
* Bionic uses some pthread keys internally. All pthread keys used internally
- * should be created in constructors, except for keys that may be used in or before constructors.
+ * should be created in constructors, except for keys that may be used in or
+ * before constructors.
+ *
* We need to manually maintain the count of pthread keys used internally, but
* pthread_test should fail if we forget.
- * Following are current pthread keys used internally by libc:
- * basename libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * dirname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
+ *
+ * These are the pthread keys currently used internally by libc:
+ *
+ * basename libc (ThreadLocalBuffer)
+ * dirname libc (ThreadLocalBuffer)
* uselocale libc (can be used in constructors)
- * getmntent_mntent libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * getmntent_strings libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * ptsname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * ttyname libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * strerror libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * strsignal libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * passwd libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * group libc (GLOBAL_INIT_THREAD_LOCAL_BUFFER)
- * _res_key libc (BIONIC_PTHREAD_KEY_WITH_CONSTRUCTOR)
+ * getmntent_mntent libc (ThreadLocalBuffer)
+ * getmntent_strings libc (ThreadLocalBuffer)
+ * ptsname libc (ThreadLocalBuffer)
+ * ttyname libc (ThreadLocalBuffer)
+ * strerror libc (ThreadLocalBuffer)
+ * strsignal libc (ThreadLocalBuffer)
+ * passwd libc (ThreadLocalBuffer)
+ * group libc (ThreadLocalBuffer)
+ * _res_key libc (constructor in BSD code)
*/
#define LIBC_PTHREAD_KEY_RESERVED_COUNT 12
diff --git a/tests/ftw_test.cpp b/tests/ftw_test.cpp
index 6741d00..b7e5bd5 100644
--- a/tests/ftw_test.cpp
+++ b/tests/ftw_test.cpp
@@ -30,11 +30,11 @@
char path[PATH_MAX];
snprintf(path, sizeof(path), "%s/dir", root);
- ASSERT_EQ(0, mkdir(path, 0555));
+ ASSERT_EQ(0, mkdir(path, 0755)) << path;
snprintf(path, sizeof(path), "%s/dir/sub", root);
- ASSERT_EQ(0, mkdir(path, 0555));
+ ASSERT_EQ(0, mkdir(path, 0555)) << path;
snprintf(path, sizeof(path), "%s/unreadable-dir", root);
- ASSERT_EQ(0, mkdir(path, 0000));
+ ASSERT_EQ(0, mkdir(path, 0000)) << path;
snprintf(path, sizeof(path), "%s/dangler", root);
ASSERT_EQ(0, symlink("/does-not-exist", path));
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index 13d743f..16bf9c0 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -68,8 +68,7 @@
for (int i = 0; i < nkeys; ++i) {
pthread_key_t key;
- // If this fails, it's likely that GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT is
- // wrong.
+ // If this fails, it's likely that LIBC_PTHREAD_KEY_RESERVED_COUNT is wrong.
ASSERT_EQ(0, pthread_key_create(&key, NULL)) << i << " of " << nkeys;
keys.push_back(key);
ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void*>(i)));