summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--adb/OVERVIEW.TXT19
-rw-r--r--adb/SYNC.TXT25
-rw-r--r--adb/file_sync_service.cpp2
-rw-r--r--adb/set_verity_enable_state_service.cpp14
-rw-r--r--adb/sysdeps.h16
-rw-r--r--base/Android.bp1
-rw-r--r--base/logging_test.cpp2
-rw-r--r--base/utf8.cpp2
-rwxr-xr-xbootstat/boot_reason_test.sh7
-rw-r--r--bootstat/bootstat.cpp10
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp7
-rw-r--r--fastboot/Android.mk15
-rw-r--r--fastboot/fastboot.cpp17
-rw-r--r--fastboot/fs.cpp43
-rw-r--r--fs_mgr/fs_mgr_slotselect.cpp15
-rw-r--r--init/action.cpp4
-rw-r--r--init/action.h2
-rw-r--r--init/builtins.cpp21
-rw-r--r--init/capabilities.cpp13
-rw-r--r--init/capabilities.h1
-rw-r--r--init/init_first_stage.cpp5
-rw-r--r--init/init_test.cpp40
-rw-r--r--init/parser.cpp20
-rw-r--r--init/parser.h18
-rw-r--r--init/service.cpp31
-rw-r--r--init/service.h6
-rw-r--r--init/subcontext.cpp14
-rw-r--r--init/ueventd_parser.cpp4
-rw-r--r--init/ueventd_parser.h2
-rw-r--r--init/util.cpp19
-rw-r--r--libbacktrace/UnwindStackMap.cpp12
-rw-r--r--libbacktrace/backtrace_test.cpp57
-rw-r--r--libcutils/Android.bp56
-rw-r--r--libcutils/android_get_control_file.cpp5
-rw-r--r--libcutils/android_reboot.cpp (renamed from libcutils/android_reboot.c)6
-rw-r--r--libcutils/ashmem-dev.cpp (renamed from libcutils/ashmem-dev.c)10
-rw-r--r--libcutils/ashmem-host.cpp (renamed from libcutils/ashmem-host.c)11
-rw-r--r--libcutils/canned_fs_config.cpp (renamed from libcutils/canned_fs_config.c)8
-rw-r--r--libcutils/config_utils.cpp (renamed from libcutils/config_utils.c)11
-rw-r--r--libcutils/dlmalloc_stubs.c38
-rw-r--r--libcutils/fs.cpp (renamed from libcutils/fs.c)36
-rw-r--r--libcutils/fs_config.cpp3
-rw-r--r--libcutils/hashmap.cpp (renamed from libcutils/hashmap.c)9
-rw-r--r--libcutils/include/cutils/android_reboot.h1
-rw-r--r--libcutils/include/cutils/partition_utils.h2
-rw-r--r--libcutils/include/cutils/qtaguid.h12
-rw-r--r--libcutils/include/cutils/record_stream.h1
-rw-r--r--libcutils/include/private/canned_fs_config.h4
-rw-r--r--libcutils/include/private/fs_config.h1
-rw-r--r--libcutils/iosched_policy.cpp (renamed from libcutils/iosched_policy.c)6
-rw-r--r--libcutils/klog.cpp3
-rw-r--r--libcutils/load_file.cpp (renamed from libcutils/load_file.c)2
-rw-r--r--libcutils/multiuser.cpp (renamed from libcutils/multiuser.c)6
-rw-r--r--libcutils/native_handle.cpp (renamed from libcutils/native_handle.c)2
-rw-r--r--libcutils/partition_utils.cpp (renamed from libcutils/partition_utils.c)2
-rw-r--r--libcutils/properties.cpp3
-rw-r--r--libcutils/qtaguid.cpp126
-rw-r--r--libcutils/record_stream.cpp (renamed from libcutils/record_stream.c)3
-rw-r--r--libcutils/sched_policy.cpp3
-rw-r--r--libcutils/socket_inaddr_any_server_unix.cpp (renamed from libcutils/socket_inaddr_any_server_unix.c)4
-rw-r--r--libcutils/socket_inaddr_any_server_windows.cpp (renamed from libcutils/socket_inaddr_any_server_windows.c)4
-rw-r--r--libcutils/socket_local_client_unix.cpp (renamed from libcutils/socket_local_client_unix.c)4
-rw-r--r--libcutils/socket_local_server_unix.cpp (renamed from libcutils/socket_local_server_unix.c)4
-rw-r--r--libcutils/socket_network_client_unix.cpp (renamed from libcutils/socket_network_client_unix.c)4
-rw-r--r--libcutils/socket_network_client_windows.cpp (renamed from libcutils/socket_network_client_windows.c)0
-rw-r--r--libcutils/sockets_unix.cpp3
-rw-r--r--libcutils/sockets_windows.cpp4
-rw-r--r--libcutils/str_parms.cpp (renamed from libcutils/str_parms.c)44
-rw-r--r--libcutils/strdup16to8.cpp (renamed from libcutils/strdup16to8.c)11
-rw-r--r--libcutils/strdup8to16.cpp (renamed from libcutils/strdup8to16.c)5
-rw-r--r--libcutils/tests/multiuser_test.cpp12
-rw-r--r--libcutils/tests/trace-dev_test.cpp2
-rw-r--r--libcutils/threads.cpp (renamed from libcutils/threads.c)4
-rw-r--r--libcutils/trace-container.cpp (renamed from libcutils/trace-container.c)2
-rw-r--r--libcutils/trace-dev.cpp (renamed from libcutils/trace-dev.c)2
-rw-r--r--libcutils/trace-host.cpp (renamed from libcutils/trace-host.c)0
-rw-r--r--liblog/include/log/log.h2
-rw-r--r--liblog/include/log/log_id.h5
-rw-r--r--liblog/log_event_list.c6
-rw-r--r--liblog/logger_name.c3
-rw-r--r--liblog/logger_write.c13
-rw-r--r--libqtaguid/Android.bp56
-rw-r--r--libqtaguid/include/qtaguid/qtaguid.h62
-rw-r--r--libqtaguid/qtaguid.c (renamed from libcutils/qtaguid.c)55
-rw-r--r--libsysutils/src/NetlinkEvent.cpp2
-rw-r--r--libunwindstack/Android.bp3
-rw-r--r--libunwindstack/DwarfEhFrame.h2
-rw-r--r--libunwindstack/Elf.cpp17
-rw-r--r--libunwindstack/MapInfo.cpp4
-rw-r--r--libunwindstack/Maps.cpp98
-rw-r--r--libunwindstack/Unwinder.cpp28
-rw-r--r--libunwindstack/include/unwindstack/Elf.h7
-rw-r--r--libunwindstack/include/unwindstack/MapInfo.h26
-rw-r--r--libunwindstack/include/unwindstack/Maps.h8
-rw-r--r--libunwindstack/include/unwindstack/RegsGetLocal.h4
-rw-r--r--libunwindstack/include/unwindstack/Unwinder.h2
-rw-r--r--libunwindstack/tests/DwarfEhFrameTest.cpp48
-rw-r--r--libunwindstack/tests/DwarfEhFrameWithHdrTest.cpp8
-rw-r--r--libunwindstack/tests/ElfTest.cpp12
-rw-r--r--libunwindstack/tests/ElfTestUtils.cpp4
-rw-r--r--libunwindstack/tests/ElfTestUtils.h3
-rw-r--r--libunwindstack/tests/MapInfoCreateMemoryTest.cpp10
-rw-r--r--libunwindstack/tests/MapInfoGetElfTest.cpp149
-rw-r--r--libunwindstack/tests/MapsTest.cpp378
-rw-r--r--libunwindstack/tests/RegsTest.cpp21
-rw-r--r--libunwindstack/tests/UnwindOfflineTest.cpp153
-rw-r--r--libunwindstack/tests/UnwindTest.cpp35
-rw-r--r--libunwindstack/tests/UnwinderTest.cpp61
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm32/libbase.sobin0 -> 62552 bytes
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm32/libc.sobin0 -> 840504 bytes
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm32/maps.txt4
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm32/regs.txt3
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm32/stack.databin0 -> 232 bytes
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm64/libunwindstack_testbin0 -> 5198416 bytes
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm64/maps.txt2
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm64/regs.txt4
-rw-r--r--libunwindstack/tests/files/offline/straddle_arm64/stack.databin0 -> 232 bytes
-rw-r--r--libunwindstack/tools/unwind_info.cpp25
-rw-r--r--libutils/Android.bp7
-rw-r--r--libutils/Threads.cpp4
-rw-r--r--libutils/include/utils/String16.h2
-rw-r--r--libutils/include/utils/String8.h1
-rw-r--r--libutils/misc.cpp6
-rw-r--r--libvndksupport/linker.c12
-rw-r--r--logcat/Android.bp1
-rw-r--r--logcat/event.logtags3
-rw-r--r--logcat/logcat.cpp5
-rw-r--r--rootdir/Android.mk44
-rw-r--r--rootdir/etc/ld.config.txt.in2
-rw-r--r--rootdir/init.rc10
-rw-r--r--trusty/keymaster/trusty_keymaster_ipc.cpp5
131 files changed, 1564 insertions, 804 deletions
diff --git a/adb/OVERVIEW.TXT b/adb/OVERVIEW.TXT
index c40695af6..29a699254 100644
--- a/adb/OVERVIEW.TXT
+++ b/adb/OVERVIEW.TXT
@@ -7,16 +7,16 @@ The Android Debug Bridge (ADB) is used to:
7- keep track of all Android devices and emulators instances 7- keep track of all Android devices and emulators instances
8 connected to or running on a given host developer machine 8 connected to or running on a given host developer machine
9 9
10- implement various control commands (e.g. "adb shell", "adb pull", etc..) 10- implement various control commands (e.g. "adb shell", "adb pull", etc.)
11 for the benefit of clients (command-line users, or helper programs like 11 for the benefit of clients (command-line users, or helper programs like
12 DDMS). These commands are what is called a 'service' in ADB. 12 DDMS). These commands are called 'services' in ADB.
13 13
14As a whole, everything works through the following components: 14As a whole, everything works through the following components:
15 15
16 1. The ADB server 16 1. The ADB server
17 17
18 This is a background process that runs on the host machine. Its purpose 18 This is a background process that runs on the host machine. Its purpose
19 if to sense the USB ports to know when devices are attached/removed, 19 is to sense the USB ports to know when devices are attached/removed,
20 as well as when emulator instances start/stop. 20 as well as when emulator instances start/stop.
21 21
22 It thus maintains a list of "connected devices" and assigns a 'state' 22 It thus maintains a list of "connected devices" and assigns a 'state'
@@ -40,7 +40,7 @@ As a whole, everything works through the following components:
40 meaning that the ADB server detected a new device/emulator, but could not 40 meaning that the ADB server detected a new device/emulator, but could not
41 connect to the adbd daemon. 41 connect to the adbd daemon.
42 42
43 the BOOTLOADER and RECOVERY states correspond to alternate states of 43 The BOOTLOADER and RECOVERY states correspond to alternate states of
44 devices when they are in the bootloader or recovery mode. 44 devices when they are in the bootloader or recovery mode.
45 45
46 3. The ADB command-line client 46 3. The ADB command-line client
@@ -49,8 +49,7 @@ As a whole, everything works through the following components:
49 or a script. It first tries to locate the ADB server on the host machine, 49 or a script. It first tries to locate the ADB server on the host machine,
50 and will start one automatically if none is found. 50 and will start one automatically if none is found.
51 51
52 then, the client sends its service requests to the ADB server. It doesn't 52 Then, the client sends its service requests to the ADB server.
53 need to know.
54 53
55 Currently, a single 'adb' binary is used for both the server and client. 54 Currently, a single 'adb' binary is used for both the server and client.
56 this makes distribution and starting the server easier. 55 this makes distribution and starting the server easier.
@@ -61,13 +60,13 @@ As a whole, everything works through the following components:
61 There are essentially two kinds of services that a client can talk to. 60 There are essentially two kinds of services that a client can talk to.
62 61
63 Host Services: 62 Host Services:
64 these services run within the ADB Server and thus do not need to 63 These services run within the ADB Server and thus do not need to
65 communicate with a device at all. A typical example is "adb devices" 64 communicate with a device at all. A typical example is "adb devices"
66 which is used to return the list of currently known devices and their 65 which is used to return the list of currently known devices and their
67 state. They are a few couple other services though. 66 states. They are a few other services though.
68 67
69 Local Services: 68 Local Services:
70 these services either run within the adbd daemon, or are started by 69 These services either run within the adbd daemon, or are started by
71 it on the device. The ADB server is used to multiplex streams 70 it on the device. The ADB server is used to multiplex streams
72 between the client and the service running in adbd. In this case 71 between the client and the service running in adbd. In this case
73 its role is to initiate the connection, then of being a pass-through 72 its role is to initiate the connection, then of being a pass-through
@@ -109,7 +108,7 @@ II. Protocol details:
109 108
110 Note that the connection is still alive after an OKAY, which allows the 109 Note that the connection is still alive after an OKAY, which allows the
111 client to make other requests. But in certain cases, an OKAY will even 110 client to make other requests. But in certain cases, an OKAY will even
112 change the state of the connection. 111 change the state of the connection.
113 112
114 For example, the case of the 'host:transport:<serialnumber>' request, 113 For example, the case of the 'host:transport:<serialnumber>' request,
115 where '<serialnumber>' is used to identify a given device/emulator; after 114 where '<serialnumber>' is used to identify a given device/emulator; after
diff --git a/adb/SYNC.TXT b/adb/SYNC.TXT
index 06d7804f4..4445a7617 100644
--- a/adb/SYNC.TXT
+++ b/adb/SYNC.TXT
@@ -1,4 +1,4 @@
1This file tries to document file related requests a client can make 1This file tries to document file-related requests a client can make
2to the ADB server of an adbd daemon. See the OVERVIEW.TXT document 2to the ADB server of an adbd daemon. See the OVERVIEW.TXT document
3to understand what's going on here. See the SERVICES.TXT to learn more 3to understand what's going on here. See the SERVICES.TXT to learn more
4about the other requests that are possible. 4about the other requests that are possible.
@@ -8,16 +8,16 @@ SYNC SERVICES:
8 8
9Requesting the sync service ("sync:") using the protocol as described in 9Requesting the sync service ("sync:") using the protocol as described in
10SERVICES.TXT sets the connection in sync mode. This mode is a binary mode that 10SERVICES.TXT sets the connection in sync mode. This mode is a binary mode that
11differ from the regular adb protocol. The connection stays in sync mode until 11differs from the regular adb protocol. The connection stays in sync mode until
12explicitly terminated (see below). 12explicitly terminated (see below).
13 13
14After the initial "sync:" command is sent the server must respond with either 14After the initial "sync:" command is sent the server must respond with either
15"OKAY" or "FAIL" as per usual. 15"OKAY" or "FAIL" as per usual.
16 16
17In sync mode both the server and the client will frequently use eight-byte 17In sync mode both the server and the client will frequently use eight-byte
18packets to communicate in this document called sync request and sync 18packets to communicate. In this document these are called sync requests and sync
19responses. The first four bytes is an id and specifies sync request is 19responses. The first four bytes are an id that specifies the sync request. It is
20represented by four utf-8 characters. The last four bytes is a Little-Endian 20represented by four utf-8 characters. The last four bytes are a Little-Endian
21integer, with various uses. This number will be called "length" below. In fact 21integer, with various uses. This number will be called "length" below. In fact
22all binary integers are Little-Endian in the sync mode. Sync mode is 22all binary integers are Little-Endian in the sync mode. Sync mode is
23implicitly exited after each sync request, and normal adb communication 23implicitly exited after each sync request, and normal adb communication
@@ -29,8 +29,8 @@ RECV - Retrieve a file from device
29SEND - Send a file to device 29SEND - Send a file to device
30STAT - Stat a file 30STAT - Stat a file
31 31
32For all of the sync request above the must be followed by length number of 32All of the sync requests above must be followed by "length": the number of
33bytes containing an utf-8 string with a remote filename. 33bytes containing a utf-8 string with a remote filename.
34 34
35LIST: 35LIST:
36Lists files in the directory specified by the remote filename. The server will 36Lists files in the directory specified by the remote filename. The server will
@@ -45,7 +45,7 @@ The directory entries will be returned in the following form
456. length number of bytes containing an utf-8 string representing the file 456. length number of bytes containing an utf-8 string representing the file
46 name. 46 name.
47 47
48When an sync response "DONE" is received the listing is done. 48When a sync response "DONE" is received the listing is done.
49 49
50SEND: 50SEND:
51The remote file name is split into two parts separated by the last 51The remote file name is split into two parts separated by the last
@@ -65,7 +65,7 @@ transferred. Each chunk must not be larger than 64k.
65 65
66When the file is transferred a sync request "DONE" is sent, where length is set 66When the file is transferred a sync request "DONE" is sent, where length is set
67to the last modified time for the file. The server responds to this last 67to the last modified time for the file. The server responds to this last
68request (but not to chuck requests) with an "OKAY" sync response (length can 68request (but not to chunk requests) with an "OKAY" sync response (length can
69be ignored). 69be ignored).
70 70
71 71
@@ -73,9 +73,8 @@ RECV:
73Retrieves a file from device to a local file. The remote path is the path to 73Retrieves a file from device to a local file. The remote path is the path to
74the file that will be returned. Just as for the SEND sync request the file 74the file that will be returned. Just as for the SEND sync request the file
75received is split up into chunks. The sync response id is "DATA" and length is 75received is split up into chunks. The sync response id is "DATA" and length is
76the chuck size. After follows chunk size number of bytes. This is repeated 76the chunk size. After follows chunk size number of bytes. This is repeated
77until the file is transferred. Each chuck will not be larger than 64k. 77until the file is transferred. Each chunk will not be larger than 64k.
78 78
79When the file is transferred a sync response "DONE" is retrieved where the 79When the file is transferred a sync response "DONE" is retrieved where the
80length can be ignored. 80length can be ignored.
81
diff --git a/adb/file_sync_service.cpp b/adb/file_sync_service.cpp
index c6f3e6691..9a87931a3 100644
--- a/adb/file_sync_service.cpp
+++ b/adb/file_sync_service.cpp
@@ -62,7 +62,7 @@ static bool update_capabilities(const char* path, uint64_t capabilities) {
62 } 62 }
63 63
64 vfs_cap_data cap_data = {}; 64 vfs_cap_data cap_data = {};
65 cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE; 65 cap_data.magic_etc = VFS_CAP_REVISION_2 | VFS_CAP_FLAGS_EFFECTIVE;
66 cap_data.data[0].permitted = (capabilities & 0xffffffff); 66 cap_data.data[0].permitted = (capabilities & 0xffffffff);
67 cap_data.data[0].inheritable = 0; 67 cap_data.data[0].inheritable = 0;
68 cap_data.data[1].permitted = (capabilities >> 32); 68 cap_data.data[1].permitted = (capabilities >> 32);
diff --git a/adb/set_verity_enable_state_service.cpp b/adb/set_verity_enable_state_service.cpp
index 49e0363a1..253d14a0e 100644
--- a/adb/set_verity_enable_state_service.cpp
+++ b/adb/set_verity_enable_state_service.cpp
@@ -93,9 +93,21 @@ static bool set_verity_enabled_state(int fd, const char* block_device, const cha
93/* Helper function to get A/B suffix, if any. If the device isn't 93/* Helper function to get A/B suffix, if any. If the device isn't
94 * using A/B the empty string is returned. Otherwise either "_a", 94 * using A/B the empty string is returned. Otherwise either "_a",
95 * "_b", ... is returned. 95 * "_b", ... is returned.
96 *
97 * Note that since sometime in O androidboot.slot_suffix is deprecated
98 * and androidboot.slot should be used instead. Since bootloaders may
99 * be out of sync with the OS, we check both and for extra safety
100 * prepend a leading underscore if there isn't one already.
96 */ 101 */
97static std::string get_ab_suffix() { 102static std::string get_ab_suffix() {
98 return android::base::GetProperty("ro.boot.slot_suffix", ""); 103 std::string ab_suffix = android::base::GetProperty("ro.boot.slot_suffix", "");
104 if (ab_suffix == "") {
105 ab_suffix = android::base::GetProperty("ro.boot.slot", "");
106 }
107 if (ab_suffix.size() > 0 && ab_suffix[0] != '_') {
108 ab_suffix = std::string("_") + ab_suffix;
109 }
110 return ab_suffix;
99} 111}
100 112
101/* Use AVB to turn verity on/off */ 113/* Use AVB to turn verity on/off */
diff --git a/adb/sysdeps.h b/adb/sysdeps.h
index 0abb680d3..307be6d58 100644
--- a/adb/sysdeps.h
+++ b/adb/sysdeps.h
@@ -31,6 +31,7 @@
31 31
32// Include this before open/close/unlink are defined as macros below. 32// Include this before open/close/unlink are defined as macros below.
33#include <android-base/errors.h> 33#include <android-base/errors.h>
34#include <android-base/macros.h>
34#include <android-base/unique_fd.h> 35#include <android-base/unique_fd.h>
35#include <android-base/utf8.h> 36#include <android-base/utf8.h>
36 37
@@ -38,21 +39,6 @@
38#include "sysdeps/network.h" 39#include "sysdeps/network.h"
39#include "sysdeps/stat.h" 40#include "sysdeps/stat.h"
40 41
41/*
42 * TEMP_FAILURE_RETRY is defined by some, but not all, versions of
43 * <unistd.h>. (Alas, it is not as standard as we'd hoped!) So, if it's
44 * not already defined, then define it here.
45 */
46#ifndef TEMP_FAILURE_RETRY
47/* Used to retry syscalls that can return EINTR. */
48#define TEMP_FAILURE_RETRY(exp) ({ \
49 typeof (exp) _rc; \
50 do { \
51 _rc = (exp); \
52 } while (_rc == -1 && errno == EINTR); \
53 _rc; })
54#endif
55
56// Some printf-like functions are implemented in terms of 42// Some printf-like functions are implemented in terms of
57// android::base::StringAppendV, so they should use the same attribute for 43// android::base::StringAppendV, so they should use the same attribute for
58// compile-time format string checking. On Windows, if the mingw version of 44// compile-time format string checking. On Windows, if the mingw version of
diff --git a/base/Android.bp b/base/Android.bp
index 7ff02a0ee..ad0edf4a9 100644
--- a/base/Android.bp
+++ b/base/Android.bp
@@ -129,6 +129,7 @@ cc_test {
129 }, 129 },
130 windows: { 130 windows: {
131 srcs: ["utf8_test.cpp"], 131 srcs: ["utf8_test.cpp"],
132 cflags: ["-Wno-unused-parameter"],
132 enabled: true, 133 enabled: true,
133 }, 134 },
134 }, 135 },
diff --git a/base/logging_test.cpp b/base/logging_test.cpp
index adb041b32..6f05d9b7f 100644
--- a/base/logging_test.cpp
+++ b/base/logging_test.cpp
@@ -192,6 +192,7 @@ TEST(logging, WOULD_LOG_VERBOSE_enabled) {
192#undef CHECK_WOULD_LOG_ENABLED 192#undef CHECK_WOULD_LOG_ENABLED
193 193
194 194
195#if !defined(_WIN32)
195static std::string make_log_pattern(android::base::LogSeverity severity, 196static std::string make_log_pattern(android::base::LogSeverity severity,
196 const char* message) { 197 const char* message) {
197 static const char log_characters[] = "VDIWEFF"; 198 static const char log_characters[] = "VDIWEFF";
@@ -203,6 +204,7 @@ static std::string make_log_pattern(android::base::LogSeverity severity,
203 "%c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s:\\d+] %s", 204 "%c \\d+-\\d+ \\d+:\\d+:\\d+ \\s*\\d+ \\s*\\d+ %s:\\d+] %s",
204 log_char, basename(&holder[0]), message); 205 log_char, basename(&holder[0]), message);
205} 206}
207#endif
206 208
207static void CheckMessage(const CapturedStderr& cap, 209static void CheckMessage(const CapturedStderr& cap,
208 android::base::LogSeverity severity, const char* expected) { 210 android::base::LogSeverity severity, const char* expected) {
diff --git a/base/utf8.cpp b/base/utf8.cpp
index 5984fb06c..adb46d09c 100644
--- a/base/utf8.cpp
+++ b/base/utf8.cpp
@@ -195,7 +195,7 @@ FILE* fopen(const char* name, const char* mode) {
195 return _wfopen(name_utf16.c_str(), mode_utf16.c_str()); 195 return _wfopen(name_utf16.c_str(), mode_utf16.c_str());
196} 196}
197 197
198int mkdir(const char* name, mode_t mode) { 198int mkdir(const char* name, mode_t) {
199 std::wstring name_utf16; 199 std::wstring name_utf16;
200 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) { 200 if (!UTF8PathToWindowsLongPath(name, &name_utf16)) {
201 return -1; 201 return -1;
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index c1d54308b..79702a6c0 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -778,7 +778,12 @@ test_kernel_panic() {
778 checkDebugBuild || return 778 checkDebugBuild || return
779 duration_test ">90" 779 duration_test ">90"
780 panic_msg="kernel_panic,sysrq" 780 panic_msg="kernel_panic,sysrq"
781 enterPstore || panic_msg="\(kernel_panic,sysrq\|kernel_panic\)" 781 enterPstore
782 if [ ${?} != 0 ]; then
783 echo " or functional bootloader" >&2
784 panic_msg="\(kernel_panic,sysrq\|kernel_panic\)"
785 pstore_ok=true
786 fi
782 echo c | adb shell su root tee /proc/sysrq-trigger >/dev/null 787 echo c | adb shell su root tee /proc/sysrq-trigger >/dev/null
783 wait_for_screen 788 wait_for_screen
784 EXPECT_PROPERTY sys.boot.reason ${panic_msg} 789 EXPECT_PROPERTY sys.boot.reason ${panic_msg}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 8c11289a2..63b36f40c 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -228,6 +228,16 @@ const std::map<std::string, int32_t> kBootReasonMap = {
228 {"reboot,its_just_so_hard", 88}, // produced by boot_reason_test 228 {"reboot,its_just_so_hard", 88}, // produced by boot_reason_test
229 {"reboot,Its Just So Hard", 89}, // produced by boot_reason_test 229 {"reboot,Its Just So Hard", 89}, // produced by boot_reason_test
230 {"usb", 90}, 230 {"usb", 90},
231 {"charge", 91},
232 {"oem_tz_crash", 92},
233 {"uvlo", 93},
234 {"oem_ps_hold", 94},
235 {"abnormal_reset", 95},
236 {"oemerr_unknown", 96},
237 {"reboot_fastboot_mode", 97},
238 {"watchdog_apps_bite", 98},
239 {"xpu_err", 99},
240 {"power_on_usb", 100},
231}; 241};
232 242
233// Converts a string value representing the reason the system booted to an 243// Converts a string value representing the reason the system booted to an
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index d6b6d58d8..bd202ff14 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -429,7 +429,12 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
429 abort_message = g_callbacks.get_abort_message(); 429 abort_message = g_callbacks.get_abort_message();
430 } 430 }
431 431
432 if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) { 432 // If sival_int is ~0, it means that the fallback handler has been called
433 // once before and this function is being called again to dump the stack
434 // of a specific thread. It is possible that the prctl call might return 1,
435 // then return 0 in subsequent calls, so check the sival_int to determine if
436 // the fallback handler should be called first.
437 if (info->si_value.sival_int == ~0 || prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) {
433 // This check might be racy if another thread sets NO_NEW_PRIVS, but this should be unlikely, 438 // This check might be racy if another thread sets NO_NEW_PRIVS, but this should be unlikely,
434 // you can only set NO_NEW_PRIVS to 1, and the effect should be at worst a single missing 439 // you can only set NO_NEW_PRIVS to 1, and the effect should be at worst a single missing
435 // ANR trace. 440 // ANR trace.
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index bc8800296..b0b23379a 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -23,7 +23,6 @@ LOCAL_CFLAGS += -DFASTBOOT_VERSION="\"$(tool_version)\""
23LOCAL_C_INCLUDES := \ 23LOCAL_C_INCLUDES := \
24 $(LOCAL_PATH)/../adb \ 24 $(LOCAL_PATH)/../adb \
25 $(LOCAL_PATH)/../mkbootimg \ 25 $(LOCAL_PATH)/../mkbootimg \
26 $(LOCAL_PATH)/../../extras/f2fs_utils \
27 26
28LOCAL_SRC_FILES := \ 27LOCAL_SRC_FILES := \
29 bootimg_utils.cpp \ 28 bootimg_utils.cpp \
@@ -40,7 +39,7 @@ LOCAL_MODULE := fastboot
40LOCAL_MODULE_TAGS := debug 39LOCAL_MODULE_TAGS := debug
41LOCAL_MODULE_HOST_OS := darwin linux windows 40LOCAL_MODULE_HOST_OS := darwin linux windows
42LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code 41LOCAL_CFLAGS += -Wall -Wextra -Werror -Wunreachable-code
43LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid 42LOCAL_REQUIRED_MODULES := mke2fs e2fsdroid make_f2fs
44 43
45LOCAL_SRC_FILES_linux := usb_linux.cpp 44LOCAL_SRC_FILES_linux := usb_linux.cpp
46LOCAL_STATIC_LIBRARIES_linux := libselinux 45LOCAL_STATIC_LIBRARIES_linux := libselinux
@@ -67,14 +66,6 @@ LOCAL_STATIC_LIBRARIES := \
67 libcutils \ 66 libcutils \
68 libgtest_host \ 67 libgtest_host \
69 68
70# libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn")
71LOCAL_CFLAGS_linux := -DUSE_F2FS
72LOCAL_LDFLAGS_linux := -ldl -rdynamic -Wl,-rpath,.
73LOCAL_REQUIRED_MODULES_linux := libf2fs_fmt_host_dyn
74# The following libf2fs_* are from system/extras/f2fs_utils,
75# and do not use code in external/f2fs-tools.
76LOCAL_STATIC_LIBRARIES_linux += libf2fs_utils_host libf2fs_ioutils_host libf2fs_dlutils_host
77
78LOCAL_CXX_STL := libc++_static 69LOCAL_CXX_STL := libc++_static
79 70
80# Don't add anything here, we don't want additional shared dependencies 71# Don't add anything here, we don't want additional shared dependencies
@@ -87,9 +78,7 @@ include $(BUILD_HOST_EXECUTABLE)
87my_dist_files := $(LOCAL_BUILT_MODULE) 78my_dist_files := $(LOCAL_BUILT_MODULE)
88my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX) 79my_dist_files += $(HOST_OUT_EXECUTABLES)/mke2fs$(HOST_EXECUTABLE_SUFFIX)
89my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX) 80my_dist_files += $(HOST_OUT_EXECUTABLES)/e2fsdroid$(HOST_EXECUTABLE_SUFFIX)
90ifeq ($(HOST_OS),linux) 81my_dist_files += $(HOST_OUT_EXECUTABLES)/make_f2fs$(HOST_EXECUTABLE_SUFFIX)
91my_dist_files += $(HOST_LIBRARY_PATH)/libf2fs_fmt_host_dyn$(HOST_SHLIB_SUFFIX)
92endif
93$(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files)) 82$(call dist-for-goals,dist_files sdk win_sdk,$(my_dist_files))
94ifdef HOST_CROSS_OS 83ifdef HOST_CROSS_OS
95# Archive fastboot.exe for win_sdk build. 84# Archive fastboot.exe for win_sdk build.
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 40c18e002..6175f59ef 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -485,7 +485,7 @@ static void* load_bootable_image(const std::string& kernel, const std::string& r
485 return bdata; 485 return bdata;
486} 486}
487 487
488static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* sz) { 488static void* unzip_to_memory(ZipArchiveHandle zip, const char* entry_name, int64_t* sz) {
489 ZipString zip_entry_name(entry_name); 489 ZipString zip_entry_name(entry_name);
490 ZipEntry zip_entry; 490 ZipEntry zip_entry;
491 if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) { 491 if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
@@ -495,7 +495,7 @@ static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, int64_t* s
495 495
496 *sz = zip_entry.uncompressed_length; 496 *sz = zip_entry.uncompressed_length;
497 497
498 fprintf(stderr, "extracting %s (%" PRId64 " MB)...\n", entry_name, *sz / 1024 / 1024); 498 fprintf(stderr, "extracting %s (%" PRId64 " MB) to RAM...\n", entry_name, *sz / 1024 / 1024);
499 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length)); 499 uint8_t* data = reinterpret_cast<uint8_t*>(malloc(zip_entry.uncompressed_length));
500 if (data == nullptr) die("failed to allocate %" PRId64 " bytes for '%s'", *sz, entry_name); 500 if (data == nullptr) die("failed to allocate %" PRId64 " bytes for '%s'", *sz, entry_name);
501 501
@@ -613,17 +613,20 @@ static int unzip_to_file(ZipArchiveHandle zip, const char* entry_name) {
613 return -1; 613 return -1;
614 } 614 }
615 615
616 fprintf(stderr, "extracting %s (%" PRIu32 " MB)...\n", entry_name, 616 fprintf(stderr, "extracting %s (%" PRIu32 " MB) to disk...", entry_name,
617 zip_entry.uncompressed_length / 1024 / 1024); 617 zip_entry.uncompressed_length / 1024 / 1024);
618 double start = now();
618 int error = ExtractEntryToFile(zip, &zip_entry, fd); 619 int error = ExtractEntryToFile(zip, &zip_entry, fd);
619 if (error != 0) { 620 if (error != 0) {
620 die("failed to extract '%s': %s", entry_name, ErrorCodeString(error)); 621 die("\nfailed to extract '%s': %s", entry_name, ErrorCodeString(error));
621 } 622 }
622 623
623 if (lseek(fd, 0, SEEK_SET) != 0) { 624 if (lseek(fd, 0, SEEK_SET) != 0) {
624 die("lseek on extracted file '%s' failed: %s", entry_name, strerror(errno)); 625 die("\nlseek on extracted file '%s' failed: %s", entry_name, strerror(errno));
625 } 626 }
626 627
628 fprintf(stderr, " took %.3fs\n", now() - start);
629
627 return fd.release(); 630 return fd.release();
628} 631}
629 632
@@ -1091,7 +1094,7 @@ static void do_flash(Transport* transport, const char* pname, const char* fname)
1091 1094
1092static void do_update_signature(ZipArchiveHandle zip, const char* filename) { 1095static void do_update_signature(ZipArchiveHandle zip, const char* filename) {
1093 int64_t sz; 1096 int64_t sz;
1094 void* data = unzip_file(zip, filename, &sz); 1097 void* data = unzip_to_memory(zip, filename, &sz);
1095 if (data == nullptr) return; 1098 if (data == nullptr) return;
1096 fb_queue_download("signature", data, sz); 1099 fb_queue_download("signature", data, sz);
1097 fb_queue_command("signature", "installing signature"); 1100 fb_queue_command("signature", "installing signature");
@@ -1130,7 +1133,7 @@ static void do_update(Transport* transport, const char* filename, const std::str
1130 } 1133 }
1131 1134
1132 int64_t sz; 1135 int64_t sz;
1133 void* data = unzip_file(zip, "android-info.txt", &sz); 1136 void* data = unzip_to_memory(zip, "android-info.txt", &sz);
1134 if (data == nullptr) { 1137 if (data == nullptr) {
1135 die("update package '%s' has no android-info.txt", filename); 1138 die("update package '%s' has no android-info.txt", filename);
1136 } 1139 }
diff --git a/fastboot/fs.cpp b/fastboot/fs.cpp
index 2d77dd6eb..320cf7f83 100644
--- a/fastboot/fs.cpp
+++ b/fastboot/fs.cpp
@@ -1,7 +1,6 @@
1#include "fs.h" 1#include "fs.h"
2 2
3#include "fastboot.h" 3#include "fastboot.h"
4#include "make_f2fs.h"
5 4
6#include <errno.h> 5#include <errno.h>
7#include <fcntl.h> 6#include <fcntl.h>
@@ -23,13 +22,12 @@
23#include <android-base/file.h> 22#include <android-base/file.h>
24#include <android-base/stringprintf.h> 23#include <android-base/stringprintf.h>
25#include <android-base/unique_fd.h> 24#include <android-base/unique_fd.h>
26#include <sparse/sparse.h>
27 25
28using android::base::StringPrintf; 26using android::base::StringPrintf;
29using android::base::unique_fd; 27using android::base::unique_fd;
30 28
31#ifdef WIN32 29#ifdef WIN32
32static int exec_e2fs_cmd(const char* path, char* const argv[]) { 30static int exec_e2fs_cmd(const char* /*path*/, char* const argv[]) {
33 std::string cmd; 31 std::string cmd;
34 int i = 0; 32 int i = 0;
35 while (argv[i] != nullptr) { 33 while (argv[i] != nullptr) {
@@ -156,22 +154,41 @@ static int generate_ext4_image(const char* fileName, long long partSize,
156 return 0; 154 return 0;
157} 155}
158 156
159#ifdef USE_F2FS
160static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir, 157static int generate_f2fs_image(const char* fileName, long long partSize, const std::string& initial_dir,
161 unsigned /* unused */, unsigned /* unused */) 158 unsigned /* unused */, unsigned /* unused */)
162{ 159{
163 if (!initial_dir.empty()) { 160#ifndef WIN32
164 fprintf(stderr, "Unable to set initial directory on F2FS filesystem: %s\n", strerror(errno)); 161 const std::string exec_dir = android::base::GetExecutableDirectory();
162 const std::string mkf2fs_path = exec_dir + "/make_f2fs";
163 std::vector<const char*> mkf2fs_args = {mkf2fs_path.c_str()};
164
165 mkf2fs_args.push_back("-S");
166 std::string size_str = std::to_string(partSize);
167 mkf2fs_args.push_back(size_str.c_str());
168 mkf2fs_args.push_back("-f");
169 mkf2fs_args.push_back("-O");
170 mkf2fs_args.push_back("encrypt");
171 mkf2fs_args.push_back("-O");
172 mkf2fs_args.push_back("quota");
173 mkf2fs_args.push_back(fileName);
174 mkf2fs_args.push_back(nullptr);
175
176 int ret = exec_e2fs_cmd(mkf2fs_args[0], const_cast<char**>(mkf2fs_args.data()));
177 if (ret != 0) {
178 fprintf(stderr, "mkf2fs failed: %d\n", ret);
165 return -1; 179 return -1;
166 } 180 }
167 unique_fd fd(open(fileName, O_CREAT | O_RDWR | O_TRUNC, S_IRUSR | S_IWUSR)); 181
168 if (fd == -1) { 182 if (!initial_dir.empty()) {
169 fprintf(stderr, "Unable to open output file for F2FS filesystem: %s\n", strerror(errno)); 183 fprintf(stderr, "sload.f2s not supported yet\n");
170 return -1; 184 return 0;
171 } 185 }
172 return make_f2fs_sparse_fd(fd, partSize, NULL, NULL); 186 return 0;
173} 187#else
188 fprintf(stderr, "make_f2fs not supported on Windows\n");
189 return -1;
174#endif 190#endif
191}
175 192
176static const struct fs_generator { 193static const struct fs_generator {
177 const char* fs_type; //must match what fastboot reports for partition type 194 const char* fs_type; //must match what fastboot reports for partition type
@@ -182,9 +199,7 @@ static const struct fs_generator {
182 199
183} generators[] = { 200} generators[] = {
184 { "ext4", generate_ext4_image}, 201 { "ext4", generate_ext4_image},
185#ifdef USE_F2FS
186 { "f2fs", generate_f2fs_image}, 202 { "f2fs", generate_f2fs_image},
187#endif
188}; 203};
189 204
190const struct fs_generator* fs_get_generator(const std::string& fs_type) { 205const struct fs_generator* fs_get_generator(const std::string& fs_type) {
diff --git a/fs_mgr/fs_mgr_slotselect.cpp b/fs_mgr/fs_mgr_slotselect.cpp
index 33fd56240..f604bcfb1 100644
--- a/fs_mgr/fs_mgr_slotselect.cpp
+++ b/fs_mgr/fs_mgr_slotselect.cpp
@@ -21,12 +21,19 @@
21#include "fs_mgr.h" 21#include "fs_mgr.h"
22#include "fs_mgr_priv.h" 22#include "fs_mgr_priv.h"
23 23
24// Returns "_a" or "_b" based on androidboot.slot_suffix in kernel cmdline, or an empty string 24// Returns "_a" or "_b" based on two possible values in kernel cmdline:
25// if that parameter does not exist. 25// - androidboot.slot = a or b OR
26// - androidboot.slot_suffix = _a or _b
27// TODO: remove slot_suffix once it's deprecated.
26std::string fs_mgr_get_slot_suffix() { 28std::string fs_mgr_get_slot_suffix() {
29 std::string slot;
27 std::string ab_suffix; 30 std::string ab_suffix;
28 31
29 fs_mgr_get_boot_config("slot_suffix", &ab_suffix); 32 if (fs_mgr_get_boot_config("slot", &slot)) {
33 ab_suffix = "_" + slot;
34 } else if (!fs_mgr_get_boot_config("slot_suffix", &ab_suffix)) {
35 ab_suffix = "";
36 }
30 return ab_suffix; 37 return ab_suffix;
31} 38}
32 39
@@ -40,7 +47,7 @@ bool fs_mgr_update_for_slotselect(struct fstab *fstab) {
40 char *tmp; 47 char *tmp;
41 if (ab_suffix.empty()) { 48 if (ab_suffix.empty()) {
42 ab_suffix = fs_mgr_get_slot_suffix(); 49 ab_suffix = fs_mgr_get_slot_suffix();
43 // Returns false as non A/B devices should not have MF_SLOTSELECT. 50 // Return false if failed to get ab_suffix when MF_SLOTSELECT is specified.
44 if (ab_suffix.empty()) return false; 51 if (ab_suffix.empty()) return false;
45 } 52 }
46 if (asprintf(&tmp, "%s%s", fstab->recs[n].blk_device, ab_suffix.c_str()) > 0) { 53 if (asprintf(&tmp, "%s%s", fstab->recs[n].blk_device, ab_suffix.c_str()) > 0) {
diff --git a/init/action.cpp b/init/action.cpp
index 2617d009f..5fa6becf8 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -379,10 +379,12 @@ Result<Success> ActionParser::ParseLineSection(std::vector<std::string>&& args,
379 return action_ ? action_->AddCommand(std::move(args), line) : Success(); 379 return action_ ? action_->AddCommand(std::move(args), line) : Success();
380} 380}
381 381
382void ActionParser::EndSection() { 382Result<Success> ActionParser::EndSection() {
383 if (action_ && action_->NumCommands() > 0) { 383 if (action_ && action_->NumCommands() > 0) {
384 action_manager_->AddAction(std::move(action_)); 384 action_manager_->AddAction(std::move(action_));
385 } 385 }
386
387 return Success();
386} 388}
387 389
388} // namespace init 390} // namespace init
diff --git a/init/action.h b/init/action.h
index cdfc6a053..1bfc6c753 100644
--- a/init/action.h
+++ b/init/action.h
@@ -130,7 +130,7 @@ class ActionParser : public SectionParser {
130 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename, 130 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
131 int line) override; 131 int line) override;
132 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override; 132 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
133 void EndSection() override; 133 Result<Success> EndSection() override;
134 134
135 private: 135 private:
136 ActionManager* action_manager_; 136 ActionManager* action_manager_;
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 950a55155..f58402166 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -65,6 +65,7 @@
65#include "property_service.h" 65#include "property_service.h"
66#include "reboot.h" 66#include "reboot.h"
67#include "rlimit_parser.h" 67#include "rlimit_parser.h"
68#include "selinux.h"
68#include "service.h" 69#include "service.h"
69#include "subcontext.h" 70#include "subcontext.h"
70#include "util.h" 71#include "util.h"
@@ -641,8 +642,26 @@ static Result<Success> do_trigger(const BuiltinArguments& args) {
641 return Success(); 642 return Success();
642} 643}
643 644
645static int MakeSymlink(const std::string& target, const std::string& linkpath) {
646 std::string secontext;
647 // Passing 0 for mode should work.
648 if (SelabelLookupFileContext(linkpath, 0, &secontext) && !secontext.empty()) {
649 setfscreatecon(secontext.c_str());
650 }
651
652 int rc = symlink(target.c_str(), linkpath.c_str());
653
654 if (!secontext.empty()) {
655 int save_errno = errno;
656 setfscreatecon(nullptr);
657 errno = save_errno;
658 }
659
660 return rc;
661}
662
644static Result<Success> do_symlink(const BuiltinArguments& args) { 663static Result<Success> do_symlink(const BuiltinArguments& args) {
645 if (symlink(args[1].c_str(), args[2].c_str()) < 0) { 664 if (MakeSymlink(args[1], args[2]) < 0) {
646 // The symlink builtin is often used to create symlinks for older devices to be backwards 665 // The symlink builtin is often used to create symlinks for older devices to be backwards
647 // compatible with new paths, therefore we skip reporting this error. 666 // compatible with new paths, therefore we skip reporting this error.
648 if (errno == EEXIST && android::base::GetMinimumLogSeverity() > android::base::DEBUG) { 667 if (errno == EEXIST && android::base::GetMinimumLogSeverity() > android::base::DEBUG) {
diff --git a/init/capabilities.cpp b/init/capabilities.cpp
index 642a3642f..50987db7c 100644
--- a/init/capabilities.cpp
+++ b/init/capabilities.cpp
@@ -194,5 +194,18 @@ bool SetCapsForExec(const CapSet& to_keep) {
194 return SetAmbientCaps(to_keep); 194 return SetAmbientCaps(to_keep);
195} 195}
196 196
197bool DropInheritableCaps() {
198 ScopedCaps caps(cap_get_proc());
199 if (cap_clear_flag(caps.get(), CAP_INHERITABLE) == -1) {
200 PLOG(ERROR) << "cap_clear_flag(INHERITABLE) failed";
201 return false;
202 }
203 if (cap_set_proc(caps.get()) != 0) {
204 PLOG(ERROR) << "cap_set_proc() failed";
205 return false;
206 }
207 return true;
208}
209
197} // namespace init 210} // namespace init
198} // namespace android 211} // namespace android
diff --git a/init/capabilities.h b/init/capabilities.h
index ede85c324..fc80c9864 100644
--- a/init/capabilities.h
+++ b/init/capabilities.h
@@ -35,6 +35,7 @@ int LookupCap(const std::string& cap_name);
35bool CapAmbientSupported(); 35bool CapAmbientSupported();
36unsigned int GetLastValidCap(); 36unsigned int GetLastValidCap();
37bool SetCapsForExec(const CapSet& to_keep); 37bool SetCapsForExec(const CapSet& to_keep);
38bool DropInheritableCaps();
38 39
39} // namespace init 40} // namespace init
40} // namespace android 41} // namespace android
diff --git a/init/init_first_stage.cpp b/init/init_first_stage.cpp
index 0f7e38fa6..6fa07e728 100644
--- a/init/init_first_stage.cpp
+++ b/init/init_first_stage.cpp
@@ -118,7 +118,10 @@ static bool inline IsRecoveryMode() {
118FirstStageMount::FirstStageMount() 118FirstStageMount::FirstStageMount()
119 : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) { 119 : need_dm_verity_(false), device_tree_fstab_(fs_mgr_read_fstab_dt(), fs_mgr_free_fstab) {
120 if (!device_tree_fstab_) { 120 if (!device_tree_fstab_) {
121 LOG(ERROR) << "Failed to read fstab from device tree"; 121 // The client of FirstStageMount should check the existence of fstab in device-tree
122 // in advance, without parsing it. Reaching here means there is a FATAL error when
123 // parsing the fstab. So stop here to expose the failure.
124 LOG(FATAL) << "Failed to read fstab from device tree";
122 return; 125 return;
123 } 126 }
124 // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>) 127 // Stores device_tree_fstab_->recs[] into mount_fstab_recs_ (vector<fstab_rec*>)
diff --git a/init/init_test.cpp b/init/init_test.cpp
index 29a65abb9..268873c12 100644
--- a/init/init_test.cpp
+++ b/init/init_test.cpp
@@ -25,6 +25,7 @@
25#include "import_parser.h" 25#include "import_parser.h"
26#include "keyword_map.h" 26#include "keyword_map.h"
27#include "parser.h" 27#include "parser.h"
28#include "service.h"
28#include "test_function_map.h" 29#include "test_function_map.h"
29#include "util.h" 30#include "util.h"
30 31
@@ -34,12 +35,13 @@ namespace init {
34using ActionManagerCommand = std::function<void(ActionManager&)>; 35using ActionManagerCommand = std::function<void(ActionManager&)>;
35 36
36void TestInit(const std::string& init_script_file, const TestFunctionMap& test_function_map, 37void TestInit(const std::string& init_script_file, const TestFunctionMap& test_function_map,
37 const std::vector<ActionManagerCommand>& commands) { 38 const std::vector<ActionManagerCommand>& commands, ServiceList* service_list) {
38 ActionManager am; 39 ActionManager am;
39 40
40 Action::set_function_map(&test_function_map); 41 Action::set_function_map(&test_function_map);
41 42
42 Parser parser; 43 Parser parser;
44 parser.AddSectionParser("service", std::make_unique<ServiceParser>(service_list, nullptr));
43 parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr)); 45 parser.AddSectionParser("on", std::make_unique<ActionParser>(&am, nullptr));
44 parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser)); 46 parser.AddSectionParser("import", std::make_unique<ImportParser>(&parser));
45 47
@@ -55,11 +57,11 @@ void TestInit(const std::string& init_script_file, const TestFunctionMap& test_f
55} 57}
56 58
57void TestInitText(const std::string& init_script, const TestFunctionMap& test_function_map, 59void TestInitText(const std::string& init_script, const TestFunctionMap& test_function_map,
58 const std::vector<ActionManagerCommand>& commands) { 60 const std::vector<ActionManagerCommand>& commands, ServiceList* service_list) {
59 TemporaryFile tf; 61 TemporaryFile tf;
60 ASSERT_TRUE(tf.fd != -1); 62 ASSERT_TRUE(tf.fd != -1);
61 ASSERT_TRUE(android::base::WriteStringToFd(init_script, tf.fd)); 63 ASSERT_TRUE(android::base::WriteStringToFd(init_script, tf.fd));
62 TestInit(tf.path, test_function_map, commands); 64 TestInit(tf.path, test_function_map, commands, service_list);
63} 65}
64 66
65TEST(init, SimpleEventTrigger) { 67TEST(init, SimpleEventTrigger) {
@@ -76,7 +78,8 @@ pass_test
76 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); }; 78 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
77 std::vector<ActionManagerCommand> commands{trigger_boot}; 79 std::vector<ActionManagerCommand> commands{trigger_boot};
78 80
79 TestInitText(init_script, test_function_map, commands); 81 ServiceList service_list;
82 TestInitText(init_script, test_function_map, commands, &service_list);
80 83
81 EXPECT_TRUE(expect_true); 84 EXPECT_TRUE(expect_true);
82} 85}
@@ -104,7 +107,30 @@ execute_third
104 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); }; 107 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
105 std::vector<ActionManagerCommand> commands{trigger_boot}; 108 std::vector<ActionManagerCommand> commands{trigger_boot};
106 109
107 TestInitText(init_script, test_function_map, commands); 110 ServiceList service_list;
111 TestInitText(init_script, test_function_map, commands, &service_list);
112}
113
114TEST(init, OverrideService) {
115 std::string init_script = R"init(
116service A something
117 class first
118
119service A something
120 class second
121 override
122
123)init";
124
125 ServiceList service_list;
126 TestInitText(init_script, TestFunctionMap(), {}, &service_list);
127 ASSERT_EQ(1, std::distance(service_list.begin(), service_list.end()));
128
129 auto service = service_list.begin()->get();
130 ASSERT_NE(nullptr, service);
131 EXPECT_EQ(std::set<std::string>({"second"}), service->classnames());
132 EXPECT_EQ("A", service->name());
133 EXPECT_TRUE(service->is_override());
108} 134}
109 135
110TEST(init, EventTriggerOrderMultipleFiles) { 136TEST(init, EventTriggerOrderMultipleFiles) {
@@ -162,7 +188,9 @@ TEST(init, EventTriggerOrderMultipleFiles) {
162 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); }; 188 ActionManagerCommand trigger_boot = [](ActionManager& am) { am.QueueEventTrigger("boot"); };
163 std::vector<ActionManagerCommand> commands{trigger_boot}; 189 std::vector<ActionManagerCommand> commands{trigger_boot};
164 190
165 TestInit(start.path, test_function_map, commands); 191 ServiceList service_list;
192
193 TestInit(start.path, test_function_map, commands, &service_list);
166 194
167 EXPECT_EQ(6, num_executed); 195 EXPECT_EQ(6, num_executed);
168} 196}
diff --git a/init/parser.cpp b/init/parser.cpp
index 8a4e798d0..6ddb09f2b 100644
--- a/init/parser.cpp
+++ b/init/parser.cpp
@@ -50,12 +50,24 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
50 state.nexttoken = 0; 50 state.nexttoken = 0;
51 51
52 SectionParser* section_parser = nullptr; 52 SectionParser* section_parser = nullptr;
53 int section_start_line = -1;
53 std::vector<std::string> args; 54 std::vector<std::string> args;
54 55
56 auto end_section = [&] {
57 if (section_parser == nullptr) return;
58
59 if (auto result = section_parser->EndSection(); !result) {
60 LOG(ERROR) << filename << ": " << section_start_line << ": " << result.error();
61 }
62
63 section_parser = nullptr;
64 section_start_line = -1;
65 };
66
55 for (;;) { 67 for (;;) {
56 switch (next_token(&state)) { 68 switch (next_token(&state)) {
57 case T_EOF: 69 case T_EOF:
58 if (section_parser) section_parser->EndSection(); 70 end_section();
59 return; 71 return;
60 case T_NEWLINE: 72 case T_NEWLINE:
61 state.line++; 73 state.line++;
@@ -65,18 +77,18 @@ void Parser::ParseData(const std::string& filename, const std::string& data) {
65 // uevent. 77 // uevent.
66 for (const auto& [prefix, callback] : line_callbacks_) { 78 for (const auto& [prefix, callback] : line_callbacks_) {
67 if (android::base::StartsWith(args[0], prefix.c_str())) { 79 if (android::base::StartsWith(args[0], prefix.c_str())) {
68 if (section_parser) section_parser->EndSection(); 80 end_section();
69 81
70 if (auto result = callback(std::move(args)); !result) { 82 if (auto result = callback(std::move(args)); !result) {
71 LOG(ERROR) << filename << ": " << state.line << ": " << result.error(); 83 LOG(ERROR) << filename << ": " << state.line << ": " << result.error();
72 } 84 }
73 section_parser = nullptr;
74 break; 85 break;
75 } 86 }
76 } 87 }
77 if (section_parsers_.count(args[0])) { 88 if (section_parsers_.count(args[0])) {
78 if (section_parser) section_parser->EndSection(); 89 end_section();
79 section_parser = section_parsers_[args[0]].get(); 90 section_parser = section_parsers_[args[0]].get();
91 section_start_line = state.line;
80 if (auto result = 92 if (auto result =
81 section_parser->ParseSection(std::move(args), filename, state.line); 93 section_parser->ParseSection(std::move(args), filename, state.line);
82 !result) { 94 !result) {
diff --git a/init/parser.h b/init/parser.h
index 4ab24a4ee..110a4688a 100644
--- a/init/parser.h
+++ b/init/parser.h
@@ -26,24 +26,22 @@
26 26
27// SectionParser is an interface that can parse a given 'section' in init. 27// SectionParser is an interface that can parse a given 'section' in init.
28// 28//
29// You can implement up to 4 functions below, with ParseSection() being mandatory. 29// You can implement up to 4 functions below, with ParseSection being mandatory. The first two
30// The first two function return bool with false indicating a failure and has a std::string* err 30// functions return Result<Success> indicating if they have an error. It will be reported along
31// parameter into which an error string can be written. It will be reported along with the 31// with the filename and line number of where the error occurred.
32// filename and line number of where the error occurred.
33// 32//
34// 1) bool ParseSection(std::vector<std::string>&& args, const std::string& filename, 33// 1) ParseSection
35// int line, std::string* err)
36// This function is called when a section is first encountered. 34// This function is called when a section is first encountered.
37// 35//
38// 2) bool ParseLineSection(std::vector<std::string>&& args, int line, std::string* err) 36// 2) ParseLineSection
39// This function is called on each subsequent line until the next section is encountered. 37// This function is called on each subsequent line until the next section is encountered.
40// 38//
41// 3) bool EndSection() 39// 3) EndSection
42// This function is called either when a new section is found or at the end of the file. 40// This function is called either when a new section is found or at the end of the file.
43// It indicates that parsing of the current section is complete and any relevant objects should 41// It indicates that parsing of the current section is complete and any relevant objects should
44// be committed. 42// be committed.
45// 43//
46// 4) bool EndFile() 44// 4) EndFile
47// This function is called at the end of the file. 45// This function is called at the end of the file.
48// It indicates that the parsing has completed and any relevant objects should be committed. 46// It indicates that the parsing has completed and any relevant objects should be committed.
49 47
@@ -56,7 +54,7 @@ class SectionParser {
56 virtual Result<Success> ParseSection(std::vector<std::string>&& args, 54 virtual Result<Success> ParseSection(std::vector<std::string>&& args,
57 const std::string& filename, int line) = 0; 55 const std::string& filename, int line) = 0;
58 virtual Result<Success> ParseLineSection(std::vector<std::string>&&, int) { return Success(); }; 56 virtual Result<Success> ParseLineSection(std::vector<std::string>&&, int) { return Success(); };
59 virtual void EndSection(){}; 57 virtual Result<Success> EndSection() { return Success(); };
60 virtual void EndFile(){}; 58 virtual void EndFile(){};
61}; 59};
62 60
diff --git a/init/service.cpp b/init/service.cpp
index 12acfc692..331b859b7 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -291,6 +291,11 @@ void Service::SetProcessAttributes() {
291 if (!SetCapsForExec(capabilities_)) { 291 if (!SetCapsForExec(capabilities_)) {
292 LOG(FATAL) << "cannot set capabilities for " << name_; 292 LOG(FATAL) << "cannot set capabilities for " << name_;
293 } 293 }
294 } else if (uid_) {
295 // Inheritable caps can be non-zero when running in a container.
296 if (!DropInheritableCaps()) {
297 LOG(FATAL) << "cannot drop inheritable caps for " << name_;
298 }
294 } 299 }
295} 300}
296 301
@@ -530,6 +535,11 @@ Result<Success> Service::ParseOomScoreAdjust(const std::vector<std::string>& arg
530 return Success(); 535 return Success();
531} 536}
532 537
538Result<Success> Service::ParseOverride(const std::vector<std::string>& args) {
539 override_ = true;
540 return Success();
541}
542
533Result<Success> Service::ParseMemcgSwappiness(const std::vector<std::string>& args) { 543Result<Success> Service::ParseMemcgSwappiness(const std::vector<std::string>& args) {
534 if (!ParseInt(args[1], &swappiness_, 0)) { 544 if (!ParseInt(args[1], &swappiness_, 0)) {
535 return Error() << "swappiness value must be equal or greater than 0"; 545 return Error() << "swappiness value must be equal or greater than 0";
@@ -671,6 +681,7 @@ const Service::OptionParserMap::Map& Service::OptionParserMap::map() const {
671 {"keycodes", {1, kMax, &Service::ParseKeycodes}}, 681 {"keycodes", {1, kMax, &Service::ParseKeycodes}},
672 {"oneshot", {0, 0, &Service::ParseOneshot}}, 682 {"oneshot", {0, 0, &Service::ParseOneshot}},
673 {"onrestart", {1, kMax, &Service::ParseOnrestart}}, 683 {"onrestart", {1, kMax, &Service::ParseOnrestart}},
684 {"override", {0, 0, &Service::ParseOverride}},
674 {"oom_score_adjust", 685 {"oom_score_adjust",
675 {1, 1, &Service::ParseOomScoreAdjust}}, 686 {1, 1, &Service::ParseOomScoreAdjust}},
676 {"memcg.swappiness", 687 {"memcg.swappiness",
@@ -1111,11 +1122,6 @@ Result<Success> ServiceParser::ParseSection(std::vector<std::string>&& args,
1111 return Error() << "invalid service name '" << name << "'"; 1122 return Error() << "invalid service name '" << name << "'";
1112 } 1123 }
1113 1124
1114 Service* old_service = service_list_->FindService(name);
1115 if (old_service) {
1116 return Error() << "ignored duplicate definition of service '" << name << "'";
1117 }
1118
1119 Subcontext* restart_action_subcontext = nullptr; 1125 Subcontext* restart_action_subcontext = nullptr;
1120 if (subcontexts_) { 1126 if (subcontexts_) {
1121 for (auto& subcontext : *subcontexts_) { 1127 for (auto& subcontext : *subcontexts_) {
@@ -1135,10 +1141,23 @@ Result<Success> ServiceParser::ParseLineSection(std::vector<std::string>&& args,
1135 return service_ ? service_->ParseLine(std::move(args)) : Success(); 1141 return service_ ? service_->ParseLine(std::move(args)) : Success();
1136} 1142}
1137 1143
1138void ServiceParser::EndSection() { 1144Result<Success> ServiceParser::EndSection() {
1139 if (service_) { 1145 if (service_) {
1146 Service* old_service = service_list_->FindService(service_->name());
1147 if (old_service) {
1148 if (!service_->is_override()) {
1149 return Error() << "ignored duplicate definition of service '" << service_->name()
1150 << "'";
1151 }
1152
1153 service_list_->RemoveService(*old_service);
1154 old_service = nullptr;
1155 }
1156
1140 service_list_->AddService(std::move(service_)); 1157 service_list_->AddService(std::move(service_));
1141 } 1158 }
1159
1160 return Success();
1142} 1161}
1143 1162
1144bool ServiceParser::IsValidName(const std::string& name) const { 1163bool ServiceParser::IsValidName(const std::string& name) const {
diff --git a/init/service.h b/init/service.h
index 593f78289..d46a41349 100644
--- a/init/service.h
+++ b/init/service.h
@@ -111,6 +111,7 @@ class Service {
111 const std::set<std::string>& interfaces() const { return interfaces_; } 111 const std::set<std::string>& interfaces() const { return interfaces_; }
112 int priority() const { return priority_; } 112 int priority() const { return priority_; }
113 int oom_score_adjust() const { return oom_score_adjust_; } 113 int oom_score_adjust() const { return oom_score_adjust_; }
114 bool is_override() const { return override_; }
114 bool process_cgroup_empty() const { return process_cgroup_empty_; } 115 bool process_cgroup_empty() const { return process_cgroup_empty_; }
115 unsigned long start_order() const { return start_order_; } 116 unsigned long start_order() const { return start_order_; }
116 const std::vector<std::string>& args() const { return args_; } 117 const std::vector<std::string>& args() const { return args_; }
@@ -139,6 +140,7 @@ class Service {
139 Result<Success> ParseOneshot(const std::vector<std::string>& args); 140 Result<Success> ParseOneshot(const std::vector<std::string>& args);
140 Result<Success> ParseOnrestart(const std::vector<std::string>& args); 141 Result<Success> ParseOnrestart(const std::vector<std::string>& args);
141 Result<Success> ParseOomScoreAdjust(const std::vector<std::string>& args); 142 Result<Success> ParseOomScoreAdjust(const std::vector<std::string>& args);
143 Result<Success> ParseOverride(const std::vector<std::string>& args);
142 Result<Success> ParseMemcgLimitInBytes(const std::vector<std::string>& args); 144 Result<Success> ParseMemcgLimitInBytes(const std::vector<std::string>& args);
143 Result<Success> ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args); 145 Result<Success> ParseMemcgSoftLimitInBytes(const std::vector<std::string>& args);
144 Result<Success> ParseMemcgSwappiness(const std::vector<std::string>& args); 146 Result<Success> ParseMemcgSwappiness(const std::vector<std::string>& args);
@@ -201,6 +203,8 @@ class Service {
201 203
202 bool process_cgroup_empty_ = false; 204 bool process_cgroup_empty_ = false;
203 205
206 bool override_ = false;
207
204 unsigned long start_order_; 208 unsigned long start_order_;
205 209
206 std::vector<std::pair<int, rlimit>> rlimits_; 210 std::vector<std::pair<int, rlimit>> rlimits_;
@@ -248,7 +252,7 @@ class ServiceParser : public SectionParser {
248 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename, 252 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
249 int line) override; 253 int line) override;
250 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override; 254 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
251 void EndSection() override; 255 Result<Success> EndSection() override;
252 256
253 private: 257 private:
254 bool IsValidName(const std::string& name) const; 258 bool IsValidName(const std::string& name) const;
diff --git a/init/subcontext.cpp b/init/subcontext.cpp
index 84feeeee4..068be6e6f 100644
--- a/init/subcontext.cpp
+++ b/init/subcontext.cpp
@@ -23,7 +23,6 @@
23 23
24#include <android-base/file.h> 24#include <android-base/file.h>
25#include <android-base/logging.h> 25#include <android-base/logging.h>
26#include <android-base/properties.h>
27#include <android-base/strings.h> 26#include <android-base/strings.h>
28#include <selinux/android.h> 27#include <selinux/android.h>
29 28
@@ -32,7 +31,6 @@
32#include "system/core/init/subcontext.pb.h" 31#include "system/core/init/subcontext.pb.h"
33#include "util.h" 32#include "util.h"
34 33
35using android::base::GetBoolProperty;
36using android::base::GetExecutablePath; 34using android::base::GetExecutablePath;
37using android::base::Join; 35using android::base::Join;
38using android::base::Socketpair; 36using android::base::Socketpair;
@@ -262,13 +260,11 @@ Result<Success> Subcontext::Execute(const std::vector<std::string>& args) {
262static std::vector<Subcontext> subcontexts; 260static std::vector<Subcontext> subcontexts;
263 261
264std::vector<Subcontext>* InitializeSubcontexts() { 262std::vector<Subcontext>* InitializeSubcontexts() {
265 if (GetBoolProperty("ro.init.subcontexts_enabled", false)) { 263 static const char* const paths_and_secontexts[][2] = {
266 static const char* const paths_and_secontexts[][2] = { 264 {"/vendor", kVendorContext.c_str()},
267 {"/vendor", kVendorContext.c_str()}, 265 };
268 }; 266 for (const auto& [path_prefix, secontext] : paths_and_secontexts) {
269 for (const auto& [path_prefix, secontext] : paths_and_secontexts) { 267 subcontexts.emplace_back(path_prefix, secontext);
270 subcontexts.emplace_back(path_prefix, secontext);
271 }
272 } 268 }
273 return &subcontexts; 269 return &subcontexts;
274} 270}
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index cd7adb433..f74c87849 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -132,8 +132,10 @@ Result<Success> SubsystemParser::ParseLineSection(std::vector<std::string>&& arg
132 return std::invoke(*parser, this, std::move(args)); 132 return std::invoke(*parser, this, std::move(args));
133} 133}
134 134
135void SubsystemParser::EndSection() { 135Result<Success> SubsystemParser::EndSection() {
136 subsystems_->emplace_back(std::move(subsystem_)); 136 subsystems_->emplace_back(std::move(subsystem_));
137
138 return Success();
137} 139}
138 140
139} // namespace init 141} // namespace init
diff --git a/init/ueventd_parser.h b/init/ueventd_parser.h
index 18d1027b4..83684f39e 100644
--- a/init/ueventd_parser.h
+++ b/init/ueventd_parser.h
@@ -32,7 +32,7 @@ class SubsystemParser : public SectionParser {
32 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename, 32 Result<Success> ParseSection(std::vector<std::string>&& args, const std::string& filename,
33 int line) override; 33 int line) override;
34 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override; 34 Result<Success> ParseLineSection(std::vector<std::string>&& args, int line) override;
35 void EndSection() override; 35 Result<Success> EndSection() override;
36 36
37 private: 37 private:
38 Result<Success> ParseDevName(std::vector<std::string>&& args); 38 Result<Success> ParseDevName(std::vector<std::string>&& args);
diff --git a/init/util.cpp b/init/util.cpp
index a19a6f3c3..d80cb1ef6 100644
--- a/init/util.cpp
+++ b/init/util.cpp
@@ -178,9 +178,26 @@ Result<std::string> ReadFile(const std::string& path) {
178 return content; 178 return content;
179} 179}
180 180
181static int OpenFile(const std::string& path, int flags, mode_t mode) {
182 std::string secontext;
183 if (SelabelLookupFileContext(path, mode, &secontext) && !secontext.empty()) {
184 setfscreatecon(secontext.c_str());
185 }
186
187 int rc = open(path.c_str(), flags, mode);
188
189 if (!secontext.empty()) {
190 int save_errno = errno;
191 setfscreatecon(nullptr);
192 errno = save_errno;
193 }
194
195 return rc;
196}
197
181Result<Success> WriteFile(const std::string& path, const std::string& content) { 198Result<Success> WriteFile(const std::string& path, const std::string& content) {
182 android::base::unique_fd fd(TEMP_FAILURE_RETRY( 199 android::base::unique_fd fd(TEMP_FAILURE_RETRY(
183 open(path.c_str(), O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0600))); 200 OpenFile(path, O_WRONLY | O_CREAT | O_NOFOLLOW | O_TRUNC | O_CLOEXEC, 0600)));
184 if (fd == -1) { 201 if (fd == -1) {
185 return ErrnoError() << "open() failed"; 202 return ErrnoError() << "open() failed";
186 } 203 }
diff --git a/libbacktrace/UnwindStackMap.cpp b/libbacktrace/UnwindStackMap.cpp
index 25e5002ba..9ac0a0b54 100644
--- a/libbacktrace/UnwindStackMap.cpp
+++ b/libbacktrace/UnwindStackMap.cpp
@@ -44,15 +44,15 @@ bool UnwindStackMap::Build() {
44 } 44 }
45 45
46 // Iterate through the maps and fill in the backtrace_map_t structure. 46 // Iterate through the maps and fill in the backtrace_map_t structure.
47 for (auto& map_info : *stack_maps_) { 47 for (auto* map_info : *stack_maps_) {
48 backtrace_map_t map; 48 backtrace_map_t map;
49 map.start = map_info.start; 49 map.start = map_info->start;
50 map.end = map_info.end; 50 map.end = map_info->end;
51 map.offset = map_info.offset; 51 map.offset = map_info->offset;
52 // Set to -1 so that it is demand loaded. 52 // Set to -1 so that it is demand loaded.
53 map.load_bias = static_cast<uintptr_t>(-1); 53 map.load_bias = static_cast<uintptr_t>(-1);
54 map.flags = map_info.flags; 54 map.flags = map_info->flags;
55 map.name = map_info.name; 55 map.name = map_info->name;
56 56
57 maps_.push_back(map); 57 maps_.push_back(map);
58 } 58 }
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 0a60ec4f3..9911e74a6 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -77,6 +77,7 @@ struct thread_t {
77 77
78struct dump_thread_t { 78struct dump_thread_t {
79 thread_t thread; 79 thread_t thread;
80 BacktraceMap* map;
80 Backtrace* backtrace; 81 Backtrace* backtrace;
81 int32_t* now; 82 int32_t* now;
82 int32_t done; 83 int32_t done;
@@ -632,7 +633,7 @@ static void* ThreadDump(void* data) {
632 } 633 }
633 634
634 // The status of the actual unwind will be checked elsewhere. 635 // The status of the actual unwind will be checked elsewhere.
635 dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid); 636 dump->backtrace = Backtrace::Create(getpid(), dump->thread.tid, dump->map);
636 dump->backtrace->Unwind(0); 637 dump->backtrace->Unwind(0);
637 638
638 android_atomic_acquire_store(1, &dump->done); 639 android_atomic_acquire_store(1, &dump->done);
@@ -640,8 +641,8 @@ static void* ThreadDump(void* data) {
640 return nullptr; 641 return nullptr;
641} 642}
642 643
643TEST(libbacktrace, thread_multiple_dump) { 644static void MultipleThreadDumpTest(bool share_map) {
644 // Dump NUM_THREADS simultaneously. 645 // Dump NUM_THREADS simultaneously using the same map.
645 std::vector<thread_t> runners(NUM_THREADS); 646 std::vector<thread_t> runners(NUM_THREADS);
646 std::vector<dump_thread_t> dumpers(NUM_THREADS); 647 std::vector<dump_thread_t> dumpers(NUM_THREADS);
647 648
@@ -662,12 +663,17 @@ TEST(libbacktrace, thread_multiple_dump) {
662 663
663 // Start all of the dumpers at once, they will spin until they are signalled 664 // Start all of the dumpers at once, they will spin until they are signalled
664 // to begin their dump run. 665 // to begin their dump run.
666 std::unique_ptr<BacktraceMap> map;
667 if (share_map) {
668 map.reset(BacktraceMap::Create(getpid()));
669 }
665 int32_t dump_now = 0; 670 int32_t dump_now = 0;
666 for (size_t i = 0; i < NUM_THREADS; i++) { 671 for (size_t i = 0; i < NUM_THREADS; i++) {
667 dumpers[i].thread.tid = runners[i].tid; 672 dumpers[i].thread.tid = runners[i].tid;
668 dumpers[i].thread.state = 0; 673 dumpers[i].thread.state = 0;
669 dumpers[i].done = 0; 674 dumpers[i].done = 0;
670 dumpers[i].now = &dump_now; 675 dumpers[i].now = &dump_now;
676 dumpers[i].map = map.get();
671 677
672 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0); 678 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
673 } 679 }
@@ -689,47 +695,12 @@ TEST(libbacktrace, thread_multiple_dump) {
689 } 695 }
690} 696}
691 697
692TEST(libbacktrace, thread_multiple_dump_same_thread) { 698TEST(libbacktrace, thread_multiple_dump) {
693 pthread_attr_t attr; 699 MultipleThreadDumpTest(false);
694 pthread_attr_init(&attr); 700}
695 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
696 thread_t runner;
697 runner.tid = 0;
698 runner.state = 0;
699 ASSERT_TRUE(pthread_create(&runner.threadId, &attr, ThreadMaxRun, &runner) == 0);
700
701 // Wait for tids to be set.
702 ASSERT_TRUE(WaitForNonZero(&runner.state, 30));
703
704 // Start all of the dumpers at once, they will spin until they are signalled
705 // to begin their dump run.
706 int32_t dump_now = 0;
707 // Dump the same thread NUM_THREADS simultaneously.
708 std::vector<dump_thread_t> dumpers(NUM_THREADS);
709 for (size_t i = 0; i < NUM_THREADS; i++) {
710 dumpers[i].thread.tid = runner.tid;
711 dumpers[i].thread.state = 0;
712 dumpers[i].done = 0;
713 dumpers[i].now = &dump_now;
714
715 ASSERT_TRUE(pthread_create(&dumpers[i].thread.threadId, &attr, ThreadDump, &dumpers[i]) == 0);
716 }
717
718 // Start all of the dumpers going at once.
719 android_atomic_acquire_store(1, &dump_now);
720
721 for (size_t i = 0; i < NUM_THREADS; i++) {
722 ASSERT_TRUE(WaitForNonZero(&dumpers[i].done, 30));
723
724 ASSERT_TRUE(dumpers[i].backtrace != nullptr);
725 VerifyMaxDump(dumpers[i].backtrace);
726
727 delete dumpers[i].backtrace;
728 dumpers[i].backtrace = nullptr;
729 }
730 701
731 // Tell the runner thread to exit its infinite loop. 702TEST(libbacktrace, thread_multiple_dump_same_map) {
732 android_atomic_acquire_store(0, &runner.state); 703 MultipleThreadDumpTest(true);
733} 704}
734 705
735// This test is for UnwindMaps that should share the same map cursor when 706// This test is for UnwindMaps that should share the same map cursor when
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index faaad0c20..9cba109a4 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -19,14 +19,14 @@
19// which are also hard or even impossible to port to native Win32 19// which are also hard or even impossible to port to native Win32
20libcutils_nonwindows_sources = [ 20libcutils_nonwindows_sources = [
21 "android_get_control_file.cpp", 21 "android_get_control_file.cpp",
22 "fs.c", 22 "fs.cpp",
23 "multiuser.c", 23 "multiuser.cpp",
24 "socket_inaddr_any_server_unix.c", 24 "socket_inaddr_any_server_unix.cpp",
25 "socket_local_client_unix.c", 25 "socket_local_client_unix.cpp",
26 "socket_local_server_unix.c", 26 "socket_local_server_unix.cpp",
27 "socket_network_client_unix.c", 27 "socket_network_client_unix.cpp",
28 "sockets_unix.cpp", 28 "sockets_unix.cpp",
29 "str_parms.c", 29 "str_parms.cpp",
30] 30]
31 31
32cc_library_headers { 32cc_library_headers {
@@ -56,41 +56,37 @@ cc_library {
56 }, 56 },
57 host_supported: true, 57 host_supported: true,
58 srcs: [ 58 srcs: [
59 "config_utils.c", 59 "config_utils.cpp",
60 "fs_config.cpp", 60 "fs_config.cpp",
61 "canned_fs_config.c", 61 "canned_fs_config.cpp",
62 "hashmap.c", 62 "hashmap.cpp",
63 "iosched_policy.c", 63 "iosched_policy.cpp",
64 "load_file.c", 64 "load_file.cpp",
65 "native_handle.c", 65 "native_handle.cpp",
66 "open_memstream.c", 66 "open_memstream.c",
67 "record_stream.c", 67 "record_stream.cpp",
68 "sched_policy.cpp", 68 "sched_policy.cpp",
69 "sockets.cpp", 69 "sockets.cpp",
70 "strdup16to8.c", 70 "strdup16to8.cpp",
71 "strdup8to16.c", 71 "strdup8to16.cpp",
72 "strlcpy.c", 72 "strlcpy.c",
73 "threads.c", 73 "threads.cpp",
74 ], 74 ],
75 75
76 target: { 76 target: {
77 host: {
78 srcs: ["dlmalloc_stubs.c"],
79 },
80 linux_bionic: { 77 linux_bionic: {
81 enabled: true, 78 enabled: true,
82 exclude_srcs: ["dlmalloc_stubs.c"],
83 }, 79 },
84 not_windows: { 80 not_windows: {
85 srcs: libcutils_nonwindows_sources + [ 81 srcs: libcutils_nonwindows_sources + [
86 "ashmem-host.c", 82 "ashmem-host.cpp",
87 "trace-host.c", 83 "trace-host.cpp",
88 ], 84 ],
89 }, 85 },
90 windows: { 86 windows: {
91 srcs: [ 87 srcs: [
92 "socket_inaddr_any_server_windows.c", 88 "socket_inaddr_any_server_windows.cpp",
93 "socket_network_client_windows.c", 89 "socket_network_client_windows.cpp",
94 "sockets_windows.cpp", 90 "sockets_windows.cpp",
95 ], 91 ],
96 92
@@ -105,13 +101,13 @@ cc_library {
105 101
106 android: { 102 android: {
107 srcs: libcutils_nonwindows_sources + [ 103 srcs: libcutils_nonwindows_sources + [
108 "android_reboot.c", 104 "android_reboot.cpp",
109 "ashmem-dev.c", 105 "ashmem-dev.cpp",
110 "klog.cpp", 106 "klog.cpp",
111 "partition_utils.c", 107 "partition_utils.cpp",
112 "properties.cpp", 108 "properties.cpp",
113 "qtaguid.c", 109 "qtaguid.cpp",
114 "trace-dev.c", 110 "trace-dev.cpp",
115 "uevent.cpp", 111 "uevent.cpp",
116 ], 112 ],
117 }, 113 },
diff --git a/libcutils/android_get_control_file.cpp b/libcutils/android_get_control_file.cpp
index 780d9f136..d8121f5cd 100644
--- a/libcutils/android_get_control_file.cpp
+++ b/libcutils/android_get_control_file.cpp
@@ -25,6 +25,9 @@
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28
29#include <cutils/android_get_control_file.h>
30
28#include <ctype.h> 31#include <ctype.h>
29#include <errno.h> 32#include <errno.h>
30#include <fcntl.h> 33#include <fcntl.h>
@@ -36,8 +39,6 @@
36#include <sys/types.h> 39#include <sys/types.h>
37#include <unistd.h> 40#include <unistd.h>
38 41
39#include <cutils/android_get_control_file.h>
40
41#include "android_get_control_env.h" 42#include "android_get_control_env.h"
42 43
43#ifndef TEMP_FAILURE_RETRY 44#ifndef TEMP_FAILURE_RETRY
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.cpp
index 996d89d9b..5e864d442 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.cpp
@@ -13,10 +13,12 @@
13 * See the License for the specific language governing permissions and 13 * See the License for the specific language governing permissions and
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16
17#include <cutils/android_reboot.h>
18
16#include <stdio.h> 19#include <stdio.h>
17#include <stdlib.h> 20#include <stdlib.h>
18 21
19#include <cutils/android_reboot.h>
20#include <cutils/properties.h> 22#include <cutils/properties.h>
21 23
22#define TAG "android_reboot" 24#define TAG "android_reboot"
@@ -26,7 +28,7 @@ int android_reboot(int cmd, int flags __unused, const char* arg) {
26 const char* restart_cmd = NULL; 28 const char* restart_cmd = NULL;
27 char* prop_value; 29 char* prop_value;
28 30
29 switch (cmd) { 31 switch (static_cast<unsigned>(cmd)) {
30 case ANDROID_RB_RESTART: // deprecated 32 case ANDROID_RB_RESTART: // deprecated
31 case ANDROID_RB_RESTART2: 33 case ANDROID_RB_RESTART2:
32 restart_cmd = "reboot"; 34 restart_cmd = "reboot";
diff --git a/libcutils/ashmem-dev.c b/libcutils/ashmem-dev.cpp
index 95f2259ec..15ace0e64 100644
--- a/libcutils/ashmem-dev.c
+++ b/libcutils/ashmem-dev.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/ashmem.h>
18
17/* 19/*
18 * Implementation of the user-space ashmem API for devices, which have our 20 * Implementation of the user-space ashmem API for devices, which have our
19 * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version, 21 * ashmem-enabled kernel. See ashmem-sim.c for the "fake" tmp-based version,
@@ -31,8 +33,6 @@
31#include <sys/sysmacros.h> 33#include <sys/sysmacros.h>
32#include <sys/types.h> 34#include <sys/types.h>
33#include <unistd.h> 35#include <unistd.h>
34
35#include <cutils/ashmem.h>
36#include <log/log.h> 36#include <log/log.h>
37 37
38#define ASHMEM_DEVICE "/dev/ashmem" 38#define ASHMEM_DEVICE "/dev/ashmem"
@@ -192,7 +192,8 @@ int ashmem_set_prot_region(int fd, int prot)
192 192
193int ashmem_pin_region(int fd, size_t offset, size_t len) 193int ashmem_pin_region(int fd, size_t offset, size_t len)
194{ 194{
195 struct ashmem_pin pin = { offset, len }; 195 // TODO: should LP64 reject too-large offset/len?
196 ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
196 197
197 int ret = __ashmem_is_ashmem(fd, 1); 198 int ret = __ashmem_is_ashmem(fd, 1);
198 if (ret < 0) { 199 if (ret < 0) {
@@ -204,7 +205,8 @@ int ashmem_pin_region(int fd, size_t offset, size_t len)
204 205
205int ashmem_unpin_region(int fd, size_t offset, size_t len) 206int ashmem_unpin_region(int fd, size_t offset, size_t len)
206{ 207{
207 struct ashmem_pin pin = { offset, len }; 208 // TODO: should LP64 reject too-large offset/len?
209 ashmem_pin pin = { static_cast<uint32_t>(offset), static_cast<uint32_t>(len) };
208 210
209 int ret = __ashmem_is_ashmem(fd, 1); 211 int ret = __ashmem_is_ashmem(fd, 1);
210 if (ret < 0) { 212 if (ret < 0) {
diff --git a/libcutils/ashmem-host.c b/libcutils/ashmem-host.cpp
index 1f9f753e4..d2c28f393 100644
--- a/libcutils/ashmem-host.c
+++ b/libcutils/ashmem-host.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/ashmem.h>
18
17/* 19/*
18 * Implementation of the user-space ashmem API for the simulator, which lacks 20 * Implementation of the user-space ashmem API for the simulator, which lacks
19 * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version. 21 * an ashmem-enabled kernel. See ashmem-dev.c for the real ashmem-based version.
@@ -31,7 +33,6 @@
31#include <time.h> 33#include <time.h>
32#include <unistd.h> 34#include <unistd.h>
33 35
34#include <cutils/ashmem.h>
35#include <utils/Compat.h> 36#include <utils/Compat.h>
36 37
37#ifndef __unused 38#ifndef __unused
@@ -40,12 +41,12 @@
40 41
41int ashmem_create_region(const char *ignored __unused, size_t size) 42int ashmem_create_region(const char *ignored __unused, size_t size)
42{ 43{
43 char template[PATH_MAX]; 44 char pattern[PATH_MAX];
44 snprintf(template, sizeof(template), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid()); 45 snprintf(pattern, sizeof(pattern), "/tmp/android-ashmem-%d-XXXXXXXXX", getpid());
45 int fd = mkstemp(template); 46 int fd = mkstemp(pattern);
46 if (fd == -1) return -1; 47 if (fd == -1) return -1;
47 48
48 unlink(template); 49 unlink(pattern);
49 50
50 if (TEMP_FAILURE_RETRY(ftruncate(fd, size)) == -1) { 51 if (TEMP_FAILURE_RETRY(ftruncate(fd, size)) == -1) {
51 close(fd); 52 close(fd);
diff --git a/libcutils/canned_fs_config.c b/libcutils/canned_fs_config.cpp
index 819a846a6..6b5763b16 100644
--- a/libcutils/canned_fs_config.c
+++ b/libcutils/canned_fs_config.cpp
@@ -14,6 +14,10 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <private/android_filesystem_config.h>
18#include <private/canned_fs_config.h>
19#include <private/fs_config.h>
20
17#include <errno.h> 21#include <errno.h>
18#include <inttypes.h> 22#include <inttypes.h>
19#include <limits.h> 23#include <limits.h>
@@ -22,10 +26,6 @@
22#include <stdlib.h> 26#include <stdlib.h>
23#include <string.h> 27#include <string.h>
24 28
25#include <private/android_filesystem_config.h>
26#include <private/fs_config.h>
27#include <private/canned_fs_config.h>
28
29typedef struct { 29typedef struct {
30 const char* path; 30 const char* path;
31 unsigned uid; 31 unsigned uid;
diff --git a/libcutils/config_utils.c b/libcutils/config_utils.cpp
index fc5ca7876..a3af01a58 100644
--- a/libcutils/config_utils.c
+++ b/libcutils/config_utils.cpp
@@ -14,20 +14,19 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/config_utils.h>
18
17#include <string.h> 19#include <string.h>
18#include <ctype.h> 20#include <ctype.h>
19#include <stdlib.h> 21#include <stdlib.h>
20#include <fcntl.h> 22#include <fcntl.h>
21#include <unistd.h> 23#include <unistd.h>
22 24
23#include <cutils/config_utils.h>
24#include <cutils/misc.h> 25#include <cutils/misc.h>
25 26
26cnode* config_node(const char *name, const char *value) 27cnode* config_node(const char *name, const char *value)
27{ 28{
28 cnode *node; 29 cnode* node = static_cast<cnode*>(calloc(sizeof(cnode), 1));
29
30 node = calloc(sizeof(cnode), 1);
31 if(node) { 30 if(node) {
32 node->name = name ? name : ""; 31 node->name = name ? name : "";
33 node->value = value ? value : ""; 32 node->value = value ? value : "";
@@ -311,9 +310,9 @@ void config_load(cnode *root, char *data)
311 310
312void config_load_file(cnode *root, const char *fn) 311void config_load_file(cnode *root, const char *fn)
313{ 312{
314 char *data; 313 char* data = static_cast<char*>(load_file(fn, nullptr));
315 data = load_file(fn, 0);
316 config_load(root, data); 314 config_load(root, data);
315 // TODO: deliberate leak :-/
317} 316}
318 317
319void config_free(cnode *root) 318void config_free(cnode *root)
diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c
deleted file mode 100644
index 2cff9dd01..000000000
--- a/libcutils/dlmalloc_stubs.c
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * Copyright (C) 2007 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "dlmalloc-stubs"
18
19#include "log/log.h"
20
21#define UNUSED __attribute__((__unused__))
22
23/*
24 * Stubs for functions defined in bionic/libc/bionic/dlmalloc.c. These
25 * are used in host builds, as the host libc will not contain these
26 * functions.
27 */
28void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*) UNUSED,
29 void* arg UNUSED)
30{
31 ALOGW("Called host unimplemented stub: dlmalloc_inspect_all");
32}
33
34int dlmalloc_trim(size_t unused UNUSED)
35{
36 ALOGW("Called host unimplemented stub: dlmalloc_trim");
37 return 0;
38}
diff --git a/libcutils/fs.c b/libcutils/fs.cpp
index b253b1cd9..ef85accce 100644
--- a/libcutils/fs.c
+++ b/libcutils/fs.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/fs.h>
18
17#define LOG_TAG "cutils" 19#define LOG_TAG "cutils"
18 20
19/* These defines are only needed because prebuilt headers are out of date */ 21/* These defines are only needed because prebuilt headers are out of date */
@@ -32,7 +34,6 @@
32#include <sys/types.h> 34#include <sys/types.h>
33#include <unistd.h> 35#include <unistd.h>
34 36
35#include <cutils/fs.h>
36#include <log/log.h> 37#include <log/log.h>
37 38
38#define ALL_PERMS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO) 39#define ALL_PERMS (S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO)
@@ -40,6 +41,11 @@
40 41
41static int fs_prepare_path_impl(const char* path, mode_t mode, uid_t uid, gid_t gid, 42static int fs_prepare_path_impl(const char* path, mode_t mode, uid_t uid, gid_t gid,
42 int allow_fixup, int prepare_as_dir) { 43 int allow_fixup, int prepare_as_dir) {
44 // TODO: fix the goto hell below.
45 int type_ok;
46 int owner_match;
47 int mode_match;
48
43 // Check if path needs to be created 49 // Check if path needs to be created
44 struct stat sb; 50 struct stat sb;
45 int create_result = -1; 51 int create_result = -1;
@@ -53,14 +59,14 @@ static int fs_prepare_path_impl(const char* path, mode_t mode, uid_t uid, gid_t
53 } 59 }
54 60
55 // Exists, verify status 61 // Exists, verify status
56 int type_ok = prepare_as_dir ? S_ISDIR(sb.st_mode) : S_ISREG(sb.st_mode); 62 type_ok = prepare_as_dir ? S_ISDIR(sb.st_mode) : S_ISREG(sb.st_mode);
57 if (!type_ok) { 63 if (!type_ok) {
58 ALOGE("Not a %s: %s", (prepare_as_dir ? "directory" : "regular file"), path); 64 ALOGE("Not a %s: %s", (prepare_as_dir ? "directory" : "regular file"), path);
59 return -1; 65 return -1;
60 } 66 }
61 67
62 int owner_match = ((sb.st_uid == uid) && (sb.st_gid == gid)); 68 owner_match = ((sb.st_uid == uid) && (sb.st_gid == gid));
63 int mode_match = ((sb.st_mode & ALL_PERMS) == mode); 69 mode_match = ((sb.st_mode & ALL_PERMS) == mode);
64 if (owner_match && mode_match) { 70 if (owner_match && mode_match) {
65 return 0; 71 return 0;
66 } else if (allow_fixup) { 72 } else if (allow_fixup) {
@@ -188,23 +194,20 @@ fail_closed:
188#ifndef __APPLE__ 194#ifndef __APPLE__
189 195
190int fs_mkdirs(const char* path, mode_t mode) { 196int fs_mkdirs(const char* path, mode_t mode) {
191 int res = 0; 197 if (*path != '/') {
192 int fd = 0; 198 ALOGE("Relative paths are not allowed: %s", path);
193 struct stat sb; 199 return -EINVAL;
194 char* buf = strdup(path);
195
196 if (*buf != '/') {
197 ALOGE("Relative paths are not allowed: %s", buf);
198 res = -EINVAL;
199 goto done;
200 } 200 }
201 201
202 if ((fd = open("/", 0)) == -1) { 202 int fd = open("/", 0);
203 if (fd == -1) {
203 ALOGE("Failed to open(/): %s", strerror(errno)); 204 ALOGE("Failed to open(/): %s", strerror(errno));
204 res = -errno; 205 return -errno;
205 goto done;
206 } 206 }
207 207
208 struct stat sb;
209 int res = 0;
210 char* buf = strdup(path);
208 char* segment = buf + 1; 211 char* segment = buf + 1;
209 char* p = segment; 212 char* p = segment;
210 while (*p != '\0') { 213 while (*p != '\0') {
@@ -266,7 +269,6 @@ int fs_mkdirs(const char* path, mode_t mode) {
266 269
267done_close: 270done_close:
268 close(fd); 271 close(fd);
269done:
270 free(buf); 272 free(buf);
271 return res; 273 return res;
272} 274}
diff --git a/libcutils/fs_config.cpp b/libcutils/fs_config.cpp
index 7603ffce6..f45472e7e 100644
--- a/libcutils/fs_config.cpp
+++ b/libcutils/fs_config.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <private/fs_config.h>
18
17// This file is used to define the properties of the filesystem 19// This file is used to define the properties of the filesystem
18// images generated by build tools (mkbootfs and mkyaffs2image) and 20// images generated by build tools (mkbootfs and mkyaffs2image) and
19// by the device side of adb. 21// by the device side of adb.
@@ -31,7 +33,6 @@
31 33
32#include <log/log.h> 34#include <log/log.h>
33#include <private/android_filesystem_config.h> 35#include <private/android_filesystem_config.h>
34#include <private/fs_config.h>
35#include <utils/Compat.h> 36#include <utils/Compat.h>
36 37
37#ifndef O_BINARY 38#ifndef O_BINARY
diff --git a/libcutils/hashmap.c b/libcutils/hashmap.cpp
index ede3b981d..65b6ab185 100644
--- a/libcutils/hashmap.c
+++ b/libcutils/hashmap.cpp
@@ -15,6 +15,7 @@
15 */ 15 */
16 16
17#include <cutils/hashmap.h> 17#include <cutils/hashmap.h>
18
18#include <assert.h> 19#include <assert.h>
19#include <errno.h> 20#include <errno.h>
20#include <cutils/threads.h> 21#include <cutils/threads.h>
@@ -45,7 +46,7 @@ Hashmap* hashmapCreate(size_t initialCapacity,
45 assert(hash != NULL); 46 assert(hash != NULL);
46 assert(equals != NULL); 47 assert(equals != NULL);
47 48
48 Hashmap* map = malloc(sizeof(Hashmap)); 49 Hashmap* map = static_cast<Hashmap*>(malloc(sizeof(Hashmap)));
49 if (map == NULL) { 50 if (map == NULL) {
50 return NULL; 51 return NULL;
51 } 52 }
@@ -58,7 +59,7 @@ Hashmap* hashmapCreate(size_t initialCapacity,
58 map->bucketCount <<= 1; 59 map->bucketCount <<= 1;
59 } 60 }
60 61
61 map->buckets = calloc(map->bucketCount, sizeof(Entry*)); 62 map->buckets = static_cast<Entry**>(calloc(map->bucketCount, sizeof(Entry*)));
62 if (map->buckets == NULL) { 63 if (map->buckets == NULL) {
63 free(map); 64 free(map);
64 return NULL; 65 return NULL;
@@ -106,7 +107,7 @@ static void expandIfNecessary(Hashmap* map) {
106 if (map->size > (map->bucketCount * 3 / 4)) { 107 if (map->size > (map->bucketCount * 3 / 4)) {
107 // Start off with a 0.33 load factor. 108 // Start off with a 0.33 load factor.
108 size_t newBucketCount = map->bucketCount << 1; 109 size_t newBucketCount = map->bucketCount << 1;
109 Entry** newBuckets = calloc(newBucketCount, sizeof(Entry*)); 110 Entry** newBuckets = static_cast<Entry**>(calloc(newBucketCount, sizeof(Entry*)));
110 if (newBuckets == NULL) { 111 if (newBuckets == NULL) {
111 // Abort expansion. 112 // Abort expansion.
112 return; 113 return;
@@ -171,7 +172,7 @@ int hashmapHash(void* key, size_t keySize) {
171} 172}
172 173
173static Entry* createEntry(void* key, int hash, void* value) { 174static Entry* createEntry(void* key, int hash, void* value) {
174 Entry* entry = malloc(sizeof(Entry)); 175 Entry* entry = static_cast<Entry*>(malloc(sizeof(Entry)));
175 if (entry == NULL) { 176 if (entry == NULL) {
176 return NULL; 177 return NULL;
177 } 178 }
diff --git a/libcutils/include/cutils/android_reboot.h b/libcutils/include/cutils/android_reboot.h
index a903adba3..99030eddd 100644
--- a/libcutils/include/cutils/android_reboot.h
+++ b/libcutils/include/cutils/android_reboot.h
@@ -17,6 +17,7 @@
17#ifndef __CUTILS_ANDROID_REBOOT_H__ 17#ifndef __CUTILS_ANDROID_REBOOT_H__
18#define __CUTILS_ANDROID_REBOOT_H__ 18#define __CUTILS_ANDROID_REBOOT_H__
19 19
20#include <sys/cdefs.h>
20 21
21__BEGIN_DECLS 22__BEGIN_DECLS
22 23
diff --git a/libcutils/include/cutils/partition_utils.h b/libcutils/include/cutils/partition_utils.h
index 72ca80d35..7518559a4 100644
--- a/libcutils/include/cutils/partition_utils.h
+++ b/libcutils/include/cutils/partition_utils.h
@@ -17,6 +17,8 @@
17#ifndef __CUTILS_PARTITION_WIPED_H__ 17#ifndef __CUTILS_PARTITION_WIPED_H__
18#define __CUTILS_PARTITION_WIPED_H__ 18#define __CUTILS_PARTITION_WIPED_H__
19 19
20#include <sys/cdefs.h>
21
20__BEGIN_DECLS 22__BEGIN_DECLS
21 23
22int partition_wiped(char *source); 24int partition_wiped(char *source);
diff --git a/libcutils/include/cutils/qtaguid.h b/libcutils/include/cutils/qtaguid.h
index 803fe0d9a..3f5e41fd3 100644
--- a/libcutils/include/cutils/qtaguid.h
+++ b/libcutils/include/cutils/qtaguid.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2011 The Android Open Source Project 2 * Copyright (C) 2017 The Android Open Source Project
3 * 3 *
4 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License. 5 * you may not use this file except in compliance with the License.
@@ -17,18 +17,14 @@
17#ifndef __CUTILS_QTAGUID_H 17#ifndef __CUTILS_QTAGUID_H
18#define __CUTILS_QTAGUID_H 18#define __CUTILS_QTAGUID_H
19 19
20#include <stdint.h>
21#include <sys/types.h> 20#include <sys/types.h>
22#include <unistd.h>
23 21
24#ifdef __cplusplus 22#ifdef __cplusplus
25extern "C" { 23extern "C" {
26#endif 24#endif
27 25
28/* 26/*
29 * Set tags (and owning UIDs) for network sockets. The socket must be untagged 27 * Set tags (and owning UIDs) for network sockets.
30 * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid
31 * module will keep a reference to it even after close.
32 */ 28 */
33extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid); 29extern int qtaguid_tagSocket(int sockfd, int tag, uid_t uid);
34 30
@@ -46,8 +42,8 @@ extern int qtaguid_setCounterSet(int counterSetNum, uid_t uid);
46 42
47/* 43/*
48 * Delete all tag info that relates to the given tag an uid. 44 * Delete all tag info that relates to the given tag an uid.
49 * If the tag is 0, then ALL info about the uid is freeded. 45 * If the tag is 0, then ALL info about the uid is freed.
50 * The delete data also affects active tagged socketd, which are 46 * The delete data also affects active tagged sockets, which are
51 * then untagged. 47 * then untagged.
52 * The calling process can only operate on its own tags. 48 * The calling process can only operate on its own tags.
53 * Unless it is part of the happy AID_NET_BW_ACCT group. 49 * Unless it is part of the happy AID_NET_BW_ACCT group.
diff --git a/libcutils/include/cutils/record_stream.h b/libcutils/include/cutils/record_stream.h
index bfac87a53..bcfc80d5d 100644
--- a/libcutils/include/cutils/record_stream.h
+++ b/libcutils/include/cutils/record_stream.h
@@ -25,6 +25,7 @@
25extern "C" { 25extern "C" {
26#endif 26#endif
27 27
28#include <stddef.h>
28 29
29typedef struct RecordStream RecordStream; 30typedef struct RecordStream RecordStream;
30 31
diff --git a/libcutils/include/private/canned_fs_config.h b/libcutils/include/private/canned_fs_config.h
index 71e1537b2..135b91c6c 100644
--- a/libcutils/include/private/canned_fs_config.h
+++ b/libcutils/include/private/canned_fs_config.h
@@ -19,8 +19,12 @@
19 19
20#include <inttypes.h> 20#include <inttypes.h>
21 21
22__BEGIN_DECLS
23
22int load_canned_fs_config(const char* fn); 24int load_canned_fs_config(const char* fn);
23void canned_fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid, 25void canned_fs_config(const char* path, int dir, const char* target_out_path, unsigned* uid,
24 unsigned* gid, unsigned* mode, uint64_t* capabilities); 26 unsigned* gid, unsigned* mode, uint64_t* capabilities);
25 27
28__END_DECLS
29
26#endif 30#endif
diff --git a/libcutils/include/private/fs_config.h b/libcutils/include/private/fs_config.h
index aab504281..892649187 100644
--- a/libcutils/include/private/fs_config.h
+++ b/libcutils/include/private/fs_config.h
@@ -24,6 +24,7 @@
24 24
25#include <stdint.h> 25#include <stdint.h>
26#include <sys/cdefs.h> 26#include <sys/cdefs.h>
27#include <sys/types.h>
27 28
28#if defined(__BIONIC__) 29#if defined(__BIONIC__)
29#include <linux/capability.h> 30#include <linux/capability.h>
diff --git a/libcutils/iosched_policy.c b/libcutils/iosched_policy.cpp
index 13c2cebbc..012c537ac 100644
--- a/libcutils/iosched_policy.c
+++ b/libcutils/iosched_policy.cpp
@@ -14,6 +14,8 @@
14** limitations under the License. 14** limitations under the License.
15*/ 15*/
16 16
17#include <cutils/iosched_policy.h>
18
17#include <errno.h> 19#include <errno.h>
18#include <fcntl.h> 20#include <fcntl.h>
19#include <stdio.h> 21#include <stdio.h>
@@ -21,8 +23,6 @@
21#include <string.h> 23#include <string.h>
22#include <unistd.h> 24#include <unistd.h>
23 25
24#include <cutils/iosched_policy.h>
25
26#if defined(__ANDROID__) 26#if defined(__ANDROID__)
27#define IOPRIO_WHO_PROCESS (1) 27#define IOPRIO_WHO_PROCESS (1)
28#define IOPRIO_CLASS_SHIFT (13) 28#define IOPRIO_CLASS_SHIFT (13)
@@ -49,7 +49,7 @@ int android_get_ioprio(int pid __android_unused, IoSchedClass *clazz, int *iopri
49 return -1; 49 return -1;
50 } 50 }
51 51
52 *clazz = (rc >> IOPRIO_CLASS_SHIFT); 52 *clazz = static_cast<IoSchedClass>(rc >> IOPRIO_CLASS_SHIFT);
53 *ioprio = (rc & 0xff); 53 *ioprio = (rc & 0xff);
54#else 54#else
55 *clazz = IoSchedClass_NONE; 55 *clazz = IoSchedClass_NONE;
diff --git a/libcutils/klog.cpp b/libcutils/klog.cpp
index d301276f9..6a9f4df8a 100644
--- a/libcutils/klog.cpp
+++ b/libcutils/klog.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/klog.h>
18
17#include <errno.h> 19#include <errno.h>
18#include <fcntl.h> 20#include <fcntl.h>
19#include <stdarg.h> 21#include <stdarg.h>
@@ -25,7 +27,6 @@
25#include <unistd.h> 27#include <unistd.h>
26 28
27#include <cutils/android_get_control_file.h> 29#include <cutils/android_get_control_file.h>
28#include <cutils/klog.h>
29 30
30static int klog_level = KLOG_INFO_LEVEL; 31static int klog_level = KLOG_INFO_LEVEL;
31 32
diff --git a/libcutils/load_file.c b/libcutils/load_file.cpp
index 99f2965ae..346105c5c 100644
--- a/libcutils/load_file.c
+++ b/libcutils/load_file.cpp
@@ -15,6 +15,8 @@
15** limitations under the License. 15** limitations under the License.
16*/ 16*/
17 17
18#include <cutils/misc.h>
19
18#include <stdlib.h> 20#include <stdlib.h>
19#include <unistd.h> 21#include <unistd.h>
20#include <fcntl.h> 22#include <fcntl.h>
diff --git a/libcutils/multiuser.c b/libcutils/multiuser.cpp
index 61403f4f1..0fd3d0c52 100644
--- a/libcutils/multiuser.c
+++ b/libcutils/multiuser.cpp
@@ -53,9 +53,11 @@ gid_t multiuser_get_ext_cache_gid(userid_t user_id, appid_t app_id) {
53 } 53 }
54} 54}
55 55
56gid_t multiuser_get_shared_gid(userid_t user_id, appid_t app_id) { 56gid_t multiuser_get_shared_gid(userid_t, appid_t app_id) {
57 if (app_id >= AID_APP_START && app_id <= AID_APP_END) { 57 if (app_id >= AID_APP_START && app_id <= AID_APP_END) {
58 return multiuser_get_uid(user_id, (app_id - AID_APP_START) + AID_SHARED_GID_START); 58 return (app_id - AID_APP_START) + AID_SHARED_GID_START;
59 } else if (app_id >= AID_ROOT && app_id <= AID_APP_START) {
60 return app_id;
59 } else { 61 } else {
60 return -1; 62 return -1;
61 } 63 }
diff --git a/libcutils/native_handle.c b/libcutils/native_handle.cpp
index 95bbc41c4..66f7a3d59 100644
--- a/libcutils/native_handle.c
+++ b/libcutils/native_handle.cpp
@@ -45,7 +45,7 @@ native_handle_t* native_handle_create(int numFds, int numInts) {
45 } 45 }
46 46
47 size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts)); 47 size_t mallocSize = sizeof(native_handle_t) + (sizeof(int) * (numFds + numInts));
48 native_handle_t* h = malloc(mallocSize); 48 native_handle_t* h = static_cast<native_handle_t*>(malloc(mallocSize));
49 if (h) { 49 if (h) {
50 h->version = sizeof(native_handle_t); 50 h->version = sizeof(native_handle_t);
51 h->numFds = numFds; 51 h->numFds = numFds;
diff --git a/libcutils/partition_utils.c b/libcutils/partition_utils.cpp
index 823b16289..6735d6cc8 100644
--- a/libcutils/partition_utils.c
+++ b/libcutils/partition_utils.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/partition_utils.h>
18
17#include <fcntl.h> 19#include <fcntl.h>
18#include <sys/ioctl.h> 20#include <sys/ioctl.h>
19#include <sys/mount.h> /* for BLKGETSIZE */ 21#include <sys/mount.h> /* for BLKGETSIZE */
diff --git a/libcutils/properties.cpp b/libcutils/properties.cpp
index 25ff1a3ad..5dbbeba48 100644
--- a/libcutils/properties.cpp
+++ b/libcutils/properties.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/properties.h>
18
17#define LOG_TAG "properties" 19#define LOG_TAG "properties"
18// #define LOG_NDEBUG 0 20// #define LOG_NDEBUG 0
19 21
@@ -25,7 +27,6 @@
25#include <string.h> 27#include <string.h>
26#include <unistd.h> 28#include <unistd.h>
27 29
28#include <cutils/properties.h>
29#include <cutils/sockets.h> 30#include <cutils/sockets.h>
30#include <log/log.h> 31#include <log/log.h>
31 32
diff --git a/libcutils/qtaguid.cpp b/libcutils/qtaguid.cpp
new file mode 100644
index 000000000..b94d134be
--- /dev/null
+++ b/libcutils/qtaguid.cpp
@@ -0,0 +1,126 @@
1/*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <cutils/qtaguid.h>
18
19// #define LOG_NDEBUG 0
20
21#define LOG_TAG "qtaguid"
22
23#include <dlfcn.h>
24#include <errno.h>
25#include <fcntl.h>
26#include <inttypes.h>
27#include <stdio.h>
28#include <string.h>
29#include <unistd.h>
30
31#include <log/log.h>
32
33class netdHandler {
34 public:
35 int (*netdTagSocket)(int, uint32_t, uid_t);
36 int (*netdUntagSocket)(int);
37 int (*netdSetCounterSet)(uint32_t, uid_t);
38 int (*netdDeleteTagData)(uint32_t, uid_t);
39};
40
41int dummyTagSocket(int, uint32_t, uid_t) {
42 return -EREMOTEIO;
43}
44
45int dummyUntagSocket(int) {
46 return -EREMOTEIO;
47}
48
49int dummySetCounterSet(uint32_t, uid_t) {
50 return -EREMOTEIO;
51}
52
53int dummyDeleteTagData(uint32_t, uid_t) {
54 return -EREMOTEIO;
55}
56
57netdHandler initHandler(void) {
58 netdHandler handler = {dummyTagSocket, dummyUntagSocket, dummySetCounterSet, dummyDeleteTagData};
59
60 void* netdClientHandle = dlopen("libnetd_client.so", RTLD_NOW);
61 if (!netdClientHandle) {
62 ALOGE("Failed to open libnetd_client.so: %s", dlerror());
63 return handler;
64 }
65
66 handler.netdTagSocket = (int (*)(int, uint32_t, uid_t))dlsym(netdClientHandle, "tagSocket");
67 if (!handler.netdTagSocket) {
68 ALOGE("load netdTagSocket handler failed: %s", dlerror());
69 }
70
71 handler.netdUntagSocket = (int (*)(int))dlsym(netdClientHandle, "untagSocket");
72 if (!handler.netdUntagSocket) {
73 ALOGE("load netdUntagSocket handler failed: %s", dlerror());
74 }
75
76 handler.netdSetCounterSet = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "setCounterSet");
77 if (!handler.netdSetCounterSet) {
78 ALOGE("load netdSetCounterSet handler failed: %s", dlerror());
79 }
80
81 handler.netdDeleteTagData = (int (*)(uint32_t, uid_t))dlsym(netdClientHandle, "deleteTagData");
82 if (!handler.netdDeleteTagData) {
83 ALOGE("load netdDeleteTagData handler failed: %s", dlerror());
84 }
85 return handler;
86}
87
88// The language guarantees that this object will be initialized in a thread-safe way.
89static netdHandler& getHandler() {
90 static netdHandler instance = initHandler();
91 return instance;
92}
93
94int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
95 // Check the socket fd passed to us is still valid before we load the netd
96 // client. Pass a already closed socket fd to netd client may let netd open
97 // the unix socket with the same fd number and pass it to server for
98 // tagging.
99 // TODO: move the check into netdTagSocket.
100 int res = fcntl(sockfd, F_GETFD);
101 if (res < 0) return res;
102
103 ALOGV("Tagging socket %d with tag %u for uid %d", sockfd, tag, uid);
104 return getHandler().netdTagSocket(sockfd, tag, uid);
105}
106
107int qtaguid_untagSocket(int sockfd) {
108 // Similiar to tag socket. We need a check before untag to make sure untag a closed socket fail
109 // as expected.
110 // TODO: move the check into netdTagSocket.
111 int res = fcntl(sockfd, F_GETFD);
112 if (res < 0) return res;
113
114 ALOGV("Untagging socket %d", sockfd);
115 return getHandler().netdUntagSocket(sockfd);
116}
117
118int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
119 ALOGV("Setting counters to set %d for uid %d", counterSetNum, uid);
120 return getHandler().netdSetCounterSet(counterSetNum, uid);
121}
122
123int qtaguid_deleteTagData(int tag, uid_t uid) {
124 ALOGV("Deleting tag data with tag %u for uid %d", tag, uid);
125 return getHandler().netdDeleteTagData(tag, uid);
126}
diff --git a/libcutils/record_stream.c b/libcutils/record_stream.cpp
index 2bc4226ed..5a86b8393 100644
--- a/libcutils/record_stream.c
+++ b/libcutils/record_stream.cpp
@@ -15,11 +15,12 @@
15** limitations under the License. 15** limitations under the License.
16*/ 16*/
17 17
18#include <cutils/record_stream.h>
19
18#include <stdlib.h> 20#include <stdlib.h>
19#include <unistd.h> 21#include <unistd.h>
20#include <assert.h> 22#include <assert.h>
21#include <errno.h> 23#include <errno.h>
22#include <cutils/record_stream.h>
23#include <string.h> 24#include <string.h>
24#include <stdint.h> 25#include <stdint.h>
25#if defined(_WIN32) 26#if defined(_WIN32)
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index b00fa8561..0e6d33333 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -14,6 +14,8 @@
14** limitations under the License. 14** limitations under the License.
15*/ 15*/
16 16
17#include <cutils/sched_policy.h>
18
17#define LOG_TAG "SchedPolicy" 19#define LOG_TAG "SchedPolicy"
18 20
19#include <errno.h> 21#include <errno.h>
@@ -24,7 +26,6 @@
24#include <unistd.h> 26#include <unistd.h>
25 27
26#include <log/log.h> 28#include <log/log.h>
27#include <cutils/sched_policy.h>
28 29
29#define UNUSED __attribute__((__unused__)) 30#define UNUSED __attribute__((__unused__))
30 31
diff --git a/libcutils/socket_inaddr_any_server_unix.c b/libcutils/socket_inaddr_any_server_unix.cpp
index 387258fdf..27c5333f3 100644
--- a/libcutils/socket_inaddr_any_server_unix.c
+++ b/libcutils/socket_inaddr_any_server_unix.cpp
@@ -14,6 +14,8 @@
14** limitations under the License. 14** limitations under the License.
15*/ 15*/
16 16
17#include <cutils/sockets.h>
18
17#include <errno.h> 19#include <errno.h>
18#include <stddef.h> 20#include <stddef.h>
19#include <stdlib.h> 21#include <stdlib.h>
@@ -25,8 +27,6 @@
25#include <sys/types.h> 27#include <sys/types.h>
26#include <netinet/in.h> 28#include <netinet/in.h>
27 29
28#include <cutils/sockets.h>
29
30#define LISTEN_BACKLOG 4 30#define LISTEN_BACKLOG 4
31 31
32/* open listen() port on any interface */ 32/* open listen() port on any interface */
diff --git a/libcutils/socket_inaddr_any_server_windows.c b/libcutils/socket_inaddr_any_server_windows.cpp
index c15200ad5..1d7320698 100644
--- a/libcutils/socket_inaddr_any_server_windows.c
+++ b/libcutils/socket_inaddr_any_server_windows.cpp
@@ -26,10 +26,10 @@
26 * SUCH DAMAGE. 26 * SUCH DAMAGE.
27 */ 27 */
28 28
29#include <errno.h>
30
31#include <cutils/sockets.h> 29#include <cutils/sockets.h>
32 30
31#include <errno.h>
32
33#define LISTEN_BACKLOG 4 33#define LISTEN_BACKLOG 4
34 34
35extern bool initialize_windows_sockets(); 35extern bool initialize_windows_sockets();
diff --git a/libcutils/socket_local_client_unix.c b/libcutils/socket_local_client_unix.cpp
index 92fb9f17d..68b2b0ce9 100644
--- a/libcutils/socket_local_client_unix.c
+++ b/libcutils/socket_local_client_unix.cpp
@@ -14,14 +14,14 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/sockets.h>
18
17#include <errno.h> 19#include <errno.h>
18#include <stddef.h> 20#include <stddef.h>
19#include <stdlib.h> 21#include <stdlib.h>
20#include <string.h> 22#include <string.h>
21#include <unistd.h> 23#include <unistd.h>
22 24
23#include <cutils/sockets.h>
24
25#if defined(_WIN32) 25#if defined(_WIN32)
26 26
27int socket_local_client(const char *name, int namespaceId, int type) 27int socket_local_client(const char *name, int namespaceId, int type)
diff --git a/libcutils/socket_local_server_unix.c b/libcutils/socket_local_server_unix.cpp
index db9e1e04d..855e5da4e 100644
--- a/libcutils/socket_local_server_unix.c
+++ b/libcutils/socket_local_server_unix.cpp
@@ -94,7 +94,7 @@ int socket_local_server_bind(int s, const char *name, int namespaceId)
94 * Returns fd on success, -1 on fail 94 * Returns fd on success, -1 on fail
95 */ 95 */
96 96
97int socket_local_server(const char *name, int namespace, int type) 97int socket_local_server(const char *name, int namespaceId, int type)
98{ 98{
99 int err; 99 int err;
100 int s; 100 int s;
@@ -102,7 +102,7 @@ int socket_local_server(const char *name, int namespace, int type)
102 s = socket(AF_LOCAL, type, 0); 102 s = socket(AF_LOCAL, type, 0);
103 if (s < 0) return -1; 103 if (s < 0) return -1;
104 104
105 err = socket_local_server_bind(s, name, namespace); 105 err = socket_local_server_bind(s, name, namespaceId);
106 106
107 if (err < 0) { 107 if (err < 0) {
108 close(s); 108 close(s);
diff --git a/libcutils/socket_network_client_unix.c b/libcutils/socket_network_client_unix.cpp
index 1b87c49be..be3c53575 100644
--- a/libcutils/socket_network_client_unix.c
+++ b/libcutils/socket_network_client_unix.cpp
@@ -14,6 +14,8 @@
14** limitations under the License. 14** limitations under the License.
15*/ 15*/
16 16
17#include <cutils/sockets.h>
18
17#include <errno.h> 19#include <errno.h>
18#include <fcntl.h> 20#include <fcntl.h>
19#include <stddef.h> 21#include <stddef.h>
@@ -27,8 +29,6 @@
27#include <netinet/in.h> 29#include <netinet/in.h>
28#include <netdb.h> 30#include <netdb.h>
29 31
30#include <cutils/sockets.h>
31
32static int toggle_O_NONBLOCK(int s) { 32static int toggle_O_NONBLOCK(int s) {
33 int flags = fcntl(s, F_GETFL); 33 int flags = fcntl(s, F_GETFL);
34 if (flags == -1 || fcntl(s, F_SETFL, flags ^ O_NONBLOCK) == -1) { 34 if (flags == -1 || fcntl(s, F_SETFL, flags ^ O_NONBLOCK) == -1) {
diff --git a/libcutils/socket_network_client_windows.c b/libcutils/socket_network_client_windows.cpp
index ab1a52f74..ab1a52f74 100644
--- a/libcutils/socket_network_client_windows.c
+++ b/libcutils/socket_network_client_windows.cpp
diff --git a/libcutils/sockets_unix.cpp b/libcutils/sockets_unix.cpp
index e91f35831..2849aa886 100644
--- a/libcutils/sockets_unix.cpp
+++ b/libcutils/sockets_unix.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/sockets.h>
18
17#define LOG_TAG "socket-unix" 19#define LOG_TAG "socket-unix"
18 20
19#include <stdio.h> 21#include <stdio.h>
@@ -26,7 +28,6 @@
26#include <unistd.h> 28#include <unistd.h>
27 29
28#include <cutils/android_get_control_file.h> 30#include <cutils/android_get_control_file.h>
29#include <cutils/sockets.h>
30#include <log/log.h> 31#include <log/log.h>
31 32
32#include "android_get_control_env.h" 33#include "android_get_control_env.h"
diff --git a/libcutils/sockets_windows.cpp b/libcutils/sockets_windows.cpp
index 3064c70e5..df1471220 100644
--- a/libcutils/sockets_windows.cpp
+++ b/libcutils/sockets_windows.cpp
@@ -37,7 +37,7 @@
37// Both adb (1) and Chrome (2) purposefully avoid WSACleanup() with no issues. 37// Both adb (1) and Chrome (2) purposefully avoid WSACleanup() with no issues.
38// (1) https://android.googlesource.com/platform/system/core.git/+/master/adb/sysdeps_win32.cpp 38// (1) https://android.googlesource.com/platform/system/core.git/+/master/adb/sysdeps_win32.cpp
39// (2) https://code.google.com/p/chromium/codesearch#chromium/src/net/base/winsock_init.cc 39// (2) https://code.google.com/p/chromium/codesearch#chromium/src/net/base/winsock_init.cc
40extern "C" bool initialize_windows_sockets() { 40bool initialize_windows_sockets() {
41 // There's no harm in calling WSAStartup() multiple times but no benefit 41 // There's no harm in calling WSAStartup() multiple times but no benefit
42 // either, we may as well skip it after the first. 42 // either, we may as well skip it after the first.
43 static bool init_success = false; 43 static bool init_success = false;
@@ -85,6 +85,6 @@ ssize_t socket_send_buffers(cutils_socket_t sock,
85 return -1; 85 return -1;
86} 86}
87 87
88int android_get_control_socket(const char* name) { 88int android_get_control_socket(const char*) {
89 return -1; 89 return -1;
90} 90}
diff --git a/libcutils/str_parms.c b/libcutils/str_parms.cpp
index 8dafdedac..139d62f6d 100644
--- a/libcutils/str_parms.c
+++ b/libcutils/str_parms.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/str_parms.h>
18
17#define LOG_TAG "str_params" 19#define LOG_TAG "str_params"
18//#define LOG_NDEBUG 0 20//#define LOG_NDEBUG 0
19 21
@@ -26,7 +28,6 @@
26 28
27#include <cutils/hashmap.h> 29#include <cutils/hashmap.h>
28#include <cutils/memory.h> 30#include <cutils/memory.h>
29#include <cutils/str_parms.h>
30#include <log/log.h> 31#include <log/log.h>
31 32
32#define UNUSED __attribute__((unused)) 33#define UNUSED __attribute__((unused))
@@ -62,30 +63,24 @@ __attribute__((no_sanitize("integer")))
62static int str_hash_fn(void *str) 63static int str_hash_fn(void *str)
63{ 64{
64 uint32_t hash = 5381; 65 uint32_t hash = 5381;
65 char *p;
66 66
67 for (p = str; p && *p; p++) 67 for (char* p = static_cast<char*>(str); p && *p; p++)
68 hash = ((hash << 5) + hash) + *p; 68 hash = ((hash << 5) + hash) + *p;
69 return (int)hash; 69 return (int)hash;
70} 70}
71 71
72struct str_parms *str_parms_create(void) 72struct str_parms *str_parms_create(void)
73{ 73{
74 struct str_parms *str_parms; 74 str_parms* s = static_cast<str_parms*>(calloc(1, sizeof(str_parms)));
75 if (!s) return NULL;
75 76
76 str_parms = calloc(1, sizeof(struct str_parms)); 77 s->map = hashmapCreate(5, str_hash_fn, str_eq);
77 if (!str_parms) 78 if (!s->map) {
79 free(s);
78 return NULL; 80 return NULL;
81 }
79 82
80 str_parms->map = hashmapCreate(5, str_hash_fn, str_eq); 83 return s;
81 if (!str_parms->map)
82 goto err;
83
84 return str_parms;
85
86err:
87 free(str_parms);
88 return NULL;
89} 84}
90 85
91struct remove_ctxt { 86struct remove_ctxt {
@@ -95,7 +90,7 @@ struct remove_ctxt {
95 90
96static bool remove_pair(void *key, void *value, void *context) 91static bool remove_pair(void *key, void *value, void *context)
97{ 92{
98 struct remove_ctxt *ctxt = context; 93 remove_ctxt* ctxt = static_cast<remove_ctxt*>(context);
99 bool should_continue; 94 bool should_continue;
100 95
101 /* 96 /*
@@ -109,7 +104,7 @@ static bool remove_pair(void *key, void *value, void *context)
109 if (!ctxt->key) { 104 if (!ctxt->key) {
110 should_continue = true; 105 should_continue = true;
111 goto do_remove; 106 goto do_remove;
112 } else if (!strcmp(ctxt->key, key)) { 107 } else if (!strcmp(ctxt->key, static_cast<const char*>(key))) {
113 should_continue = false; 108 should_continue = false;
114 goto do_remove; 109 goto do_remove;
115 } 110 }
@@ -292,9 +287,8 @@ int str_parms_has_key(struct str_parms *str_parms, const char *key) {
292int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val, 287int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
293 int len) 288 int len)
294{ 289{
295 char *value; 290 // TODO: hashmapGet should take a const* key.
296 291 char* value = static_cast<char*>(hashmapGet(str_parms->map, (void*)key));
297 value = hashmapGet(str_parms->map, (void *)key);
298 if (value) 292 if (value)
299 return strlcpy(val, value, len); 293 return strlcpy(val, value, len);
300 294
@@ -303,10 +297,10 @@ int str_parms_get_str(struct str_parms *str_parms, const char *key, char *val,
303 297
304int str_parms_get_int(struct str_parms *str_parms, const char *key, int *val) 298int str_parms_get_int(struct str_parms *str_parms, const char *key, int *val)
305{ 299{
306 char *value;
307 char *end; 300 char *end;
308 301
309 value = hashmapGet(str_parms->map, (void *)key); 302 // TODO: hashmapGet should take a const* key.
303 char* value = static_cast<char*>(hashmapGet(str_parms->map, (void*)key));
310 if (!value) 304 if (!value)
311 return -ENOENT; 305 return -ENOENT;
312 306
@@ -321,10 +315,10 @@ int str_parms_get_float(struct str_parms *str_parms, const char *key,
321 float *val) 315 float *val)
322{ 316{
323 float out; 317 float out;
324 char *value;
325 char *end; 318 char *end;
326 319
327 value = hashmapGet(str_parms->map, (void *)key); 320 // TODO: hashmapGet should take a const* key.
321 char* value = static_cast<char*>(hashmapGet(str_parms->map, (void*)(key)));
328 if (!value) 322 if (!value)
329 return -ENOENT; 323 return -ENOENT;
330 324
@@ -338,7 +332,7 @@ int str_parms_get_float(struct str_parms *str_parms, const char *key,
338 332
339static bool combine_strings(void *key, void *value, void *context) 333static bool combine_strings(void *key, void *value, void *context)
340{ 334{
341 char **old_str = context; 335 char** old_str = static_cast<char**>(context);
342 char *new_str; 336 char *new_str;
343 int ret; 337 int ret;
344 338
diff --git a/libcutils/strdup16to8.c b/libcutils/strdup16to8.cpp
index 4dc987e41..d89181e14 100644
--- a/libcutils/strdup16to8.c
+++ b/libcutils/strdup16to8.cpp
@@ -15,10 +15,10 @@
15** limitations under the License. 15** limitations under the License.
16*/ 16*/
17 17
18#include <limits.h> /* for SIZE_MAX */
19
20#include <cutils/jstring.h> 18#include <cutils/jstring.h>
19
21#include <assert.h> 20#include <assert.h>
21#include <limits.h> /* for SIZE_MAX */
22#include <stdlib.h> 22#include <stdlib.h>
23 23
24 24
@@ -145,14 +145,11 @@ extern char* strncpy16to8(char* utf8Str, const char16_t* utf16Str, size_t len)
145 */ 145 */
146char * strndup16to8 (const char16_t* s, size_t n) 146char * strndup16to8 (const char16_t* s, size_t n)
147{ 147{
148 char* ret;
149 size_t len;
150
151 if (s == NULL) { 148 if (s == NULL) {
152 return NULL; 149 return NULL;
153 } 150 }
154 151
155 len = strnlen16to8(s, n); 152 size_t len = strnlen16to8(s, n);
156 153
157 /* We are paranoid, and we check for SIZE_MAX-1 154 /* We are paranoid, and we check for SIZE_MAX-1
158 * too since it is an overflow value for our 155 * too since it is an overflow value for our
@@ -161,7 +158,7 @@ char * strndup16to8 (const char16_t* s, size_t n)
161 if (len >= SIZE_MAX-1) 158 if (len >= SIZE_MAX-1)
162 return NULL; 159 return NULL;
163 160
164 ret = malloc(len + 1); 161 char* ret = static_cast<char*>(malloc(len + 1));
165 if (ret == NULL) 162 if (ret == NULL)
166 return NULL; 163 return NULL;
167 164
diff --git a/libcutils/strdup8to16.c b/libcutils/strdup8to16.cpp
index c23cf8b9a..d1e51b9ca 100644
--- a/libcutils/strdup8to16.c
+++ b/libcutils/strdup8to16.cpp
@@ -16,9 +16,10 @@
16*/ 16*/
17 17
18#include <cutils/jstring.h> 18#include <cutils/jstring.h>
19
19#include <assert.h> 20#include <assert.h>
20#include <stdlib.h>
21#include <limits.h> 21#include <limits.h>
22#include <stdlib.h>
22 23
23/* See http://www.unicode.org/reports/tr22/ for discussion 24/* See http://www.unicode.org/reports/tr22/ for discussion
24 * on invalid sequences 25 * on invalid sequences
@@ -116,7 +117,7 @@ static inline uint32_t getUtf32FromUtf8(const char** pUtf8Ptr)
116 int i; 117 int i;
117 118
118 /* Mask for leader byte for lengths 1, 2, 3, and 4 respectively*/ 119 /* Mask for leader byte for lengths 1, 2, 3, and 4 respectively*/
119 static const char leaderMask[4] = {0xff, 0x1f, 0x0f, 0x07}; 120 static const unsigned char leaderMask[4] = {0xff, 0x1f, 0x0f, 0x07};
120 121
121 /* Bytes that start with bits "10" are not leading characters. */ 122 /* Bytes that start with bits "10" are not leading characters. */
122 if (((**pUtf8Ptr) & 0xc0) == 0x80) { 123 if (((**pUtf8Ptr) & 0xc0) == 0x80) {
diff --git a/libcutils/tests/multiuser_test.cpp b/libcutils/tests/multiuser_test.cpp
index 2f9d854b3..4b0fd130f 100644
--- a/libcutils/tests/multiuser_test.cpp
+++ b/libcutils/tests/multiuser_test.cpp
@@ -57,7 +57,10 @@ TEST(MultiuserTest, TestCache) {
57 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 1000)); 57 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 1000));
58 EXPECT_EQ(20000U, multiuser_get_cache_gid(0, 10000)); 58 EXPECT_EQ(20000U, multiuser_get_cache_gid(0, 10000));
59 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 50000)); 59 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(0, 50000));
60 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 0));
61 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 1000));
60 EXPECT_EQ(1020000U, multiuser_get_cache_gid(10, 10000)); 62 EXPECT_EQ(1020000U, multiuser_get_cache_gid(10, 10000));
63 EXPECT_EQ(ERR_GID, multiuser_get_cache_gid(10, 50000));
61} 64}
62 65
63TEST(MultiuserTest, TestExt) { 66TEST(MultiuserTest, TestExt) {
@@ -77,9 +80,12 @@ TEST(MultiuserTest, TestExtCache) {
77} 80}
78 81
79TEST(MultiuserTest, TestShared) { 82TEST(MultiuserTest, TestShared) {
80 EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 0)); 83 EXPECT_EQ(0U, multiuser_get_shared_gid(0, 0));
81 EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 1000)); 84 EXPECT_EQ(1000U, multiuser_get_shared_gid(0, 1000));
82 EXPECT_EQ(50000U, multiuser_get_shared_gid(0, 10000)); 85 EXPECT_EQ(50000U, multiuser_get_shared_gid(0, 10000));
83 EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 50000)); 86 EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(0, 50000));
84 EXPECT_EQ(1050000U, multiuser_get_shared_gid(10, 10000)); 87 EXPECT_EQ(0U, multiuser_get_shared_gid(10, 0));
88 EXPECT_EQ(1000U, multiuser_get_shared_gid(10, 1000));
89 EXPECT_EQ(50000U, multiuser_get_shared_gid(10, 10000));
90 EXPECT_EQ(ERR_GID, multiuser_get_shared_gid(10, 50000));
85} 91}
diff --git a/libcutils/tests/trace-dev_test.cpp b/libcutils/tests/trace-dev_test.cpp
index edf981b39..f8d4f0064 100644
--- a/libcutils/tests/trace-dev_test.cpp
+++ b/libcutils/tests/trace-dev_test.cpp
@@ -25,7 +25,7 @@
25#include <android-base/test_utils.h> 25#include <android-base/test_utils.h>
26#include <gtest/gtest.h> 26#include <gtest/gtest.h>
27 27
28#include "../trace-dev.c" 28#include "../trace-dev.cpp"
29 29
30class TraceDevTest : public ::testing::Test { 30class TraceDevTest : public ::testing::Test {
31 protected: 31 protected:
diff --git a/libcutils/threads.c b/libcutils/threads.cpp
index 4bae39e0f..a7e6b2d8e 100644
--- a/libcutils/threads.c
+++ b/libcutils/threads.cpp
@@ -14,7 +14,7 @@
14** limitations under the License. 14** limitations under the License.
15*/ 15*/
16 16
17#include "cutils/threads.h" 17#include <cutils/threads.h>
18 18
19// For gettid. 19// For gettid.
20#if defined(__APPLE__) 20#if defined(__APPLE__)
@@ -84,7 +84,7 @@ void* thread_store_get( thread_store_t* store )
84 84
85void thread_store_set( thread_store_t* store, 85void thread_store_set( thread_store_t* store,
86 void* value, 86 void* value,
87 thread_store_destruct_t destroy ) 87 thread_store_destruct_t /*destroy*/ )
88{ 88{
89 /* XXX: can't use destructor on thread exit */ 89 /* XXX: can't use destructor on thread exit */
90 if (!store->lock_init) { 90 if (!store->lock_init) {
diff --git a/libcutils/trace-container.c b/libcutils/trace-container.cpp
index 03e91b1f2..d981f8fa5 100644
--- a/libcutils/trace-container.c
+++ b/libcutils/trace-container.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/trace.h>
18
17#include "trace-dev.inc" 19#include "trace-dev.inc"
18 20
19#include <cutils/sockets.h> 21#include <cutils/sockets.h>
diff --git a/libcutils/trace-dev.c b/libcutils/trace-dev.cpp
index 4468e83f6..4da821555 100644
--- a/libcutils/trace-dev.c
+++ b/libcutils/trace-dev.cpp
@@ -14,6 +14,8 @@
14 * limitations under the License. 14 * limitations under the License.
15 */ 15 */
16 16
17#include <cutils/trace.h>
18
17#include "trace-dev.inc" 19#include "trace-dev.inc"
18 20
19static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT; 21static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT;
diff --git a/libcutils/trace-host.c b/libcutils/trace-host.cpp
index 05842cd7d..05842cd7d 100644
--- a/libcutils/trace-host.c
+++ b/libcutils/trace-host.cpp
diff --git a/liblog/include/log/log.h b/liblog/include/log/log.h
index d01708d8b..3813e6e32 100644
--- a/liblog/include/log/log.h
+++ b/liblog/include/log/log.h
@@ -95,6 +95,8 @@ int __android_log_btwrite(int32_t tag, char type, const void* payload,
95 size_t len); 95 size_t len);
96int __android_log_bswrite(int32_t tag, const char* payload); 96int __android_log_bswrite(int32_t tag, const char* payload);
97 97
98int __android_log_stats_bwrite(int32_t tag, const void* payload, size_t len);
99
98#define android_bWriteLog(tag, payload, len) \ 100#define android_bWriteLog(tag, payload, len) \
99 __android_log_bwrite(tag, payload, len) 101 __android_log_bwrite(tag, payload, len)
100#define android_btWriteLog(tag, type, payload, len) \ 102#define android_btWriteLog(tag, type, payload, len) \
diff --git a/liblog/include/log/log_id.h b/liblog/include/log/log_id.h
index 7bfa2770b..c44f5a2eb 100644
--- a/liblog/include/log/log_id.h
+++ b/liblog/include/log/log_id.h
@@ -31,8 +31,9 @@ typedef enum log_id {
31 LOG_ID_EVENTS = 2, 31 LOG_ID_EVENTS = 2,
32 LOG_ID_SYSTEM = 3, 32 LOG_ID_SYSTEM = 3,
33 LOG_ID_CRASH = 4, 33 LOG_ID_CRASH = 4,
34 LOG_ID_SECURITY = 5, 34 LOG_ID_STATS = 5,
35 LOG_ID_KERNEL = 6, /* place last, third-parties can not use it */ 35 LOG_ID_SECURITY = 6,
36 LOG_ID_KERNEL = 7, /* place last, third-parties can not use it */
36 37
37 LOG_ID_MAX 38 LOG_ID_MAX
38} log_id_t; 39} log_id_t;
diff --git a/liblog/log_event_list.c b/liblog/log_event_list.c
index 59ea5ef13..a59cb8738 100644
--- a/liblog/log_event_list.c
+++ b/liblog/log_event_list.c
@@ -301,7 +301,7 @@ LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
301 const char* msg; 301 const char* msg;
302 ssize_t len; 302 ssize_t len;
303 303
304 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY)) { 304 if ((id != LOG_ID_EVENTS) && (id != LOG_ID_SECURITY) && (id != LOG_ID_STATS)) {
305 return -EINVAL; 305 return -EINVAL;
306 } 306 }
307 307
@@ -326,7 +326,9 @@ LIBLOG_ABI_PUBLIC int android_log_write_list(android_log_context ctx,
326 } 326 }
327 return (id == LOG_ID_EVENTS) 327 return (id == LOG_ID_EVENTS)
328 ? __android_log_bwrite(context->tag, msg, len) 328 ? __android_log_bwrite(context->tag, msg, len)
329 : __android_log_security_bwrite(context->tag, msg, len); 329 : ((id == LOG_ID_STATS)
330 ? __android_log_stats_bwrite(context->tag, msg, len)
331 : __android_log_security_bwrite(context->tag, msg, len));
330} 332}
331 333
332LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx, 334LIBLOG_ABI_PRIVATE int android_log_write_list_buffer(android_log_context ctx,
diff --git a/liblog/logger_name.c b/liblog/logger_name.c
index a5a83e05a..479bbfeec 100644
--- a/liblog/logger_name.c
+++ b/liblog/logger_name.c
@@ -22,12 +22,13 @@
22 22
23/* In the future, we would like to make this list extensible */ 23/* In the future, we would like to make this list extensible */
24static const char* LOG_NAME[LOG_ID_MAX] = { 24static const char* LOG_NAME[LOG_ID_MAX] = {
25 /* clang-format off */ 25 /* clang-format off */
26 [LOG_ID_MAIN] = "main", 26 [LOG_ID_MAIN] = "main",
27 [LOG_ID_RADIO] = "radio", 27 [LOG_ID_RADIO] = "radio",
28 [LOG_ID_EVENTS] = "events", 28 [LOG_ID_EVENTS] = "events",
29 [LOG_ID_SYSTEM] = "system", 29 [LOG_ID_SYSTEM] = "system",
30 [LOG_ID_CRASH] = "crash", 30 [LOG_ID_CRASH] = "crash",
31 [LOG_ID_STATS] = "stats",
31 [LOG_ID_SECURITY] = "security", 32 [LOG_ID_SECURITY] = "security",
32 [LOG_ID_KERNEL] = "kernel", 33 [LOG_ID_KERNEL] = "kernel",
33 /* clang-format on */ 34 /* clang-format on */
diff --git a/liblog/logger_write.c b/liblog/logger_write.c
index 84feb206b..589ce8429 100644
--- a/liblog/logger_write.c
+++ b/liblog/logger_write.c
@@ -546,6 +546,19 @@ LIBLOG_ABI_PUBLIC int __android_log_bwrite(int32_t tag, const void* payload,
546 return write_to_log(LOG_ID_EVENTS, vec, 2); 546 return write_to_log(LOG_ID_EVENTS, vec, 2);
547} 547}
548 548
549LIBLOG_ABI_PUBLIC int __android_log_stats_bwrite(int32_t tag,
550 const void* payload,
551 size_t len) {
552 struct iovec vec[2];
553
554 vec[0].iov_base = &tag;
555 vec[0].iov_len = sizeof(tag);
556 vec[1].iov_base = (void*)payload;
557 vec[1].iov_len = len;
558
559 return write_to_log(LOG_ID_STATS, vec, 2);
560}
561
549LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag, 562LIBLOG_ABI_PUBLIC int __android_log_security_bwrite(int32_t tag,
550 const void* payload, 563 const void* payload,
551 size_t len) { 564 size_t len) {
diff --git a/libqtaguid/Android.bp b/libqtaguid/Android.bp
new file mode 100644
index 000000000..de632caa2
--- /dev/null
+++ b/libqtaguid/Android.bp
@@ -0,0 +1,56 @@
1//
2// Copyright (C) 2017 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17cc_library_headers {
18 name: "libqtaguid_headers",
19 vendor_available: false,
20 host_supported: false,
21 export_include_dirs: ["include"],
22 target: {
23 linux_bionic: {
24 enabled: true,
25 },
26 },
27}
28
29cc_library {
30 name: "libqtaguid",
31 vendor_available: false,
32 host_supported: false,
33 target: {
34 android: {
35 srcs: [
36 "qtaguid.c",
37 ],
38 sanitize: {
39 misc_undefined: ["integer"],
40 },
41 },
42 },
43
44 shared_libs: ["liblog"],
45 header_libs: [
46 "libqtaguid_headers",
47 ],
48 export_header_lib_headers: ["libqtaguid_headers"],
49 local_include_dirs: ["include"],
50
51 cflags: [
52 "-Werror",
53 "-Wall",
54 "-Wextra",
55 ],
56}
diff --git a/libqtaguid/include/qtaguid/qtaguid.h b/libqtaguid/include/qtaguid/qtaguid.h
new file mode 100644
index 000000000..72285e532
--- /dev/null
+++ b/libqtaguid/include/qtaguid/qtaguid.h
@@ -0,0 +1,62 @@
1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef __LEGACY_QTAGUID_H
18#define __LEGACY_QTAGUID_H
19
20#include <stdint.h>
21#include <sys/types.h>
22#include <unistd.h>
23
24#ifdef __cplusplus
25extern "C" {
26#endif
27
28/*
29 * Set tags (and owning UIDs) for network sockets. The socket must be untagged
30 * by calling qtaguid_untagSocket() before closing it, otherwise the qtaguid
31 * module will keep a reference to it even after close.
32 */
33extern int legacy_tagSocket(int sockfd, int tag, uid_t uid);
34
35/*
36 * Untag a network socket before closing.
37 */
38extern int legacy_untagSocket(int sockfd);
39
40/*
41 * For the given uid, switch counter sets.
42 * The kernel only keeps a limited number of sets.
43 * 2 for now.
44 */
45extern int legacy_setCounterSet(int counterSetNum, uid_t uid);
46
47/*
48 * Delete all tag info that relates to the given tag an uid.
49 * If the tag is 0, then ALL info about the uid is freeded.
50 * The delete data also affects active tagged socketd, which are
51 * then untagged.
52 * The calling process can only operate on its own tags.
53 * Unless it is part of the happy AID_NET_BW_ACCT group.
54 * In which case it can clobber everything.
55 */
56extern int legacy_deleteTagData(int tag, uid_t uid);
57
58#ifdef __cplusplus
59}
60#endif
61
62#endif /* __LEGACY_QTAGUID_H */
diff --git a/libcutils/qtaguid.c b/libqtaguid/qtaguid.c
index 22b83253f..cd38bad77 100644
--- a/libcutils/qtaguid.c
+++ b/libqtaguid/qtaguid.c
@@ -27,12 +27,10 @@
27#include <unistd.h> 27#include <unistd.h>
28 28
29#include <log/log.h> 29#include <log/log.h>
30#include <cutils/qtaguid.h> 30#include <qtaguid/qtaguid.h>
31 31
32static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl"; 32static const char* CTRL_PROCPATH = "/proc/net/xt_qtaguid/ctrl";
33static const int CTRL_MAX_INPUT_LEN = 128; 33static const int CTRL_MAX_INPUT_LEN = 128;
34static const char *GLOBAL_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/passive";
35static const char *TAG_PACIFIER_PARAM = "/sys/module/xt_qtaguid/parameters/tag_tracking_passive";
36 34
37/* 35/*
38 * One per proccess. 36 * One per proccess.
@@ -46,7 +44,7 @@ static int resTrackFd = -1;
46pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT; 44pthread_once_t resTrackInitDone = PTHREAD_ONCE_INIT;
47 45
48/* Only call once per process. */ 46/* Only call once per process. */
49void qtaguid_resTrack(void) { 47void legacy_resTrack(void) {
50 resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC)); 48 resTrackFd = TEMP_FAILURE_RETRY(open("/dev/xt_qtaguid", O_RDONLY | O_CLOEXEC));
51} 49}
52 50
@@ -55,7 +53,7 @@ void qtaguid_resTrack(void) {
55 * 0 on success. 53 * 0 on success.
56 * -errno on failure. 54 * -errno on failure.
57 */ 55 */
58static int write_ctrl(const char *cmd) { 56static int write_ctrl(const char* cmd) {
59 int fd, res, savedErrno; 57 int fd, res, savedErrno;
60 58
61 ALOGV("write_ctrl(%s)", cmd); 59 ALOGV("write_ctrl(%s)", cmd);
@@ -79,28 +77,12 @@ static int write_ctrl(const char *cmd) {
79 return -savedErrno; 77 return -savedErrno;
80} 78}
81 79
82static int write_param(const char *param_path, const char *value) { 80int legacy_tagSocket(int sockfd, int tag, uid_t uid) {
83 int param_fd;
84 int res;
85
86 param_fd = TEMP_FAILURE_RETRY(open(param_path, O_WRONLY | O_CLOEXEC));
87 if (param_fd < 0) {
88 return -errno;
89 }
90 res = TEMP_FAILURE_RETRY(write(param_fd, value, strlen(value)));
91 if (res < 0) {
92 return -errno;
93 }
94 close(param_fd);
95 return 0;
96}
97
98int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
99 char lineBuf[CTRL_MAX_INPUT_LEN]; 81 char lineBuf[CTRL_MAX_INPUT_LEN];
100 int res; 82 int res;
101 uint64_t kTag = ((uint64_t)tag << 32); 83 uint64_t kTag = ((uint64_t)tag << 32);
102 84
103 pthread_once(&resTrackInitDone, qtaguid_resTrack); 85 pthread_once(&resTrackInitDone, legacy_resTrack);
104 86
105 snprintf(lineBuf, sizeof(lineBuf), "t %d %" PRIu64 " %d", sockfd, kTag, uid); 87 snprintf(lineBuf, sizeof(lineBuf), "t %d %" PRIu64 " %d", sockfd, kTag, uid);
106 88
@@ -108,14 +90,14 @@ int qtaguid_tagSocket(int sockfd, int tag, uid_t uid) {
108 90
109 res = write_ctrl(lineBuf); 91 res = write_ctrl(lineBuf);
110 if (res < 0) { 92 if (res < 0) {
111 ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d", 93 ALOGI("Tagging socket %d with tag %" PRIx64 "(%d) for uid %d failed errno=%d", sockfd, kTag,
112 sockfd, kTag, tag, uid, res); 94 tag, uid, res);
113 } 95 }
114 96
115 return res; 97 return res;
116} 98}
117 99
118int qtaguid_untagSocket(int sockfd) { 100int legacy_untagSocket(int sockfd) {
119 char lineBuf[CTRL_MAX_INPUT_LEN]; 101 char lineBuf[CTRL_MAX_INPUT_LEN];
120 int res; 102 int res;
121 103
@@ -130,7 +112,7 @@ int qtaguid_untagSocket(int sockfd) {
130 return res; 112 return res;
131} 113}
132 114
133int qtaguid_setCounterSet(int counterSetNum, uid_t uid) { 115int legacy_setCounterSet(int counterSetNum, uid_t uid) {
134 char lineBuf[CTRL_MAX_INPUT_LEN]; 116 char lineBuf[CTRL_MAX_INPUT_LEN];
135 int res; 117 int res;
136 118
@@ -141,34 +123,21 @@ int qtaguid_setCounterSet(int counterSetNum, uid_t uid) {
141 return res; 123 return res;
142} 124}
143 125
144int qtaguid_deleteTagData(int tag, uid_t uid) { 126int legacy_deleteTagData(int tag, uid_t uid) {
145 char lineBuf[CTRL_MAX_INPUT_LEN]; 127 char lineBuf[CTRL_MAX_INPUT_LEN];
146 int cnt = 0, res = 0; 128 int cnt = 0, res = 0;
147 uint64_t kTag = (uint64_t)tag << 32; 129 uint64_t kTag = (uint64_t)tag << 32;
148 130
149 ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid); 131 ALOGV("Deleting tag data with tag %" PRIx64 "{%d,0} for uid %d", kTag, tag, uid);
150 132
151 pthread_once(&resTrackInitDone, qtaguid_resTrack); 133 pthread_once(&resTrackInitDone, legacy_resTrack);
152 134
153 snprintf(lineBuf, sizeof(lineBuf), "d %" PRIu64 " %d", kTag, uid); 135 snprintf(lineBuf, sizeof(lineBuf), "d %" PRIu64 " %d", kTag, uid);
154 res = write_ctrl(lineBuf); 136 res = write_ctrl(lineBuf);
155 if (res < 0) { 137 if (res < 0) {
156 ALOGI("Deleting tag data with tag %" PRIx64 "/%d for uid %d failed with cnt=%d errno=%d", 138 ALOGI("Deleting tag data with tag %" PRIx64 "/%d for uid %d failed with cnt=%d errno=%d",
157 kTag, tag, uid, cnt, errno); 139 kTag, tag, uid, cnt, errno);
158 } 140 }
159 141
160 return res; 142 return res;
161} 143}
162
163int qtaguid_setPacifier(int on) {
164 const char *value;
165
166 value = on ? "Y" : "N";
167 if (write_param(GLOBAL_PACIFIER_PARAM, value) < 0) {
168 return -errno;
169 }
170 if (write_param(TAG_PACIFIER_PARAM, value) < 0) {
171 return -errno;
172 }
173 return 0;
174}
diff --git a/libsysutils/src/NetlinkEvent.cpp b/libsysutils/src/NetlinkEvent.cpp
index 00b1ee228..7f92904f2 100644
--- a/libsysutils/src/NetlinkEvent.cpp
+++ b/libsysutils/src/NetlinkEvent.cpp
@@ -501,6 +501,8 @@ bool NetlinkEvent::parseNdUserOptMessage(const struct nlmsghdr *nh) {
501 asprintf(&mParams[0], "INTERFACE=%s", ifname); 501 asprintf(&mParams[0], "INTERFACE=%s", ifname);
502 asprintf(&mParams[1], "LIFETIME=%u", lifetime); 502 asprintf(&mParams[1], "LIFETIME=%u", lifetime);
503 mParams[2] = buf; 503 mParams[2] = buf;
504 } else if (opthdr->nd_opt_type == ND_OPT_DNSSL) {
505 // TODO: support DNSSL.
504 } else { 506 } else {
505 SLOGD("Unknown ND option type %d\n", opthdr->nd_opt_type); 507 SLOGD("Unknown ND option type %d\n", opthdr->nd_opt_type);
506 return false; 508 return false;
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index 40364fe40..75aa427f5 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -130,6 +130,7 @@ cc_test {
130 "tests/RegsStepIfSignalHandlerTest.cpp", 130 "tests/RegsStepIfSignalHandlerTest.cpp",
131 "tests/RegsTest.cpp", 131 "tests/RegsTest.cpp",
132 "tests/SymbolsTest.cpp", 132 "tests/SymbolsTest.cpp",
133 "tests/UnwindOfflineTest.cpp",
133 "tests/UnwindTest.cpp", 134 "tests/UnwindTest.cpp",
134 "tests/UnwinderTest.cpp", 135 "tests/UnwinderTest.cpp",
135 ], 136 ],
@@ -153,6 +154,8 @@ cc_test {
153 data: [ 154 data: [
154 "tests/files/elf32.xz", 155 "tests/files/elf32.xz",
155 "tests/files/elf64.xz", 156 "tests/files/elf64.xz",
157 "tests/files/offline/straddle_arm32/*",
158 "tests/files/offline/straddle_arm64/*",
156 ], 159 ],
157} 160}
158 161
diff --git a/libunwindstack/DwarfEhFrame.h b/libunwindstack/DwarfEhFrame.h
index 561d23a88..2589c89f2 100644
--- a/libunwindstack/DwarfEhFrame.h
+++ b/libunwindstack/DwarfEhFrame.h
@@ -40,7 +40,7 @@ class DwarfEhFrame : public DwarfSectionImpl<AddressType> {
40 40
41 uint64_t AdjustPcFromFde(uint64_t pc) override { 41 uint64_t AdjustPcFromFde(uint64_t pc) override {
42 // The eh_frame uses relative pcs. 42 // The eh_frame uses relative pcs.
43 return pc + this->memory_.cur_offset(); 43 return pc + this->memory_.cur_offset() - 4;
44 } 44 }
45}; 45};
46 46
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index edf7ac2d7..48e33ee2b 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -18,6 +18,7 @@
18#include <string.h> 18#include <string.h>
19 19
20#include <memory> 20#include <memory>
21#include <mutex>
21#include <string> 22#include <string>
22 23
23#define LOG_TAG "unwind" 24#define LOG_TAG "unwind"
@@ -87,6 +88,7 @@ void Elf::InitGnuDebugdata() {
87} 88}
88 89
89bool Elf::GetSoname(std::string* name) { 90bool Elf::GetSoname(std::string* name) {
91 std::lock_guard<std::mutex> guard(lock_);
90 return valid_ && interface_->GetSoname(name); 92 return valid_ && interface_->GetSoname(name);
91} 93}
92 94
@@ -95,14 +97,15 @@ uint64_t Elf::GetRelPc(uint64_t pc, const MapInfo* map_info) {
95} 97}
96 98
97bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) { 99bool Elf::GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
100 std::lock_guard<std::mutex> guard(lock_);
98 return valid_ && (interface_->GetFunctionName(addr, load_bias_, name, func_offset) || 101 return valid_ && (interface_->GetFunctionName(addr, load_bias_, name, func_offset) ||
99 (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName( 102 (gnu_debugdata_interface_ && gnu_debugdata_interface_->GetFunctionName(
100 addr, load_bias_, name, func_offset))); 103 addr, load_bias_, name, func_offset)));
101} 104}
102 105
103// The relative pc is always relative to the start of the map from which it comes. 106// The relative pc is always relative to the start of the map from which it comes.
104bool Elf::Step(uint64_t rel_pc, uint64_t elf_offset, Regs* regs, Memory* process_memory, 107bool Elf::Step(uint64_t rel_pc, uint64_t adjusted_rel_pc, uint64_t elf_offset, Regs* regs,
105 bool* finished) { 108 Memory* process_memory, bool* finished) {
106 if (!valid_) { 109 if (!valid_) {
107 return false; 110 return false;
108 } 111 }
@@ -114,14 +117,16 @@ bool Elf::Step(uint64_t rel_pc, uint64_t elf_offset, Regs* regs, Memory* process
114 } 117 }
115 118
116 // Adjust the load bias to get the real relative pc. 119 // Adjust the load bias to get the real relative pc.
117 if (rel_pc < load_bias_) { 120 if (adjusted_rel_pc < load_bias_) {
118 return false; 121 return false;
119 } 122 }
120 rel_pc -= load_bias_; 123 adjusted_rel_pc -= load_bias_;
121 124
122 return interface_->Step(rel_pc, regs, process_memory, finished) || 125 // Lock during the step which can update information in the object.
126 std::lock_guard<std::mutex> guard(lock_);
127 return interface_->Step(adjusted_rel_pc, regs, process_memory, finished) ||
123 (gnu_debugdata_interface_ && 128 (gnu_debugdata_interface_ &&
124 gnu_debugdata_interface_->Step(rel_pc, regs, process_memory, finished)); 129 gnu_debugdata_interface_->Step(adjusted_rel_pc, regs, process_memory, finished));
125} 130}
126 131
127bool Elf::IsValidElf(Memory* memory) { 132bool Elf::IsValidElf(Memory* memory) {
diff --git a/libunwindstack/MapInfo.cpp b/libunwindstack/MapInfo.cpp
index 140d05a92..541765992 100644
--- a/libunwindstack/MapInfo.cpp
+++ b/libunwindstack/MapInfo.cpp
@@ -19,6 +19,7 @@
19#include <unistd.h> 19#include <unistd.h>
20 20
21#include <memory> 21#include <memory>
22#include <mutex>
22#include <string> 23#include <string>
23 24
24#include <unwindstack/Elf.h> 25#include <unwindstack/Elf.h>
@@ -105,6 +106,9 @@ Memory* MapInfo::CreateMemory(const std::shared_ptr<Memory>& process_memory) {
105} 106}
106 107
107Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) { 108Elf* MapInfo::GetElf(const std::shared_ptr<Memory>& process_memory, bool init_gnu_debugdata) {
109 // Make sure no other thread is trying to add the elf to this map.
110 std::lock_guard<std::mutex> guard(mutex_);
111
108 if (elf) { 112 if (elf) {
109 return elf; 113 return elf;
110 } 114 }
diff --git a/libunwindstack/Maps.cpp b/libunwindstack/Maps.cpp
index 5e1c0a2fd..56370c196 100644
--- a/libunwindstack/Maps.cpp
+++ b/libunwindstack/Maps.cpp
@@ -44,7 +44,7 @@ MapInfo* Maps::Find(uint64_t pc) {
44 size_t last = maps_.size(); 44 size_t last = maps_.size();
45 while (first < last) { 45 while (first < last) {
46 size_t index = (first + last) / 2; 46 size_t index = (first + last) / 2;
47 MapInfo* cur = &maps_[index]; 47 MapInfo* cur = maps_[index];
48 if (pc >= cur->start && pc < cur->end) { 48 if (pc >= cur->start && pc < cur->end) {
49 return cur; 49 return cur;
50 } else if (pc < cur->start) { 50 } else if (pc < cur->start) {
@@ -57,22 +57,22 @@ MapInfo* Maps::Find(uint64_t pc) {
57} 57}
58 58
59// Assumes that line does not end in '\n'. 59// Assumes that line does not end in '\n'.
60static bool InternalParseLine(const char* line, MapInfo* map_info) { 60static MapInfo* InternalParseLine(const char* line) {
61 // Do not use a sscanf implementation since it is not performant. 61 // Do not use a sscanf implementation since it is not performant.
62 62
63 // Example linux /proc/<pid>/maps lines: 63 // Example linux /proc/<pid>/maps lines:
64 // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so 64 // 6f000000-6f01e000 rwxp 00000000 00:0c 16389419 /system/lib/libcomposer.so
65 char* str; 65 char* str;
66 const char* old_str = line; 66 const char* old_str = line;
67 map_info->start = strtoul(old_str, &str, 16); 67 uint64_t start = strtoull(old_str, &str, 16);
68 if (old_str == str || *str++ != '-') { 68 if (old_str == str || *str++ != '-') {
69 return false; 69 return nullptr;
70 } 70 }
71 71
72 old_str = str; 72 old_str = str;
73 map_info->end = strtoul(old_str, &str, 16); 73 uint64_t end = strtoull(old_str, &str, 16);
74 if (old_str == str || !std::isspace(*str++)) { 74 if (old_str == str || !std::isspace(*str++)) {
75 return false; 75 return nullptr;
76 } 76 }
77 77
78 while (std::isspace(*str)) { 78 while (std::isspace(*str)) {
@@ -81,82 +81,81 @@ static bool InternalParseLine(const char* line, MapInfo* map_info) {
81 81
82 // Parse permissions data. 82 // Parse permissions data.
83 if (*str == '\0') { 83 if (*str == '\0') {
84 return false; 84 return nullptr;
85 } 85 }
86 map_info->flags = 0; 86 uint16_t flags = 0;
87 if (*str == 'r') { 87 if (*str == 'r') {
88 map_info->flags |= PROT_READ; 88 flags |= PROT_READ;
89 } else if (*str != '-') { 89 } else if (*str != '-') {
90 return false; 90 return nullptr;
91 } 91 }
92 str++; 92 str++;
93 if (*str == 'w') { 93 if (*str == 'w') {
94 map_info->flags |= PROT_WRITE; 94 flags |= PROT_WRITE;
95 } else if (*str != '-') { 95 } else if (*str != '-') {
96 return false; 96 return nullptr;
97 } 97 }
98 str++; 98 str++;
99 if (*str == 'x') { 99 if (*str == 'x') {
100 map_info->flags |= PROT_EXEC; 100 flags |= PROT_EXEC;
101 } else if (*str != '-') { 101 } else if (*str != '-') {
102 return false; 102 return nullptr;
103 } 103 }
104 str++; 104 str++;
105 if (*str != 'p' && *str != 's') { 105 if (*str != 'p' && *str != 's') {
106 return false; 106 return nullptr;
107 } 107 }
108 str++; 108 str++;
109 109
110 if (!std::isspace(*str++)) { 110 if (!std::isspace(*str++)) {
111 return false; 111 return nullptr;
112 } 112 }
113 113
114 old_str = str; 114 old_str = str;
115 map_info->offset = strtoul(old_str, &str, 16); 115 uint64_t offset = strtoull(old_str, &str, 16);
116 if (old_str == str || !std::isspace(*str)) { 116 if (old_str == str || !std::isspace(*str)) {
117 return false; 117 return nullptr;
118 } 118 }
119 119
120 // Ignore the 00:00 values. 120 // Ignore the 00:00 values.
121 old_str = str; 121 old_str = str;
122 (void)strtoul(old_str, &str, 16); 122 (void)strtoull(old_str, &str, 16);
123 if (old_str == str || *str++ != ':') { 123 if (old_str == str || *str++ != ':') {
124 return false; 124 return nullptr;
125 } 125 }
126 if (std::isspace(*str)) { 126 if (std::isspace(*str)) {
127 return false; 127 return nullptr;
128 } 128 }
129 129
130 // Skip the inode. 130 // Skip the inode.
131 old_str = str; 131 old_str = str;
132 (void)strtoul(str, &str, 16); 132 (void)strtoull(str, &str, 16);
133 if (old_str == str || !std::isspace(*str++)) { 133 if (old_str == str || !std::isspace(*str++)) {
134 return false; 134 return nullptr;
135 } 135 }
136 136
137 // Skip decimal digit. 137 // Skip decimal digit.
138 old_str = str; 138 old_str = str;
139 (void)strtoul(old_str, &str, 10); 139 (void)strtoull(old_str, &str, 10);
140 if (old_str == str || (!std::isspace(*str) && *str != '\0')) { 140 if (old_str == str || (!std::isspace(*str) && *str != '\0')) {
141 return false; 141 return nullptr;
142 } 142 }
143 143
144 while (std::isspace(*str)) { 144 while (std::isspace(*str)) {
145 str++; 145 str++;
146 } 146 }
147 if (*str == '\0') { 147 if (*str == '\0') {
148 map_info->name = str; 148 return new MapInfo(start, end, offset, flags, "");
149 return true;
150 } 149 }
151 150
152 // Save the name data. 151 // Save the name data.
153 map_info->name = str; 152 std::string name(str);
154 153
155 // Mark a device map in /dev/ and not in /dev/ashmem/ specially. 154 // Mark a device map in /dev/ and not in /dev/ashmem/ specially.
156 if (map_info->name.substr(0, 5) == "/dev/" && map_info->name.substr(5, 7) != "ashmem/") { 155 if (name.substr(0, 5) == "/dev/" && name.substr(5, 7) != "ashmem/") {
157 map_info->flags |= MAPS_FLAGS_DEVICE_MAP; 156 flags |= MAPS_FLAGS_DEVICE_MAP;
158 } 157 }
159 return true; 158 return new MapInfo(start, end, offset, flags, name);
160} 159}
161 160
162bool Maps::Parse() { 161bool Maps::Parse() {
@@ -187,8 +186,8 @@ bool Maps::Parse() {
187 } 186 }
188 *newline = '\0'; 187 *newline = '\0';
189 188
190 MapInfo map_info; 189 MapInfo* map_info = InternalParseLine(line);
191 if (!InternalParseLine(line, &map_info)) { 190 if (map_info == nullptr) {
192 return_value = false; 191 return_value = false;
193 break; 192 break;
194 } 193 }
@@ -205,8 +204,7 @@ bool Maps::Parse() {
205 204
206Maps::~Maps() { 205Maps::~Maps() {
207 for (auto& map : maps_) { 206 for (auto& map : maps_) {
208 delete map.elf; 207 delete map;
209 map.elf = nullptr;
210 } 208 }
211} 209}
212 210
@@ -222,8 +220,8 @@ bool BufferMaps::Parse() {
222 end_of_line++; 220 end_of_line++;
223