Merge changes I70ea4b23,Iedcfe36b,I3f21fc71,Ie99c0eef
* changes:
libc: Match header annotations to version script
versioner: Build SymbolDatabase from version scripts
versioner: Add 28 to version list
libc: Add default __STRING implementation
diff --git a/docs/status.md b/docs/status.md
index 0106ccd..54385a4 100644
--- a/docs/status.md
+++ b/docs/status.md
@@ -42,6 +42,7 @@
* `reallocarray` (BSD/GNU extension in `<malloc.h>` and `<stdlib.h>`)
* `res_randomid` (in `<resolv.h>`)
* `pthread_sigqueue` (GNU extension)
+ * `getloadavg` (BSD/GNU extension in <stdlib.h>)
New libc behavior in Q (API level 29):
* Whole printf family now supports the GNU `%m` extension, rather than a special-case hack in `syslog`
diff --git a/libc/Android.bp b/libc/Android.bp
index 1fc3062..681394f 100644
--- a/libc/Android.bp
+++ b/libc/Android.bp
@@ -1314,6 +1314,7 @@
"bionic/getdomainname.cpp",
"bionic/getentropy.cpp",
"bionic/gethostname.cpp",
+ "bionic/getloadavg.cpp",
"bionic/getpagesize.cpp",
"bionic/getpgrp.cpp",
"bionic/getpid.cpp",
diff --git a/libc/arch-common/bionic/crtbrand.S b/libc/arch-common/bionic/crtbrand.S
index 4b4f99c..34d6480 100644
--- a/libc/arch-common/bionic/crtbrand.S
+++ b/libc/arch-common/bionic/crtbrand.S
@@ -33,7 +33,12 @@
.long 2f-1f // int32_t namesz
.long 3f-2f // int32_t descsz
.long 1 // int32_t type
+#ifdef __ANDROID__
1:.ascii "Android\0" // char name[]
2:.long PLATFORM_SDK_VERSION // int32_t android_api
+#else
+1:.ascii "LinuxBionic\0" // char name[]
+2:
+#endif
3:
.size abitag, .-abitag
diff --git a/libc/bionic/getloadavg.cpp b/libc/bionic/getloadavg.cpp
new file mode 100644
index 0000000..28d316c
--- /dev/null
+++ b/libc/bionic/getloadavg.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <stdlib.h>
+
+#include <sys/sysinfo.h>
+
+int getloadavg(double averages[], int n) {
+ if (n < 0) return -1;
+ if (n > 3) n = 3;
+
+ struct sysinfo si;
+ if (sysinfo(&si) == -1) return -1;
+
+ for (int i = 0; i < n; ++i) {
+ averages[i] = static_cast<double>(si.loads[i]) / static_cast<double>(1 << SI_LOAD_SHIFT);
+ }
+ return n;
+}
diff --git a/libc/bionic/grp_pwd_file.h b/libc/bionic/grp_pwd_file.h
index 29d75f4..9004c4e 100644
--- a/libc/bionic/grp_pwd_file.h
+++ b/libc/bionic/grp_pwd_file.h
@@ -45,7 +45,7 @@
bool FindByName(const char* name, Line* line);
void Unmap();
- DISALLOW_COPY_AND_ASSIGN(MmapFile);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(MmapFile);
private:
enum class FileStatus {
@@ -78,7 +78,7 @@
mmap_file_.Unmap();
}
- DISALLOW_COPY_AND_ASSIGN(PasswdFile);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(PasswdFile);
private:
MmapFile mmap_file_;
@@ -94,7 +94,7 @@
mmap_file_.Unmap();
}
- DISALLOW_COPY_AND_ASSIGN(GroupFile);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(GroupFile);
private:
MmapFile mmap_file_;
diff --git a/libc/bionic/jemalloc_wrapper.cpp b/libc/bionic/jemalloc_wrapper.cpp
index 812884c..40f2a66 100644
--- a/libc/bionic/jemalloc_wrapper.cpp
+++ b/libc/bionic/jemalloc_wrapper.cpp
@@ -79,6 +79,18 @@
}
}
return 1;
+ } else if (param == M_PURGE) {
+ unsigned narenas;
+ size_t sz = sizeof(unsigned);
+ if (je_mallctl("arenas.narenas", &narenas, &sz, nullptr, 0) != 0) {
+ return 0;
+ }
+ char buffer[100];
+ snprintf(buffer, sizeof(buffer), "arena.%u.purge", narenas);
+ if (je_mallctl(buffer, nullptr, nullptr, nullptr, 0) != 0) {
+ return 0;
+ }
+ return 1;
}
return 0;
}
diff --git a/libc/bionic/locale.cpp b/libc/bionic/locale.cpp
index 2a5bcab..8358fb0 100644
--- a/libc/bionic/locale.cpp
+++ b/libc/bionic/locale.cpp
@@ -66,7 +66,7 @@
}
}
- DISALLOW_COPY_AND_ASSIGN(__locale_t);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(__locale_t);
};
size_t __ctype_get_mb_cur_max() {
diff --git a/libc/bionic/malloc_info.cpp b/libc/bionic/malloc_info.cpp
index 99caedb..9c8a4bf 100644
--- a/libc/bionic/malloc_info.cpp
+++ b/libc/bionic/malloc_info.cpp
@@ -53,7 +53,7 @@
FILE* fp;
const char* name;
- DISALLOW_COPY_AND_ASSIGN(Elem);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(Elem);
};
int malloc_info(int options, FILE* fp) {
diff --git a/libc/bionic/pthread_atfork.cpp b/libc/bionic/pthread_atfork.cpp
index 84e511c..fb12a3b 100644
--- a/libc/bionic/pthread_atfork.cpp
+++ b/libc/bionic/pthread_atfork.cpp
@@ -107,7 +107,7 @@
atfork_t* first_;
atfork_t* last_;
- DISALLOW_COPY_AND_ASSIGN(atfork_list_t);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(atfork_list_t);
};
static pthread_mutex_t g_atfork_list_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
@@ -180,4 +180,3 @@
});
pthread_mutex_unlock(&g_atfork_list_mutex);
}
-
diff --git a/libc/bionic/pthread_internal.cpp b/libc/bionic/pthread_internal.cpp
index 829194c..92786fe 100644
--- a/libc/bionic/pthread_internal.cpp
+++ b/libc/bionic/pthread_internal.cpp
@@ -54,7 +54,7 @@
private:
pthread_rwlock_t* rwlock_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedRWLock);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedRWLock);
};
typedef ScopedRWLock<true> ScopedWriteLock;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 65ec5ff..b68cb94 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -112,10 +112,6 @@
thread_local_dtor* thread_local_dtors;
- void* tls[BIONIC_TLS_SLOTS];
-
- pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
-
/*
* The dynamic linker implements dlerror(3), which makes it hard for us to implement this
* per-thread buffer by simply using malloc(3) and free(3).
@@ -124,6 +120,12 @@
char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
bionic_tls* bionic_tls;
+
+ pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
+
+ // The thread pointer (__get_tls()) points at this field. This field must come last so that
+ // an executable's TLS segment can be allocated at a fixed offset after the thread pointer.
+ void* tls[BIONIC_TLS_SLOTS];
};
__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
diff --git a/libc/bionic/scandir.cpp b/libc/bionic/scandir.cpp
index e55be42..0b39049 100644
--- a/libc/bionic/scandir.cpp
+++ b/libc/bionic/scandir.cpp
@@ -90,7 +90,7 @@
return copy;
}
- DISALLOW_COPY_AND_ASSIGN(ScandirResult);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ScandirResult);
};
int scandirat(int parent_fd, const char* dir_name, dirent*** name_list,
diff --git a/libc/bionic/system_property_set.cpp b/libc/bionic/system_property_set.cpp
index a70a376..bc3ba76 100644
--- a/libc/bionic/system_property_set.cpp
+++ b/libc/bionic/system_property_set.cpp
@@ -170,7 +170,7 @@
uint32_t uint_buf_[kUintBufSize];
size_t uint_buf_index_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(SocketWriter);
};
struct prop_msg {
diff --git a/libc/include/malloc.h b/libc/include/malloc.h
index f5fbedf..42237d0 100644
--- a/libc/include/malloc.h
+++ b/libc/include/malloc.h
@@ -161,8 +161,19 @@
*/
int malloc_info(int __must_be_zero, FILE* __fp) __INTRODUCED_IN(23);
-/** mallopt() option to set the decay time. Valid values are 0 and 1. */
+/**
+ * mallopt() option to set the decay time. Valid values are 0 and 1.
+ *
+ * Available since API level 27.
+ */
#define M_DECAY_TIME -100
+/**
+ * mallopt() option to immediately purge any memory not in use. This
+ * will release the memory back to the kernel. The value is ignored.
+ *
+ * Available since API level 28.
+ */
+#define M_PURGE -101
/**
* [mallopt(3)](http://man7.org/linux/man-pages/man3/mallopt.3.html) modifies
diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h
index 6888e8c..96a77a7 100644
--- a/libc/include/stdlib.h
+++ b/libc/include/stdlib.h
@@ -147,6 +147,15 @@
lldiv_t lldiv(long long __numerator, long long __denominator) __attribute_const__;
+/**
+ * [getloadavg(3)](http://man7.org/linux/man-pages/man3/getloadavg.3.html) queries the
+ * number of runnable processes averaged over time. The Linux kernel supports averages
+ * over the last 1, 5, and 15 minutes.
+ *
+ * Returns the number of samples written to `__averages` (at most 3), and returns -1 on failure.
+ */
+int getloadavg(double __averages[], int __n) __INTRODUCED_IN_FUTURE;
+
/* BSD compatibility. */
const char* getprogname(void) __INTRODUCED_IN(21);
void setprogname(const char* __name) __INTRODUCED_IN(21);
diff --git a/libc/libc.arm.map b/libc/libc.arm.map
index a22a8df..bd39d42 100644
--- a/libc/libc.arm.map
+++ b/libc/libc.arm.map
@@ -1432,6 +1432,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map
index 55fd587..81ff00d 100644
--- a/libc/libc.arm64.map
+++ b/libc/libc.arm64.map
@@ -1353,6 +1353,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.map.txt b/libc/libc.map.txt
index 304dbb7..934ad1f 100644
--- a/libc/libc.map.txt
+++ b/libc/libc.map.txt
@@ -1457,6 +1457,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.mips.map b/libc/libc.mips.map
index 397ff72..dc184a6 100644
--- a/libc/libc.mips.map
+++ b/libc/libc.mips.map
@@ -1416,6 +1416,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map
index 55fd587..81ff00d 100644
--- a/libc/libc.mips64.map
+++ b/libc/libc.mips64.map
@@ -1353,6 +1353,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.x86.map b/libc/libc.x86.map
index a18657c..f360dbf 100644
--- a/libc/libc.x86.map
+++ b/libc/libc.x86.map
@@ -1414,6 +1414,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map
index 55fd587..81ff00d 100644
--- a/libc/libc.x86_64.map
+++ b/libc/libc.x86_64.map
@@ -1353,6 +1353,7 @@
android_fdsan_get_error_level;
android_fdsan_set_error_level;
android_get_device_api_level;
+ getloadavg;
pthread_sigqueue;
reallocarray;
timespec_get;
diff --git a/libc/malloc_debug/DebugData.h b/libc/malloc_debug/DebugData.h
index f7cf8ab..3a36299 100644
--- a/libc/malloc_debug/DebugData.h
+++ b/libc/malloc_debug/DebugData.h
@@ -94,7 +94,7 @@
Config config_;
- DISALLOW_COPY_AND_ASSIGN(DebugData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(DebugData);
};
extern DebugData* g_debug;
diff --git a/libc/malloc_debug/GuardData.h b/libc/malloc_debug/GuardData.h
index 7b21671..b6ec889 100644
--- a/libc/malloc_debug/GuardData.h
+++ b/libc/malloc_debug/GuardData.h
@@ -56,7 +56,7 @@
virtual const char* GetTypeName() = 0;
- DISALLOW_COPY_AND_ASSIGN(GuardData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(GuardData);
};
class FrontGuardData : public GuardData {
@@ -75,7 +75,7 @@
size_t offset_ = 0;
- DISALLOW_COPY_AND_ASSIGN(FrontGuardData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(FrontGuardData);
};
class RearGuardData : public GuardData {
@@ -90,5 +90,5 @@
private:
const char* GetTypeName() override { return "REAR"; }
- DISALLOW_COPY_AND_ASSIGN(RearGuardData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(RearGuardData);
};
diff --git a/libc/malloc_debug/MapData.h b/libc/malloc_debug/MapData.h
index d8398bd..b9b697c 100644
--- a/libc/malloc_debug/MapData.h
+++ b/libc/malloc_debug/MapData.h
@@ -68,5 +68,5 @@
std::mutex m_;
std::set<MapEntry*, compare_entries> entries_;
- DISALLOW_COPY_AND_ASSIGN(MapData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(MapData);
};
diff --git a/libc/malloc_debug/OptionData.h b/libc/malloc_debug/OptionData.h
index 3fa8e14..8fb13a4 100644
--- a/libc/malloc_debug/OptionData.h
+++ b/libc/malloc_debug/OptionData.h
@@ -39,5 +39,5 @@
protected:
DebugData* debug_;
- DISALLOW_COPY_AND_ASSIGN(OptionData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(OptionData);
};
diff --git a/libc/malloc_debug/PointerData.h b/libc/malloc_debug/PointerData.h
index 62d4186..b05a763 100644
--- a/libc/malloc_debug/PointerData.h
+++ b/libc/malloc_debug/PointerData.h
@@ -184,5 +184,5 @@
static std::mutex free_pointer_mutex_;
static std::deque<FreePointerInfoType> free_pointers_;
- DISALLOW_COPY_AND_ASSIGN(PointerData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(PointerData);
};
diff --git a/libc/malloc_debug/RecordData.h b/libc/malloc_debug/RecordData.h
index 3e5ca02..a015882 100644
--- a/libc/malloc_debug/RecordData.h
+++ b/libc/malloc_debug/RecordData.h
@@ -49,7 +49,7 @@
pid_t tid_;
private:
- DISALLOW_COPY_AND_ASSIGN(RecordEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordEntry);
};
class ThreadCompleteEntry : public RecordEntry {
@@ -60,7 +60,7 @@
std::string GetString() const override;
private:
- DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ThreadCompleteEntry);
};
class AllocEntry : public RecordEntry {
@@ -72,7 +72,7 @@
void* pointer_;
private:
- DISALLOW_COPY_AND_ASSIGN(AllocEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(AllocEntry);
};
class MallocEntry : public AllocEntry {
@@ -86,7 +86,7 @@
size_t size_;
private:
- DISALLOW_COPY_AND_ASSIGN(MallocEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(MallocEntry);
};
class FreeEntry : public AllocEntry {
@@ -97,7 +97,7 @@
std::string GetString() const override;
private:
- DISALLOW_COPY_AND_ASSIGN(FreeEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(FreeEntry);
};
class CallocEntry : public MallocEntry {
@@ -111,7 +111,7 @@
size_t nmemb_;
private:
- DISALLOW_COPY_AND_ASSIGN(CallocEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(CallocEntry);
};
class ReallocEntry : public MallocEntry {
@@ -125,7 +125,7 @@
void* old_pointer_;
private:
- DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ReallocEntry);
};
// aligned_alloc, posix_memalign, memalign, pvalloc, valloc all recorded with this class.
@@ -140,7 +140,7 @@
size_t alignment_;
private:
- DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(MemalignEntry);
};
class Config;
@@ -170,5 +170,5 @@
std::atomic_bool dump_;
std::string dump_file_;
- DISALLOW_COPY_AND_ASSIGN(RecordData);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(RecordData);
};
diff --git a/libc/malloc_debug/debug_disable.h b/libc/malloc_debug/debug_disable.h
index 0049595..f9c3149 100644
--- a/libc/malloc_debug/debug_disable.h
+++ b/libc/malloc_debug/debug_disable.h
@@ -57,5 +57,5 @@
private:
bool disabled_;
- DISALLOW_COPY_AND_ASSIGN(ScopedDisableDebugCalls);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedDisableDebugCalls);
};
diff --git a/libc/private/ErrnoRestorer.h b/libc/private/ErrnoRestorer.h
index f467393..52e115a 100644
--- a/libc/private/ErrnoRestorer.h
+++ b/libc/private/ErrnoRestorer.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef ERRNO_RESTORER_H
-#define ERRNO_RESTORER_H
+#pragma once
#include <errno.h>
@@ -37,7 +36,5 @@
private:
int saved_errno_;
- DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ErrnoRestorer);
};
-
-#endif // ERRNO_RESTORER_H
diff --git a/libc/private/KernelArgumentBlock.h b/libc/private/KernelArgumentBlock.h
index e05ceb9..886dd32 100644
--- a/libc/private/KernelArgumentBlock.h
+++ b/libc/private/KernelArgumentBlock.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef KERNEL_ARGUMENT_BLOCK_H
-#define KERNEL_ARGUMENT_BLOCK_H
+#pragma once
#include <elf.h>
#include <link.h>
@@ -71,7 +70,5 @@
libc_shared_globals* shared_globals;
private:
- DISALLOW_COPY_AND_ASSIGN(KernelArgumentBlock);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(KernelArgumentBlock);
};
-
-#endif // KERNEL_ARGUMENT_BLOCK_H
diff --git a/libc/private/ScopedPthreadMutexLocker.h b/libc/private/ScopedPthreadMutexLocker.h
index 58462e3..1c1e4a7 100644
--- a/libc/private/ScopedPthreadMutexLocker.h
+++ b/libc/private/ScopedPthreadMutexLocker.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef SCOPED_PTHREAD_MUTEX_LOCKER_H
-#define SCOPED_PTHREAD_MUTEX_LOCKER_H
+#pragma once
#include <pthread.h>
@@ -34,7 +33,5 @@
private:
pthread_mutex_t* mu_;
- DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(ScopedPthreadMutexLocker);
};
-
-#endif // SCOPED_PTHREAD_MUTEX_LOCKER_H
diff --git a/libc/private/ScopedReaddir.h b/libc/private/ScopedReaddir.h
index 1a59e1a..dc22309 100644
--- a/libc/private/ScopedReaddir.h
+++ b/libc/private/ScopedReaddir.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef SCOPED_READDIR_H
-#define SCOPED_READDIR_H
+#pragma once
#include <dirent.h>
@@ -47,7 +46,5 @@
private:
DIR* dir_;
- DISALLOW_COPY_AND_ASSIGN(ScopedReaddir);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedReaddir);
};
-
-#endif // SCOPED_READDIR_H
diff --git a/libc/private/ScopedSignalBlocker.h b/libc/private/ScopedSignalBlocker.h
index d1cf629..10aacb3 100644
--- a/libc/private/ScopedSignalBlocker.h
+++ b/libc/private/ScopedSignalBlocker.h
@@ -46,5 +46,5 @@
sigset64_t old_set_;
- DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedSignalBlocker);
};
diff --git a/libc/private/WriteProtected.h b/libc/private/WriteProtected.h
index 7a6b098..69a6822 100644
--- a/libc/private/WriteProtected.h
+++ b/libc/private/WriteProtected.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef _PRIVATE_WRITEPROTECTED_H
-#define _PRIVATE_WRITEPROTECTED_H
+#pragma once
#include <errno.h>
#include <string.h>
@@ -33,7 +32,7 @@
char padding[PAGE_SIZE];
WriteProtectedContents() = default;
- DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtectedContents);
} __attribute__((aligned(PAGE_SIZE)));
// Write protected wrapper class that aligns its contents to a page boundary,
@@ -49,7 +48,7 @@
public:
WriteProtected() = default;
- DISALLOW_COPY_AND_ASSIGN(WriteProtected);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(WriteProtected);
void initialize() {
// Not strictly necessary, but this will hopefully segfault if we initialize
@@ -82,5 +81,3 @@
}
}
};
-
-#endif
diff --git a/libc/private/bionic_lock.h b/libc/private/bionic_lock.h
index 54168d3..eebfeff 100644
--- a/libc/private/bionic_lock.h
+++ b/libc/private/bionic_lock.h
@@ -25,8 +25,8 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
-#ifndef _BIONIC_LOCK_H
-#define _BIONIC_LOCK_H
+
+#pragma once
#include <stdatomic.h>
#include "private/bionic_futex.h"
@@ -85,10 +85,8 @@
lock_.unlock();
}
- DISALLOW_COPY_AND_ASSIGN(LockGuard);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(LockGuard);
private:
Lock& lock_;
};
-
-#endif // _BIONIC_LOCK_H
diff --git a/libc/private/bionic_macros.h b/libc/private/bionic_macros.h
index 0a36cdb..4800e3a 100644
--- a/libc/private/bionic_macros.h
+++ b/libc/private/bionic_macros.h
@@ -14,31 +14,17 @@
* limitations under the License.
*/
-#ifndef _BIONIC_MACROS_H_
-#define _BIONIC_MACROS_H_
+#pragma once
#include <stdint.h>
-// Frameworks OpenGL code currently leaks this header and allows
-// collisions with other declarations, e.g., from libnativehelper.
-// TODO: Remove once cleaned up. b/18334516
-#if !defined(DISALLOW_COPY_AND_ASSIGN)
-// DISALLOW_COPY_AND_ASSIGN disallows the copy and operator= functions.
-// It goes in the private: declarations in a class.
-#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
- TypeName(const TypeName&) = delete; \
+#define BIONIC_DISALLOW_COPY_AND_ASSIGN(TypeName) \
+ TypeName(const TypeName&) = delete; \
void operator=(const TypeName&) = delete
-#endif // !defined(DISALLOW_COPY_AND_ASSIGN)
-// A macro to disallow all the implicit constructors, namely the
-// default constructor, copy constructor and operator= functions.
-//
-// This should be used in the private: declarations for a class
-// that wants to prevent anyone from instantiating it. This is
-// especially useful for classes containing only static methods.
-#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
- TypeName() = delete; \
- DISALLOW_COPY_AND_ASSIGN(TypeName)
+#define BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
+ TypeName() = delete; \
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(TypeName)
#define BIONIC_ROUND_UP_POWER_OF_2(value) \
((sizeof(value) == 8) \
@@ -101,5 +87,3 @@
#else
#define __BIONIC_FALLTHROUGH
#endif
-
-#endif // _BIONIC_MACROS_H_
diff --git a/libc/private/bionic_systrace.h b/libc/private/bionic_systrace.h
index 304fb80..86d2a08 100644
--- a/libc/private/bionic_systrace.h
+++ b/libc/private/bionic_systrace.h
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef BIONIC_SYSTRACE_H
-#define BIONIC_SYSTRACE_H
+#pragma once
#include "bionic_macros.h"
@@ -31,10 +30,8 @@
void End();
private:
bool called_end_;
- DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ScopedTrace);
};
void bionic_trace_begin(const char* message);
void bionic_trace_end();
-
-#endif
diff --git a/libc/system_properties/include/system_properties/context_node.h b/libc/system_properties/include/system_properties/context_node.h
index 35d0e92..20f4013 100644
--- a/libc/system_properties/include/system_properties/context_node.h
+++ b/libc/system_properties/include/system_properties/context_node.h
@@ -42,7 +42,7 @@
Unmap();
}
- DISALLOW_COPY_AND_ASSIGN(ContextNode);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(ContextNode);
bool Open(bool access_rw, bool* fsetxattr_failed);
bool CheckAccessAndOpen();
diff --git a/libc/system_properties/include/system_properties/prop_area.h b/libc/system_properties/include/system_properties/prop_area.h
index 2c25337..a69f90e 100644
--- a/libc/system_properties/include/system_properties/prop_area.h
+++ b/libc/system_properties/include/system_properties/prop_area.h
@@ -86,7 +86,7 @@
}
private:
- DISALLOW_COPY_AND_ASSIGN(prop_bt);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(prop_bt);
};
class prop_area {
@@ -158,5 +158,5 @@
uint32_t reserved_[28];
char data_[0];
- DISALLOW_COPY_AND_ASSIGN(prop_area);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(prop_area);
};
diff --git a/libc/system_properties/include/system_properties/prop_info.h b/libc/system_properties/include/system_properties/prop_info.h
index a127550..27b29c8 100644
--- a/libc/system_properties/include/system_properties/prop_info.h
+++ b/libc/system_properties/include/system_properties/prop_info.h
@@ -83,7 +83,7 @@
prop_info(const char* name, uint32_t namelen, uint32_t long_offset);
private:
- DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
+ BIONIC_DISALLOW_IMPLICIT_CONSTRUCTORS(prop_info);
};
static_assert(sizeof(prop_info) == 96, "sizeof struct prop_info must be 96 bytes");
diff --git a/libc/system_properties/include/system_properties/system_properties.h b/libc/system_properties/include/system_properties/system_properties.h
index 52ffcaf..cad29cc 100644
--- a/libc/system_properties/include/system_properties/system_properties.h
+++ b/libc/system_properties/include/system_properties/system_properties.h
@@ -52,7 +52,7 @@
explicit SystemProperties(bool initialized) : initialized_(initialized) {
}
- DISALLOW_COPY_AND_ASSIGN(SystemProperties);
+ BIONIC_DISALLOW_COPY_AND_ASSIGN(SystemProperties);
bool Init(const char* filename);
bool AreaInit(const char* filename, bool* fsetxattr_failed);
diff --git a/linker/Android.bp b/linker/Android.bp
index 697c260..779cd3f 100644
--- a/linker/Android.bp
+++ b/linker/Android.bp
@@ -15,7 +15,7 @@
// We need to access Bionic private headers in the linker.
include_dirs: ["bionic/libc"],
- static_libs: ["libasync_safe"],
+ static_libs: ["libasync_safe", "libbase"],
}
// This is used for bionic on (host) Linux to bootstrap our linker embedded into
diff --git a/linker/linked_list.h b/linker/linked_list.h
index 7f70a2c..5473ca0 100644
--- a/linker/linked_list.h
+++ b/linker/linked_list.h
@@ -28,7 +28,7 @@
#pragma once
-#include "private/bionic_macros.h"
+#include <android-base/macros.h>
template<typename T>
struct LinkedListEntry {
diff --git a/linker/linker.cpp b/linker/linker.cpp
index b605ed9..e866c3d 100644
--- a/linker/linker.cpp
+++ b/linker/linker.cpp
@@ -1086,6 +1086,7 @@
fd = open_library_on_paths(zip_archive_cache, name, file_offset, needed_by->get_dt_runpath(), realpath);
// Check if the library is accessible
if (fd != -1 && !ns->is_accessible(*realpath)) {
+ close(fd);
fd = -1;
}
}
@@ -1318,6 +1319,15 @@
}
}
+#if !defined(__ANDROID__)
+ // Bionic on the host currently uses some Android prebuilts, which don't set
+ // DT_RUNPATH with any relative paths, so they can't find their dependencies.
+ // b/118058804
+ if (si->get_dt_runpath().empty()) {
+ si->set_dt_runpath("$ORIGIN/../lib64:$ORIGIN/lib64");
+ }
+#endif
+
for_each_dt_needed(task->get_elf_reader(), [&](const char* name) {
load_tasks->push_back(LoadTask::create(name, si, ns, task->get_readers_map()));
});
diff --git a/linker/linker_block_allocator.h b/linker/linker_block_allocator.h
index b501659..bd44fc8 100644
--- a/linker/linker_block_allocator.h
+++ b/linker/linker_block_allocator.h
@@ -30,7 +30,8 @@
#include <stdlib.h>
#include <limits.h>
-#include "private/bionic_macros.h"
+
+#include <android-base/macros.h>
struct LinkerBlockAllocatorPage;
diff --git a/linker/linker_common_types.h b/linker/linker_common_types.h
index ffa4066..ae78aa9 100644
--- a/linker/linker_common_types.h
+++ b/linker/linker_common_types.h
@@ -31,6 +31,8 @@
#include <android/dlext.h>
#include "linked_list.h"
+#include <android-base/macros.h>
+
// TODO(dimitry): move this to linker_defines.h? Unless it is removed by
// consequent refactoring steps.
diff --git a/linker/linker_config.h b/linker/linker_config.h
index e117aea..24c44f4 100644
--- a/linker/linker_config.h
+++ b/linker/linker_config.h
@@ -32,13 +32,14 @@
#include <stdlib.h>
#include <limits.h>
-#include "private/bionic_macros.h"
#include <memory>
#include <string>
#include <vector>
#include <unordered_map>
+#include <android-base/macros.h>
+
class NamespaceLinkConfig {
public:
NamespaceLinkConfig() = default;
diff --git a/linker/linker_logger.h b/linker/linker_logger.h
index 9ce438e..1828799 100644
--- a/linker/linker_logger.h
+++ b/linker/linker_logger.h
@@ -30,9 +30,11 @@
#include <stdlib.h>
#include <limits.h>
-#include "private/bionic_macros.h"
+
#include "private/bionic_systrace.h"
+#include <android-base/macros.h>
+
#define LD_LOG(type, x...) \
{ \
g_linker_logger.Log(type, x); \
diff --git a/linker/linker_mapped_file_fragment.h b/linker/linker_mapped_file_fragment.h
index f7872bd..91e094f 100644
--- a/linker/linker_mapped_file_fragment.h
+++ b/linker/linker_mapped_file_fragment.h
@@ -30,7 +30,7 @@
#include <unistd.h>
-#include "private/bionic_macros.h"
+#include <android-base/macros.h>
class MappedFileFragment {
public:
diff --git a/linker/linker_wrapper.cpp b/linker/linker_wrapper.cpp
index 571d3ab..fc673aa 100644
--- a/linker/linker_wrapper.cpp
+++ b/linker/linker_wrapper.cpp
@@ -28,9 +28,27 @@
#include "private/KernelArgumentBlock.h"
-extern const char linker_code_start;
-extern const char original_start;
-extern const char linker_entry;
+extern const char linker_offset;
+
+// This will be replaced by host_bionic_inject, but must be non-zero
+// here so that it's placed in the data section.
+uintptr_t original_start = 42;
+
+/* Find the load bias and base address of an executable or shared object loaded
+ * by the kernel. The ELF file's PHDR table must have a PT_PHDR entry.
+ *
+ * A VDSO doesn't have a PT_PHDR entry in its PHDR table.
+ */
+static void get_elf_base_from_phdr(const ElfW(Phdr)* phdr_table, size_t phdr_count,
+ ElfW(Addr)* base, ElfW(Addr)* load_bias) {
+ for (size_t i = 0; i < phdr_count; ++i) {
+ if (phdr_table[i].p_type == PT_PHDR) {
+ *load_bias = reinterpret_cast<ElfW(Addr)>(phdr_table) - phdr_table[i].p_vaddr;
+ *base = reinterpret_cast<ElfW(Addr)>(phdr_table) - phdr_table[i].p_offset;
+ return;
+ }
+ }
+}
/*
* This is the entry point for the linker wrapper, which finds
@@ -39,21 +57,26 @@
extern "C" ElfW(Addr) __linker_init(void* raw_args) {
KernelArgumentBlock args(raw_args);
- static uintptr_t linker_offset = reinterpret_cast<uintptr_t>(&linker_code_start);
- static uintptr_t linktime_addr = reinterpret_cast<uintptr_t>(&linktime_addr);
- ElfW(Addr) my_addr = reinterpret_cast<uintptr_t>(&linktime_addr) - linktime_addr;
+ ElfW(Addr) base_addr = 0;
+ ElfW(Addr) load_bias = 0;
+ get_elf_base_from_phdr(
+ reinterpret_cast<ElfW(Phdr)*>(args.getauxval(AT_PHDR)), args.getauxval(AT_PHNUM),
+ &base_addr, &load_bias);
- // Set AT_ENTRY to the proper entry point
+ ElfW(Addr) linker_addr = base_addr + reinterpret_cast<uintptr_t>(&linker_offset);
+ ElfW(Addr) linker_entry_offset = reinterpret_cast<ElfW(Ehdr)*>(linker_addr)->e_entry;
+
for (ElfW(auxv_t)* v = args.auxv; v->a_type != AT_NULL; ++v) {
if (v->a_type == AT_BASE) {
- v->a_un.a_val = my_addr + linker_offset;
+ // Set AT_BASE to the embedded linker
+ v->a_un.a_val = linker_addr;
}
if (v->a_type == AT_ENTRY) {
- v->a_un.a_val = my_addr + reinterpret_cast<uintptr_t>(&original_start);
+ // Set AT_ENTRY to the proper entry point
+ v->a_un.a_val = base_addr + original_start;
}
}
- // Return address of linker entry point -- may need to ensure that raw_args
- // was saved.
- return my_addr + linker_offset + reinterpret_cast<uintptr_t>(&linker_entry);
+ // Return address of linker entry point
+ return linker_addr + linker_entry_offset;
}
diff --git a/tests/TemporaryFile.h b/tests/TemporaryFile.h
index 8af92d4..7853781 100644
--- a/tests/TemporaryFile.h
+++ b/tests/TemporaryFile.h
@@ -17,7 +17,7 @@
#include <fcntl.h>
#include <unistd.h>
-#include "private/bionic_macros.h"
+#include <android-base/macros.h>
template <typename T = int (*)(char*)>
class GenericTemporaryFile {
diff --git a/tests/grp_pwd_test.cpp b/tests/grp_pwd_test.cpp
index 1c36dcf..ca34205 100644
--- a/tests/grp_pwd_test.cpp
+++ b/tests/grp_pwd_test.cpp
@@ -250,7 +250,9 @@
// Upgrading devices launched before API level 28 may not comply with the below check.
// Due to the difficulty in changing uids after launch, it is waived for these devices.
- if (android::base::GetIntProperty("ro.product.first_api_level", 0) < 28) {
+ // Also grant this check for device launched with 28(P) to give the vendor time to
+ // adopt the AID scheme.
+ if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 28) {
return;
}
@@ -584,6 +586,10 @@
TEST(pwd, vendor_prefix_users) {
#if defined(__BIONIC__)
+ if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 28) {
+ return;
+ }
+
TestAidNamePrefix("/vendor/etc/passwd");
#else
print_no_getpwnam_test_info();
@@ -592,6 +598,10 @@
TEST(pwd, vendor_prefix_groups) {
#if defined(__BIONIC__)
+ if (android::base::GetIntProperty("ro.product.first_api_level", 0) <= 28) {
+ return;
+ }
+
TestAidNamePrefix("/vendor/etc/group");
#else
print_no_getgrnam_test_info();
diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp
index e68f1ff..84ce531 100644
--- a/tests/pthread_test.cpp
+++ b/tests/pthread_test.cpp
@@ -34,12 +34,12 @@
#include <future>
#include <vector>
+#include <android-base/macros.h>
#include <android-base/parseint.h>
#include <android-base/scopeguard.h>
#include <android-base/strings.h>
#include "private/bionic_constants.h"
-#include "private/bionic_macros.h"
#include "BionicDeathTest.h"
#include "SignalUtils.h"
#include "utils.h"
diff --git a/tests/stdlib_test.cpp b/tests/stdlib_test.cpp
index 6e41555..1c3e1d1 100644
--- a/tests/stdlib_test.cpp
+++ b/tests/stdlib_test.cpp
@@ -816,3 +816,35 @@
ASSERT_EQ(LLONG_MAX, llabs(-LLONG_MAX));
ASSERT_EQ(LLONG_MAX, llabs(LLONG_MAX));
}
+
+TEST(stdlib, getloadavg) {
+ double load[3];
+
+ // The second argument should have been size_t.
+ ASSERT_EQ(-1, getloadavg(load, -1));
+ ASSERT_EQ(-1, getloadavg(load, INT_MIN));
+
+ // Zero is a no-op.
+ ASSERT_EQ(0, getloadavg(load, 0));
+
+ // The Linux kernel doesn't support more than 3 (but you can ask for fewer).
+ ASSERT_EQ(1, getloadavg(load, 1));
+ ASSERT_EQ(2, getloadavg(load, 2));
+ ASSERT_EQ(3, getloadavg(load, 3));
+ ASSERT_EQ(3, getloadavg(load, 4));
+ ASSERT_EQ(3, getloadavg(load, INT_MAX));
+
+ // Read /proc/loadavg and check that it's "close enough".
+ load[0] = nan("");
+ double expected[3];
+ std::unique_ptr<FILE, decltype(&fclose)> fp{fopen("/proc/loadavg", "re"), fclose};
+ ASSERT_EQ(3, fscanf(fp.get(), "%lf %lf %lf", &expected[0], &expected[1], &expected[2]));
+ ASSERT_EQ(3, getloadavg(load, 3));
+
+ // It's probably too flaky if we look at the 1-minute average, so we just place a NaN there
+ // and check that it's overwritten with _something_.
+ ASSERT_FALSE(isnan(load[0]));
+ // For the others, rounding to an integer is pessimistic but at least gives us a sanity check.
+ ASSERT_DOUBLE_EQ(rint(expected[1]), rint(load[1]));
+ ASSERT_DOUBLE_EQ(rint(expected[2]), rint(load[2]));
+}