Merge "Fix clang header dependency for versioner"
diff --git a/libc/Android.bp b/libc/Android.bp
index 52a7aca..71d4d4a 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1675,7 +1675,9 @@
versions: ["10000"],
},
- symbol_ordering_file: "symbol_ordering",
+ // Sorting bss symbols by size usually results in less dirty pages at run
+ // time, because small symbols are grouped together.
+ sort_bss_symbols_by_size: true,
}
genrule {
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index 4984e38..6e1b0de 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -135,8 +135,11 @@
main_thread.mmap_base = mapping.mmap_base;
main_thread.mmap_size = mapping.mmap_size;
+ main_thread.mmap_base_unguarded = mapping.mmap_base_unguarded;
+ main_thread.mmap_size_unguarded = mapping.mmap_size_unguarded;
__set_tls(&new_tcb->tls_slot(0));
+ __set_stack_and_tls_vma_name(true);
__free_temp_bionic_tls(temp_tls);
}
diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp
index fc00207..cda5e85 100644
--- a/libc/bionic/fork.cpp
+++ b/libc/bionic/fork.cpp
@@ -55,6 +55,10 @@
// fork, close all of their fds blindly, and then exec.
android_fdsan_set_error_level(ANDROID_FDSAN_ERROR_LEVEL_DISABLED);
+ // Reset the stack_and_tls VMA name so it doesn't end with a tid from the
+ // parent process.
+ __set_stack_and_tls_vma_name(true);
+
__bionic_atfork_run_child();
} else {
__bionic_atfork_run_parent();
diff --git a/libc/bionic/jemalloc.h b/libc/bionic/jemalloc.h
index b9a4e99..ef77c9c 100644
--- a/libc/bionic/jemalloc.h
+++ b/libc/bionic/jemalloc.h
@@ -30,7 +30,7 @@
void* je_aligned_alloc_wrapper(size_t, size_t);
int je_iterate(uintptr_t, size_t, void (*)(uintptr_t, size_t, void*), void*);
-int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
+int je_mallctl(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen) __attribute__((nothrow));
struct mallinfo je_mallinfo();
void je_malloc_disable();
void je_malloc_enable();
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 4cf14ad..0dbf539 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -254,6 +254,8 @@
ThreadMapping result = {};
result.mmap_base = space;
result.mmap_size = mmap_size;
+ result.mmap_base_unguarded = space + stack_guard_size;
+ result.mmap_size_unguarded = mmap_size - stack_guard_size - PTHREAD_GUARD_SIZE;
result.static_tls = space + mmap_size - PTHREAD_GUARD_SIZE - layout.size();
result.stack_base = space;
result.stack_top = result.static_tls;
@@ -315,12 +317,33 @@
thread->attr = *attr;
thread->mmap_base = mapping.mmap_base;
thread->mmap_size = mapping.mmap_size;
+ thread->mmap_base_unguarded = mapping.mmap_base_unguarded;
+ thread->mmap_size_unguarded = mapping.mmap_size_unguarded;
*tcbp = tcb;
*child_stack = stack_top;
return 0;
}
+void __set_stack_and_tls_vma_name(bool is_main_thread) {
+ // Name the thread's stack-and-tls area to help with debugging. This mapped area also includes
+ // static TLS data, which is typically a few pages (e.g. bionic_tls).
+ pthread_internal_t* thread = __get_thread();
+ const char* name;
+ if (is_main_thread) {
+ name = "stack_and_tls:main";
+ } else {
+ // The kernel doesn't copy the name string, but this variable will last at least as long as the
+ // mapped area. The mapped area's VMAs are unmapped with a single call to munmap.
+ auto& name_buffer = thread->vma_name_buffer;
+ static_assert(arraysize(name_buffer) >= arraysize("stack_and_tls:") + 11 + 1);
+ async_safe_format_buffer(name_buffer, arraysize(name_buffer), "stack_and_tls:%d", thread->tid);
+ name = name_buffer;
+ }
+ prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->mmap_base_unguarded, thread->mmap_size_unguarded,
+ name);
+}
+
__attribute__((no_sanitize("hwaddress")))
static int __pthread_start(void* arg) {
pthread_internal_t* thread = reinterpret_cast<pthread_internal_t*>(arg);
@@ -333,6 +356,7 @@
// accesses previously made by the creating thread are visible to us.
thread->startup_handshake_lock.lock();
+ __set_stack_and_tls_vma_name(false);
__init_additional_stacks(thread);
void* result = thread->start_routine(thread->start_routine_arg);
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index a1e0c45..22cc400 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -129,6 +129,11 @@
void* mmap_base;
size_t mmap_size;
+ // The location of the VMA to label as the thread's stack_and_tls.
+ void* mmap_base_unguarded;
+ size_t mmap_size_unguarded;
+ char vma_name_buffer[32];
+
thread_local_dtor* thread_local_dtors;
/*
@@ -147,6 +152,8 @@
struct ThreadMapping {
char* mmap_base;
size_t mmap_size;
+ char* mmap_base_unguarded;
+ size_t mmap_size_unguarded;
char* static_tls;
char* stack_base;
@@ -162,6 +169,7 @@
__LIBC_HIDDEN__ void __init_additional_stacks(pthread_internal_t*);
__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
__LIBC_HIDDEN__ ThreadMapping __allocate_thread_mapping(size_t stack_size, size_t stack_guard_size);
+__LIBC_HIDDEN__ void __set_stack_and_tls_vma_name(bool is_main_thread);
__LIBC_HIDDEN__ pthread_t __pthread_internal_add(pthread_internal_t* thread);
__LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id, const char* caller);
diff --git a/libc/include/android/legacy_signal_inlines.h b/libc/include/android/legacy_signal_inlines.h
index 5ca9813..d2c7677 100644
--- a/libc/include/android/legacy_signal_inlines.h
+++ b/libc/include/android/legacy_signal_inlines.h
@@ -52,7 +52,7 @@
static __inline int __ndk_legacy___libc_current_sigrtmin() {
if (__libc_current_sigrtmin) return __libc_current_sigrtmin();
- return __SIGRTMIN + 6; /* Should match __libc_current_sigrtmin. */
+ return __SIGRTMIN + 7; /* Should match __libc_current_sigrtmin. */
}
#undef SIGRTMAX
diff --git a/libc/private/sigrtmin.h b/libc/private/sigrtmin.h
index d78d980..5de1a32 100644
--- a/libc/private/sigrtmin.h
+++ b/libc/private/sigrtmin.h
@@ -39,13 +39,14 @@
// 33 (__SIGRTMIN + 1) libbacktrace
// 34 (__SIGRTMIN + 2) libcore
// 35 (__SIGRTMIN + 3) debuggerd -b
-// 36 (__SIGRTMIN + 4) heapprofd
+// 36 (__SIGRTMIN + 4) heapprofd native dumps
// 37 (__SIGRTMIN + 5) coverage (libprofile-extras)
+// 38 (__SIGRTMIN + 6) heapprofd ART managed heap dumps
//
// If you change this, also change __ndk_legacy___libc_current_sigrtmin
// in <android/legacy_signal_inlines.h> to match.
-#define __SIGRT_RESERVED 6
+#define __SIGRT_RESERVED 7
static inline __always_inline sigset64_t filter_reserved_signals(sigset64_t sigset, int how) {
int (*block)(sigset64_t*, int);
int (*unblock)(sigset64_t*, int);
@@ -72,5 +73,6 @@
unblock(&sigset, __SIGRTMIN + 3);
unblock(&sigset, __SIGRTMIN + 4);
unblock(&sigset, __SIGRTMIN + 5);
+ unblock(&sigset, __SIGRTMIN + 6);
return sigset;
}
diff --git a/libc/symbol_ordering b/libc/symbol_ordering
deleted file mode 100644
index 679d461..0000000
--- a/libc/symbol_ordering
+++ /dev/null
@@ -1,208 +0,0 @@
-# This file is generated by sorting symbols in the .bss section in libc.so by
-# their sizes and taking out symbols that are unique to a target. By sorting
-# symbols by size, we usually have less dirty pages at runtime, because small
-# symbols are grouped together.
-
-ctl_initialized
-gGlobalsMutating
-global_hashtable_initialized
-gmtcheck.gmt_is_set
-had_conf_error
-je_background_thread_enabled_state
-je_log_init_done
-je_opt_abort
-je_opt_abort_conf
-je_opt_background_thread
-je_opt_junk_alloc
-je_opt_junk_free
-je_opt_stats_print
-je_opt_utrace
-je_opt_xmalloc
-je_opt_zero
-je_tsd_booted
-malloc_disabled_tcache
-malloc_slow_flags
-mmap_flags
-os_overcommits
-restartloop
-_ZL24gHeapprofdInitInProgress
-_ZL27gHeapprofdInitHookInstalled
-_ZL23gZygoteChildProfileable
-_ZZ17__find_icu_symbolPKcE9found_icu
-ru_a
-ru_b
-ru_counter
-ru_g
-ru_msb
-ru_seed
-ru_seed2
-ru_x
-_ZZ12bindresvportE4port
-a0
-__atexit
-atexit_mutex
-b0
-ctl_arenas
-ctl_stats
-__cxa_finalize.call_depth
-daylight
-dirty_decay_ms_default.0
-environ
-error_message_count
-error_one_per_line
-error_print_progname
-__free_hook
-g_atexit_lock
-gGlobalsMutateLock
-global_hashtable
-gmtptr
-handlers
-je_background_thread_info
-je_hooks_arena_new_hook
-je_init_system_thp_mode
-je_malloc_conf
-je_malloc_disable.once_control
-je_malloc_message
-je_narenas_auto
-je_ncpus
-je_nhbins
-je_opt_dirty_decay_ms
-je_opt_metadata_thp
-je_opt_muzzy_decay_ms
-je_opt_narenas
-je_opt_thp
-je_tcache_bin_info
-je_tcache_maxclass
-je_tcaches
-je_tsd_tsd
-lastenv
-lcl_is_set
-lclptr
-locallock
-malloc_disabled_lock
-__malloc_hook
-malloc_initializer
-mbrlen.mbs
-mbtowc.mbs
-__memalign_hook
-muzzy_decay_ms_default.0
-narenas_total
-ncleanups
-optarg
-optreset
-os_page
-p5s
-__progname
-random_mutex
-__realloc_hook
-_res_cache_list_lock
-_res_cache_once
-_res_key
-__res_randomid.__libc_mutex_random
-rs
-_rs_forkdetect._rs_pid
-_rs_forked
-rsx
-ru_pid
-ru_prf
-ru_reseed
-__stack_chk_guard
-stack_nelms
-strtok.last
-suboptarg
-__system_property_area__
-tcaches_avail
-tcaches_past
-timezone
-tmpnam.tmpcount
-ut
-wctomb.mbs
-_ZL11g_arc4_lock
-_ZL13g_locale_once
-_ZL13g_thread_list
-_ZL14syslog_log_tag
-_ZL16gHeapprofdHandle
-_ZL17g_libicuuc_handle
-_ZL18netdClientInitOnce
-_ZL30g_propservice_protocol_version
-_ZN9prop_area13pa_data_size_E
-_ZN9prop_area8pa_size_E
-_ZZ10mbsnrtowcsE15__private_state
-_ZZ10wcsnrtombsE15__private_state
-_ZZ13error_at_lineE9last_file
-_ZZ13error_at_lineE9last_line
-_ZZ14__icu_charTypejE10u_charType
-_ZZ23__bionic_get_shell_pathE7sh_path
-_ZZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
-_ZZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
-_ZZ7mbrtowcE15__private_state
-_ZZ7wcrtombE15__private_state
-_ZZ8c16rtombE15__private_state
-_ZZ8c32rtombE15__private_state
-_ZZ8iswcntrlE10u_charType
-_ZZ8iswdigitE9u_isdigit
-_ZZ8iswpunctE9u_ispunct
-_ZZ8mbrtoc16E15__private_state
-_ZZ8mbrtoc32E15__private_state
-_ZZ8towlowerE9u_tolower
-_ZZ8towupperE9u_toupper
-ether_aton.addr
-seed48.sseed
-__dtoa_locks
-_ZGVZ14__icu_charTypejE10u_charType
-_ZGVZ14tzset_unlockedE20persist_sys_timezone
-_ZGVZ17__find_icu_symbolPKcE9found_icu
-_ZGVZ23__bionic_get_shell_pathE7sh_path
-_ZGVZ23__icu_hasBinaryPropertyj9UPropertyPFiiEE19u_hasBinaryProperty
-_ZGVZ25__icu_getIntPropertyValuej9UPropertyE21u_getIntPropertyValue
-_ZGVZ8iswcntrlE10u_charType
-_ZGVZ8iswdigitE9u_isdigit
-_ZGVZ8iswpunctE9u_ispunct
-_ZGVZ8towlowerE9u_tolower
-_ZGVZ8towupperE9u_toupper
-_ZL10gAllocated
-_ZL11gAllocLimit
-_ZL13g_atfork_list
-_ZL6g_lock
-_ZL6g_tags
-je_opt_stats_print_opts
-nuls
-precsize_ntoa.retbuf
-__p_secstodate.output
-ether_ntoa.buf
-inet_ntoa.b
-__p_class.classbuf
-__p_type.typebuf
-__sym_ntop.unname
-__sym_ntos.unname
-_ZL10gFunctions
-freelist
-__p_option.nbuf
-__p_time.nbuf
-_ZL18g_thread_list_lock
-tm
-_ZL8g_locale
-ctl_mtx
-init_lock
-je_arenas_lock
-je_background_thread_lock
-tcaches_mtx
-je_tsd_init_head
-buf_asctime
-__loc_ntoa.tmpbuf
-utmp
-_ZZ14tzset_unlockedE20persist_sys_timezone
-arena_binind_div_info
-__hexdig_D2A
-lcl_TZname
-inet_nsap_ntoa_tmpbuf
-_ZL7key_map
-_ZL17system_properties
-private_mem
-_res_cache_list
-__libc_globals
-tmpnam.buf
-je_extents_rtree
-_nres
-je_arenas
-je_extent_mutex_pool
diff --git a/linker/linker.cpp b/linker/linker.cpp
index 55d684f..e39da81 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -282,6 +282,16 @@
void count_relocation(RelocationKind kind) {
++linker_stats.count[kind];
}
+
+void print_linker_stats() {
+ PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol (%d cached)",
+ g_argv[0],
+ linker_stats.count[kRelocAbsolute],
+ linker_stats.count[kRelocRelative],
+ linker_stats.count[kRelocCopy],
+ linker_stats.count[kRelocSymbol],
+ linker_stats.count[kRelocSymbolCached]);
+}
#else
void count_relocation(RelocationKind) {
}
@@ -2883,6 +2893,17 @@
const size_t tls_tp_base = __libc_shared_globals()->static_tls_layout.offset_thread_pointer();
std::vector<std::pair<TlsDescriptor*, size_t>> deferred_tlsdesc_relocs;
+ struct {
+ // Cache key
+ ElfW(Word) sym;
+
+ // Cache value
+ const ElfW(Sym)* s;
+ soinfo* lsi;
+ } symbol_lookup_cache;
+
+ symbol_lookup_cache.sym = 0;
+
for (size_t idx = 0; rel_iterator.has_next(); ++idx) {
const auto rel = rel_iterator.next();
if (rel == nullptr) {
@@ -2926,14 +2947,25 @@
return false;
} else {
sym_name = get_string(symtab_[sym].st_name);
- const version_info* vi = nullptr;
- if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
- return false;
- }
+ if (sym == symbol_lookup_cache.sym) {
+ s = symbol_lookup_cache.s;
+ lsi = symbol_lookup_cache.lsi;
+ count_relocation(kRelocSymbolCached);
+ } else {
+ const version_info* vi = nullptr;
- if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
- return false;
+ if (!lookup_version_info(version_tracker, sym, sym_name, &vi)) {
+ return false;
+ }
+
+ if (!soinfo_do_lookup(this, sym_name, vi, &lsi, global_group, local_group, &s)) {
+ return false;
+ }
+
+ symbol_lookup_cache.sym = sym;
+ symbol_lookup_cache.s = s;
+ symbol_lookup_cache.lsi = lsi;
}
if (s == nullptr) {
diff --git a/linker/linker.h b/linker/linker.h
index 0f30946..782da1c 100644
--- a/linker/linker.h
+++ b/linker/linker.h
@@ -94,11 +94,14 @@
kRelocRelative,
kRelocCopy,
kRelocSymbol,
+ kRelocSymbolCached,
kRelocMax
};
void count_relocation(RelocationKind kind);
+void print_linker_stats();
+
soinfo* get_libdl_info(const soinfo& linker_si);
soinfo* find_containing_library(const void* p);
diff --git a/linker/linker_main.cpp b/linker/linker_main.cpp
index 612f52f..11d3d29 100644
--- a/linker/linker_main.cpp
+++ b/linker/linker_main.cpp
@@ -490,11 +490,7 @@
static_cast<long long>(t0.tv_usec))));
#endif
#if STATS
- PRINT("RELO STATS: %s: %d abs, %d rel, %d copy, %d symbol", g_argv[0],
- linker_stats.count[kRelocAbsolute],
- linker_stats.count[kRelocRelative],
- linker_stats.count[kRelocCopy],
- linker_stats.count[kRelocSymbol]);
+ print_linker_stats();
#endif
#if COUNT_PAGES
{