Merge "fs_mgr: report errno string for __mount errors"
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index f993820..f86aaa0 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -275,7 +275,6 @@
"libdebuggerd_client",
"liblog",
"libprocinfo",
- "libselinux",
],
local_include_dirs: ["include"],
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 0cc5f69..b016e23 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -28,7 +28,6 @@
#include <android-base/unique_fd.h>
#include <debuggerd/client.h>
#include <procinfo/process.h>
-#include <selinux/selinux.h>
#include "util.h"
using android::base::unique_fd;
diff --git a/healthd/BatteryPropertiesRegistrar.cpp b/healthd/BatteryPropertiesRegistrar.cpp
index 523e1f1..e51a06d 100644
--- a/healthd/BatteryPropertiesRegistrar.cpp
+++ b/healthd/BatteryPropertiesRegistrar.cpp
@@ -36,9 +36,19 @@
}
void BatteryPropertiesRegistrar::notifyListeners(const struct BatteryProperties& props) {
- Mutex::Autolock _l(mRegistrationLock);
- for (size_t i = 0; i < mListeners.size(); i++) {
- mListeners[i]->batteryPropertiesChanged(props);
+ Vector<sp<IBatteryPropertiesListener> > listenersCopy;
+
+ // Binder currently may service an incoming oneway transaction whenever an
+ // outbound oneway call is made (if there is already a pending incoming
+ // oneway call waiting). This is considered a bug and may change in the
+ // future. For now, avoid recursive mutex lock while making outbound
+ // calls by making a local copy of the current list of listeners.
+ {
+ Mutex::Autolock _l(mRegistrationLock);
+ listenersCopy = mListeners;
+ }
+ for (size_t i = 0; i < listenersCopy.size(); i++) {
+ listenersCopy[i]->batteryPropertiesChanged(props);
}
}
diff --git a/include/ziparchive b/include/ziparchive
new file mode 120000
index 0000000..d8fa424
--- /dev/null
+++ b/include/ziparchive
@@ -0,0 +1 @@
+../libziparchive/include/ziparchive
\ No newline at end of file
diff --git a/init/capabilities.cpp b/init/capabilities.cpp
index 53832a4..642a364 100644
--- a/init/capabilities.cpp
+++ b/init/capabilities.cpp
@@ -107,17 +107,15 @@
}
static bool SetProcCaps(const CapSet& to_keep, bool add_setpcap) {
- cap_t caps = cap_init();
- auto deleter = [](cap_t* p) { cap_free(*p); };
- std::unique_ptr<cap_t, decltype(deleter)> ptr_caps(&caps, deleter);
+ ScopedCaps caps(cap_init());
- cap_clear(caps);
+ cap_clear(caps.get());
cap_value_t value[1];
for (size_t cap = 0; cap < to_keep.size(); ++cap) {
if (to_keep.test(cap)) {
value[0] = cap;
- if (cap_set_flag(caps, CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
- cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
+ if (cap_set_flag(caps.get(), CAP_INHERITABLE, arraysize(value), value, CAP_SET) != 0 ||
+ cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0) {
PLOG(ERROR) << "cap_set_flag(INHERITABLE|PERMITTED, " << cap << ") failed";
return false;
}
@@ -126,14 +124,14 @@
if (add_setpcap) {
value[0] = CAP_SETPCAP;
- if (cap_set_flag(caps, CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
- cap_set_flag(caps, CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
+ if (cap_set_flag(caps.get(), CAP_PERMITTED, arraysize(value), value, CAP_SET) != 0 ||
+ cap_set_flag(caps.get(), CAP_EFFECTIVE, arraysize(value), value, CAP_SET) != 0) {
PLOG(ERROR) << "cap_set_flag(PERMITTED|EFFECTIVE, " << CAP_SETPCAP << ") failed";
return false;
}
}
- if (cap_set_proc(caps) != 0) {
+ if (cap_set_proc(caps.get()) != 0) {
PLOG(ERROR) << "cap_set_proc(" << to_keep.to_ulong() << ") failed";
return false;
}
diff --git a/init/capabilities.h b/init/capabilities.h
index ef507a6..ede85c3 100644
--- a/init/capabilities.h
+++ b/init/capabilities.h
@@ -15,15 +15,21 @@
#ifndef _INIT_CAPABILITIES_H
#define _INIT_CAPABILITIES_H
-#include <linux/capability.h>
+#include <sys/capability.h>
#include <bitset>
#include <string>
+#include <type_traits>
namespace android {
namespace init {
+struct CapDeleter {
+ void operator()(cap_t caps) const { cap_free(caps); }
+};
+
using CapSet = std::bitset<CAP_LAST_CAP + 1>;
+using ScopedCaps = std::unique_ptr<std::remove_pointer<cap_t>::type, CapDeleter>;
int LookupCap(const std::string& cap_name);
bool CapAmbientSupported();
diff --git a/init/reboot.cpp b/init/reboot.cpp
index df7912f..34c98a7 100644
--- a/init/reboot.cpp
+++ b/init/reboot.cpp
@@ -20,7 +20,7 @@
#include <fcntl.h>
#include <linux/fs.h>
#include <mntent.h>
-#include <selinux/selinux.h>
+#include <sys/capability.h>
#include <sys/cdefs.h>
#include <sys/ioctl.h>
#include <sys/mount.h>
@@ -48,6 +48,7 @@
#include <logwrap/logwrap.h>
#include <private/android_filesystem_config.h>
+#include "capabilities.h"
#include "property_service.h"
#include "service.h"
@@ -162,9 +163,38 @@
LOG(WARNING) << "powerctl_shutdown_time_ms:" << std::to_string(t->duration_ms()) << ":" << stat;
}
+// Determines whether the system is capable of rebooting. This is conservative,
+// so if any of the attempts to determine this fail, it will still return true.
+static bool IsRebootCapable() {
+ if (!CAP_IS_SUPPORTED(CAP_SYS_BOOT)) {
+ PLOG(WARNING) << "CAP_SYS_BOOT is not supported";
+ return true;
+ }
+
+ ScopedCaps caps(cap_get_proc());
+ if (!caps) {
+ PLOG(WARNING) << "cap_get_proc() failed";
+ return true;
+ }
+
+ cap_flag_value_t value = CAP_SET;
+ if (cap_get_flag(caps.get(), CAP_SYS_BOOT, CAP_EFFECTIVE, &value) != 0) {
+ PLOG(WARNING) << "cap_get_flag(CAP_SYS_BOOT, EFFECTIVE) failed";
+ return true;
+ }
+ return value == CAP_SET;
+}
+
static void __attribute__((noreturn))
RebootSystem(unsigned int cmd, const std::string& rebootTarget) {
LOG(INFO) << "Reboot ending, jumping to kernel";
+
+ if (!IsRebootCapable()) {
+ // On systems where init does not have the capability of rebooting the
+ // device, just exit cleanly.
+ exit(0);
+ }
+
switch (cmd) {
case ANDROID_RB_POWEROFF:
reboot(RB_POWER_OFF);
diff --git a/init/service.cpp b/init/service.cpp
index f9a452b..f2e5d22 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -235,8 +235,15 @@
void Service::SetProcessAttributes() {
// Keep capabilites on uid change.
if (capabilities_.any() && uid_) {
- if (prctl(PR_SET_SECUREBITS, SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED) != 0) {
- PLOG(FATAL) << "prtcl(PR_SET_KEEPCAPS) failed for " << name_;
+ // If Android is running in a container, some securebits might already
+ // be locked, so don't change those.
+ int64_t securebits = prctl(PR_GET_SECUREBITS);
+ if (securebits == -1) {
+ PLOG(FATAL) << "prctl(PR_GET_SECUREBITS) failed for " << name_;
+ }
+ securebits |= SECBIT_KEEP_CAPS | SECBIT_KEEP_CAPS_LOCKED;
+ if (prctl(PR_SET_SECUREBITS, securebits) != 0) {
+ PLOG(FATAL) << "prctl(PR_SET_SECUREBITS) failed for " << name_;
}
}
diff --git a/libcutils/sched_policy.cpp b/libcutils/sched_policy.cpp
index aeb881a..f733e90 100644
--- a/libcutils/sched_policy.cpp
+++ b/libcutils/sched_policy.cpp
@@ -28,13 +28,6 @@
#define UNUSED __attribute__((__unused__))
-#ifndef SLOGE
-#define SLOGE ALOGE
-#endif
-#ifndef SLOGW
-#define SLOGW ALOGW
-#endif
-
/* Re-map SP_DEFAULT to the system default policy, and leave other values unchanged.
* Call this any place a SchedPolicy is used as an input parameter.
* Returns the possibly re-mapped policy.
@@ -125,7 +118,6 @@
In older releases, this was controlled by build-time configuration.
*/
-
bool cpusets_enabled() {
static bool enabled = (access("/dev/cpuset/tasks", F_OK) == 0);
@@ -137,12 +129,8 @@
CONFIG_CGROUP_SCHEDTUNE that's in Android common Linux kernel and Linaro
Stable Kernel (LSK), but not in mainline Linux as of v4.9.
- With runtime check using the following function, build time
- variables like ENABLE_SCHEDBOOST (used in Android.mk) or schedboost
- (used in Android.bp) are not needed.
-
+ In older releases, this was controlled by build-time configuration.
*/
-
bool schedboost_enabled() {
static bool enabled = (access("/dev/stune/tasks", F_OK) == 0);
diff --git a/liblog/include_vndk/log/log.h b/liblog/include_vndk/log/log.h
index 01623df..a79beec 100644
--- a/liblog/include_vndk/log/log.h
+++ b/liblog/include_vndk/log/log.h
@@ -9,6 +9,7 @@
#include <log/log_radio.h>
#include <log/log_read.h>
#include <log/log_safetynet.h>
+#include <log/log_system.h>
#include <log/log_time.h>
/*
diff --git a/liblog/include_vndk/log/log_system.h b/liblog/include_vndk/log/log_system.h
new file mode 120000
index 0000000..d0d3904
--- /dev/null
+++ b/liblog/include_vndk/log/log_system.h
@@ -0,0 +1 @@
+../../include/log/log_system.h
\ No newline at end of file
diff --git a/libmemunreachable/ScopedSignalHandler.h b/libmemunreachable/ScopedSignalHandler.h
index f62f368..ff53fad 100644
--- a/libmemunreachable/ScopedSignalHandler.h
+++ b/libmemunreachable/ScopedSignalHandler.h
@@ -37,7 +37,7 @@
template <class F>
void install(int signal, F&& f) {
- if (signal != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed");
+ if (signal_ != -1) MEM_LOG_ALWAYS_FATAL("ScopedSignalHandler already installed");
handler_ = SignalFn(std::allocator_arg, allocator_,
[=](int signal, siginfo_t* si, void* uctx) { f(*this, signal, si, uctx); });
diff --git a/libprocessgroup/processgroup.cpp b/libprocessgroup/processgroup.cpp
index f5d4e1c..9b8248e 100644
--- a/libprocessgroup/processgroup.cpp
+++ b/libprocessgroup/processgroup.cpp
@@ -43,9 +43,6 @@
using namespace std::chrono_literals;
-// Uncomment line below use memory cgroups for keeping track of (forked) PIDs
-// #define USE_MEMCG 1
-
#define MEM_CGROUP_PATH "/dev/memcg/apps"
#define MEM_CGROUP_TASKS "/dev/memcg/apps/tasks"
#define ACCT_CGROUP_PATH "/acct"
@@ -91,7 +88,6 @@
};
static const char* getCgroupRootPath() {
-#ifdef USE_MEMCG
static const char* cgroup_root_path = NULL;
std::call_once(init_path_flag, [&]() {
// Check if mem cgroup is mounted, only then check for write-access to avoid
@@ -100,9 +96,6 @@
ACCT_CGROUP_PATH : MEM_CGROUP_PATH;
});
return cgroup_root_path;
-#else
- return ACCT_CGROUP_PATH;
-#endif
}
static int convertUidToPath(char *path, size_t size, uid_t uid)
diff --git a/libunwindstack/Android.bp b/libunwindstack/Android.bp
index d7e949b..8776db7 100644
--- a/libunwindstack/Android.bp
+++ b/libunwindstack/Android.bp
@@ -57,16 +57,17 @@
"ElfInterface.cpp",
"ElfInterfaceArm.cpp",
"Log.cpp",
- "Regs.cpp",
"MapInfo.cpp",
"Maps.cpp",
"Memory.cpp",
+ "Regs.cpp",
"Symbols.cpp",
],
shared_libs: [
"libbase",
"liblog",
+ "liblzma",
],
}
@@ -75,17 +76,6 @@
defaults: ["libunwindstack_common"],
}
-cc_library {
- name: "libunwindstack_debug",
- defaults: ["libunwindstack_common"],
-
- cflags: [
- "-UNDEBUG",
- "-O0",
- "-g",
- ],
-}
-
//-------------------------------------------------------------------------
// Unit Tests
//-------------------------------------------------------------------------
@@ -128,6 +118,7 @@
shared_libs: [
"libbase",
"liblog",
+ "liblzma",
],
static_libs: [
@@ -151,15 +142,10 @@
shared_libs: [
"libunwindstack",
],
-}
-// These unit tests run against the static debug library.
-cc_test {
- name: "libunwindstack_test_debug",
- defaults: ["libunwindstack_test_common"],
-
- static_libs: [
- "libunwindstack_debug",
+ data: [
+ "tests/elf32.xz",
+ "tests/elf64.xz",
],
}
@@ -173,6 +159,7 @@
shared_libs: [
"libunwindstack",
"libbase",
+ "liblzma",
],
static_libs: [
@@ -190,3 +177,25 @@
"unwind_info.cpp",
],
}
+
+// Generates the elf data for use in the tests for .gnu_debugdata frames.
+// Once these files are generated, use the xz command to compress the data.
+cc_binary_host {
+ name: "gen_gnudebugdata",
+
+ cflags: [
+ "-Wall",
+ "-Werror",
+ "-Wextra",
+ ],
+
+ srcs: [
+ "tests/GenGnuDebugdata.cpp",
+ ],
+
+ target: {
+ darwin: {
+ enabled: false,
+ },
+ },
+}
diff --git a/libunwindstack/ArmExidx.cpp b/libunwindstack/ArmExidx.cpp
index 12adf57..5c7caca 100644
--- a/libunwindstack/ArmExidx.cpp
+++ b/libunwindstack/ArmExidx.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <assert.h>
#include <stdint.h>
#include <deque>
@@ -23,6 +22,7 @@
#include <android-base/stringprintf.h>
#include "ArmExidx.h"
+#include "Check.h"
#include "Log.h"
#include "Machine.h"
#include "Memory.h"
@@ -173,7 +173,7 @@
}
inline bool ArmExidx::DecodePrefix_10_00(uint8_t byte) {
- assert((byte >> 4) == 0x8);
+ CHECK((byte >> 4) == 0x8);
uint16_t registers = (byte & 0xf) << 8;
if (!GetByte(&byte)) {
@@ -232,7 +232,7 @@
}
inline bool ArmExidx::DecodePrefix_10_01(uint8_t byte) {
- assert((byte >> 4) == 0x9);
+ CHECK((byte >> 4) == 0x9);
uint8_t bits = byte & 0xf;
if (bits == 13 || bits == 15) {
@@ -258,7 +258,7 @@
}
inline bool ArmExidx::DecodePrefix_10_10(uint8_t byte) {
- assert((byte >> 4) == 0xa);
+ CHECK((byte >> 4) == 0xa);
// 10100nnn: Pop r4-r[4+nnn]
// 10101nnn: Pop r4-r[4+nnn], r14
@@ -419,7 +419,7 @@
}
inline bool ArmExidx::DecodePrefix_10_11_1nnn(uint8_t byte) {
- assert((byte & ~0x07) == 0xb8);
+ CHECK((byte & ~0x07) == 0xb8);
// 10111nnn: Pop VFP double-precision registers D[8]-D[8+nnn] by FSTMFDX
if (log_) {
@@ -439,7 +439,7 @@
}
inline bool ArmExidx::DecodePrefix_10(uint8_t byte) {
- assert((byte >> 6) == 0x2);
+ CHECK((byte >> 6) == 0x2);
switch ((byte >> 4) & 0x3) {
case 0:
@@ -469,7 +469,7 @@
}
inline bool ArmExidx::DecodePrefix_11_000(uint8_t byte) {
- assert((byte & ~0x07) == 0xc0);
+ CHECK((byte & ~0x07) == 0xc0);
uint8_t bits = byte & 0x7;
if (bits == 6) {
@@ -550,7 +550,7 @@
}
inline bool ArmExidx::DecodePrefix_11_001(uint8_t byte) {
- assert((byte & ~0x07) == 0xc8);
+ CHECK((byte & ~0x07) == 0xc8);
uint8_t bits = byte & 0x7;
if (bits == 0) {
@@ -605,7 +605,7 @@
}
inline bool ArmExidx::DecodePrefix_11_010(uint8_t byte) {
- assert((byte & ~0x07) == 0xd0);
+ CHECK((byte & ~0x07) == 0xd0);
// 11010nnn: Pop VFP double precision registers D[8]-D[8+nnn] by VPUSH
if (log_) {
@@ -624,7 +624,7 @@
}
inline bool ArmExidx::DecodePrefix_11(uint8_t byte) {
- assert((byte >> 6) == 0x3);
+ CHECK((byte >> 6) == 0x3);
switch ((byte >> 3) & 0x7) {
case 0:
diff --git a/libunwindstack/Check.h b/libunwindstack/Check.h
new file mode 100644
index 0000000..e0c48c7
--- /dev/null
+++ b/libunwindstack/Check.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _LIBUNWINDSTACK_ERROR_H
+#define _LIBUNWINDSTACK_ERROR_H
+
+#include <stdlib.h>
+
+#include "Log.h"
+
+#define CHECK(assertion) \
+ if (__builtin_expect(!(assertion), false)) { \
+ log(0, "%s:%d: %s\n", __FILE__, __LINE__, #assertion); \
+ abort(); \
+ }
+
+#endif // _LIBUNWINDSTACK_ERROR_H
diff --git a/libunwindstack/DwarfEhFrame.cpp b/libunwindstack/DwarfEhFrame.cpp
index 045fb36..937b6bd 100644
--- a/libunwindstack/DwarfEhFrame.cpp
+++ b/libunwindstack/DwarfEhFrame.cpp
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#include <assert.h>
#include <stdint.h>
+#include "Check.h"
#include "DwarfEhFrame.h"
#include "DwarfMemory.h"
#include "DwarfSection.h"
@@ -105,8 +105,8 @@
template <typename AddressType>
bool DwarfEhFrame<AddressType>::GetFdeOffsetBinary(uint64_t pc, uint64_t* fde_offset,
uint64_t total_entries) {
- assert(fde_count_ > 0);
- assert(total_entries <= fde_count_);
+ CHECK(fde_count_ > 0);
+ CHECK(total_entries <= fde_count_);
size_t first = 0;
size_t last = total_entries;
@@ -133,7 +133,7 @@
template <typename AddressType>
bool DwarfEhFrame<AddressType>::GetFdeOffsetSequential(uint64_t pc, uint64_t* fde_offset) {
- assert(fde_count_ != 0);
+ CHECK(fde_count_ != 0);
last_error_ = DWARF_ERROR_NONE;
// We can do a binary search if the pc is in the range of the elements
// that have already been cached.
diff --git a/libunwindstack/DwarfMemory.cpp b/libunwindstack/DwarfMemory.cpp
index 11806ea..a984fc6 100644
--- a/libunwindstack/DwarfMemory.cpp
+++ b/libunwindstack/DwarfMemory.cpp
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include <assert.h>
#include <stdint.h>
#include <string>
+#include "Check.h"
#include "DwarfEncoding.h"
#include "DwarfMemory.h"
#include "Memory.h"
@@ -100,8 +100,8 @@
}
bool DwarfMemory::AdjustEncodedValue(uint8_t encoding, uint64_t* value) {
- assert((encoding & 0x0f) == 0);
- assert(encoding != DW_EH_PE_aligned);
+ CHECK((encoding & 0x0f) == 0);
+ CHECK(encoding != DW_EH_PE_aligned);
// Handle the encoding.
switch (encoding) {
diff --git a/libunwindstack/Elf.cpp b/libunwindstack/Elf.cpp
index 272b5f0..ad1447a 100644
--- a/libunwindstack/Elf.cpp
+++ b/libunwindstack/Elf.cpp
@@ -49,6 +49,28 @@
return valid_;
}
+// It is expensive to initialize the .gnu_debugdata section. Provide a method
+// to initialize this data separately.
+void Elf::InitGnuDebugdata() {
+ if (!valid_ || interface_->gnu_debugdata_offset() == 0) {
+ return;
+ }
+
+ gnu_debugdata_memory_.reset(interface_->CreateGnuDebugdataMemory());
+ gnu_debugdata_interface_.reset(CreateInterfaceFromMemory(gnu_debugdata_memory_.get()));
+ ElfInterface* gnu = gnu_debugdata_interface_.get();
+ if (gnu == nullptr) {
+ return;
+ }
+ if (gnu->Init()) {
+ gnu->InitHeaders();
+ } else {
+ // Free all of the memory associated with the gnu_debugdata section.
+ gnu_debugdata_memory_.reset(nullptr);
+ gnu_debugdata_interface_.reset(nullptr);
+ }
+}
+
bool Elf::IsValidElf(Memory* memory) {
if (memory == nullptr) {
return false;
diff --git a/libunwindstack/Elf.h b/libunwindstack/Elf.h
index f9db541..cff9dc4 100644
--- a/libunwindstack/Elf.h
+++ b/libunwindstack/Elf.h
@@ -46,11 +46,15 @@
}
bool GetFunctionName(uint64_t addr, std::string* name, uint64_t* func_offset) {
- return valid_ && interface_->GetFunctionName(addr, name, func_offset);
+ return valid_ && (interface_->GetFunctionName(addr, name, func_offset) ||
+ (gnu_debugdata_interface_ &&
+ gnu_debugdata_interface_->GetFunctionName(addr, name, func_offset)));
}
bool Step(uint64_t rel_pc, Regs* regs, Memory* process_memory) {
- return valid_ && interface_->Step(rel_pc, regs, process_memory);
+ return valid_ && (interface_->Step(rel_pc, regs, process_memory) ||
+ (gnu_debugdata_interface_ &&
+ gnu_debugdata_interface_->Step(rel_pc, regs, process_memory)));
}
ElfInterface* CreateInterfaceFromMemory(Memory* memory);
@@ -65,6 +69,8 @@
ElfInterface* interface() { return interface_.get(); }
+ ElfInterface* gnu_debugdata_interface() { return gnu_debugdata_interface_.get(); }
+
static bool IsValidElf(Memory* memory);
protected:
@@ -73,6 +79,9 @@
std::unique_ptr<Memory> memory_;
uint32_t machine_type_;
uint8_t class_type_;
+
+ std::unique_ptr<Memory> gnu_debugdata_memory_;
+ std::unique_ptr<ElfInterface> gnu_debugdata_interface_;
};
#endif // _LIBUNWINDSTACK_ELF_H
diff --git a/libunwindstack/ElfInterface.cpp b/libunwindstack/ElfInterface.cpp
index 3a7f7cb..7d38ee0 100644
--- a/libunwindstack/ElfInterface.cpp
+++ b/libunwindstack/ElfInterface.cpp
@@ -20,6 +20,10 @@
#include <memory>
#include <string>
+#include <7zCrc.h>
+#include <Xz.h>
+#include <XzCrc64.h>
+
#include "DwarfDebugFrame.h"
#include "DwarfEhFrame.h"
#include "DwarfSection.h"
@@ -35,6 +39,60 @@
}
}
+Memory* ElfInterface::CreateGnuDebugdataMemory() {
+ if (gnu_debugdata_offset_ == 0 || gnu_debugdata_size_ == 0) {
+ return nullptr;
+ }
+
+ // TODO: Only call these initialization functions once.
+ CrcGenerateTable();
+ Crc64GenerateTable();
+
+ std::vector<uint8_t> src(gnu_debugdata_size_);
+ if (!memory_->Read(gnu_debugdata_offset_, src.data(), gnu_debugdata_size_)) {
+ gnu_debugdata_offset_ = 0;
+ gnu_debugdata_size_ = static_cast<uint64_t>(-1);
+ return nullptr;
+ }
+
+ ISzAlloc alloc;
+ CXzUnpacker state;
+ alloc.Alloc = [](void*, size_t size) { return malloc(size); };
+ alloc.Free = [](void*, void* ptr) { return free(ptr); };
+
+ XzUnpacker_Construct(&state, &alloc);
+
+ std::unique_ptr<MemoryBuffer> dst(new MemoryBuffer);
+ int return_val;
+ size_t src_offset = 0;
+ size_t dst_offset = 0;
+ ECoderStatus status;
+ dst->Resize(5 * gnu_debugdata_size_);
+ do {
+ size_t src_remaining = src.size() - src_offset;
+ size_t dst_remaining = dst->Size() - dst_offset;
+ if (dst_remaining < 2 * gnu_debugdata_size_) {
+ dst->Resize(dst->Size() + 2 * gnu_debugdata_size_);
+ dst_remaining += 2 * gnu_debugdata_size_;
+ }
+ return_val = XzUnpacker_Code(&state, dst->GetPtr(dst_offset), &dst_remaining, &src[src_offset],
+ &src_remaining, CODER_FINISH_ANY, &status);
+ src_offset += src_remaining;
+ dst_offset += dst_remaining;
+ } while (return_val == SZ_OK && status == CODER_STATUS_NOT_FINISHED);
+ XzUnpacker_Free(&state);
+ if (return_val != SZ_OK || !XzUnpacker_IsStreamWasFinished(&state)) {
+ gnu_debugdata_offset_ = 0;
+ gnu_debugdata_size_ = static_cast<uint64_t>(-1);
+ return nullptr;
+ }
+
+ // Shrink back down to the exact size.
+ dst->Resize(dst_offset);
+
+ return dst.release();
+}
+
template <typename AddressType>
void ElfInterface::InitHeadersWithTemplate() {
if (eh_frame_offset_ != 0) {
diff --git a/libunwindstack/Memory.h b/libunwindstack/Memory.h
index f9f6d56..e353cab 100644
--- a/libunwindstack/Memory.h
+++ b/libunwindstack/Memory.h
@@ -17,7 +17,6 @@
#ifndef _LIBUNWINDSTACK_MEMORY_H
#define _LIBUNWINDSTACK_MEMORY_H
-#include <assert.h>
#include <stdint.h>
#include <sys/types.h>
#include <unistd.h>
@@ -25,6 +24,8 @@
#include <string>
#include <vector>
+#include "Check.h"
+
class Memory {
public:
Memory() = default;
@@ -130,7 +131,7 @@
public:
MemoryRange(Memory* memory, uint64_t begin, uint64_t end)
: memory_(memory), begin_(begin), length_(end - begin) {
- assert(end > begin);
+ CHECK(end > begin);
}
virtual ~MemoryRange() { delete memory_; }
diff --git a/libunwindstack/Regs.cpp b/libunwindstack/Regs.cpp
index e7d10b2..da22b07 100644
--- a/libunwindstack/Regs.cpp
+++ b/libunwindstack/Regs.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <assert.h>
#include <elf.h>
#include <stdint.h>
#include <sys/ptrace.h>
@@ -22,6 +21,7 @@
#include <vector>
+#include "Check.h"
#include "Elf.h"
#include "ElfInterface.h"
#include "Machine.h"
@@ -43,7 +43,7 @@
bool RegsImpl<AddressType>::GetReturnAddressFromDefault(Memory* memory, uint64_t* value) {
switch (return_loc_.type) {
case LOCATION_REGISTER:
- assert(return_loc_.value < total_regs_);
+ CHECK(return_loc_.value < total_regs_);
*value = regs_[return_loc_.value];
return true;
case LOCATION_SP_OFFSET:
diff --git a/libunwindstack/Symbols.cpp b/libunwindstack/Symbols.cpp
index 86c1233..edc2187 100644
--- a/libunwindstack/Symbols.cpp
+++ b/libunwindstack/Symbols.cpp
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include <assert.h>
#include <elf.h>
#include <stdint.h>
#include <string>
+#include "Check.h"
#include "Memory.h"
#include "Symbols.h"
@@ -58,7 +58,7 @@
if (symbols_.size() != 0) {
const Info* info = GetInfoFromCache(addr);
if (info) {
- assert(addr >= info->start_offset && addr <= info->end_offset);
+ CHECK(addr >= info->start_offset && addr <= info->end_offset);
*func_offset = addr - info->start_offset;
return elf_memory->ReadString(info->str_offset, name, str_end_ - info->str_offset);
}
diff --git a/libunwindstack/tests/ElfTest.cpp b/libunwindstack/tests/ElfTest.cpp
index 25fec8e..22cade2 100644
--- a/libunwindstack/tests/ElfTest.cpp
+++ b/libunwindstack/tests/ElfTest.cpp
@@ -15,6 +15,10 @@
*/
#include <elf.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
#include <gtest/gtest.h>
@@ -26,10 +30,6 @@
#define PT_ARM_EXIDX 0x70000001
#endif
-#if !defined(EM_AARCH64)
-#define EM_AARCH64 183
-#endif
-
class ElfTest : public ::testing::Test {
protected:
void SetUp() override {
@@ -43,17 +43,18 @@
ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
ehdr->e_ident[EI_VERSION] = EV_CURRENT;
ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
+
+ ehdr->e_type = ET_DYN;
+ ehdr->e_version = EV_CURRENT;
}
- void InitElf32(uint32_t type) {
+ void InitElf32(uint32_t machine) {
Elf32_Ehdr ehdr;
InitEhdr<Elf32_Ehdr>(&ehdr);
ehdr.e_ident[EI_CLASS] = ELFCLASS32;
- ehdr.e_type = ET_DYN;
- ehdr.e_machine = type;
- ehdr.e_version = EV_CURRENT;
+ ehdr.e_machine = machine;
ehdr.e_entry = 0;
ehdr.e_phoff = 0x100;
ehdr.e_shoff = 0;
@@ -64,7 +65,7 @@
ehdr.e_shentsize = sizeof(Elf32_Shdr);
ehdr.e_shnum = 0;
ehdr.e_shstrndx = 0;
- if (type == EM_ARM) {
+ if (machine == EM_ARM) {
ehdr.e_flags = 0x5000200;
ehdr.e_phnum = 2;
}
@@ -82,7 +83,7 @@
phdr.p_align = 0x1000;
memory_->SetMemory(0x100, &phdr, sizeof(phdr));
- if (type == EM_ARM) {
+ if (machine == EM_ARM) {
memset(&phdr, 0, sizeof(phdr));
phdr.p_type = PT_ARM_EXIDX;
phdr.p_offset = 0x30000;
@@ -96,15 +97,13 @@
}
}
- void InitElf64(uint32_t type) {
+ void InitElf64(uint32_t machine) {
Elf64_Ehdr ehdr;
InitEhdr<Elf64_Ehdr>(&ehdr);
ehdr.e_ident[EI_CLASS] = ELFCLASS64;
- ehdr.e_type = ET_DYN;
- ehdr.e_machine = type;
- ehdr.e_version = EV_CURRENT;
+ ehdr.e_machine = machine;
ehdr.e_entry = 0;
ehdr.e_phoff = 0x100;
ehdr.e_shoff = 0;
@@ -130,6 +129,12 @@
memory_->SetMemory(0x100, &phdr, sizeof(phdr));
}
+ template <typename Ehdr, typename Shdr>
+ void GnuDebugdataInitFail(Ehdr* ehdr);
+
+ template <typename Ehdr, typename Shdr>
+ void GnuDebugdataInit(Ehdr* ehdr);
+
MemoryFake* memory_;
};
@@ -208,3 +213,154 @@
ASSERT_EQ(ELFCLASS64, elf.class_type());
ASSERT_TRUE(elf.interface() != nullptr);
}
+
+template <typename Ehdr, typename Shdr>
+void ElfTest::GnuDebugdataInitFail(Ehdr* ehdr) {
+ Elf elf(memory_);
+
+ uint64_t offset = 0x2000;
+
+ ehdr->e_shoff = offset;
+ ehdr->e_shnum = 3;
+ ehdr->e_shentsize = sizeof(Shdr);
+ ehdr->e_shstrndx = 2;
+ memory_->SetMemory(0, ehdr, sizeof(*ehdr));
+
+ Shdr shdr;
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_NULL;
+ memory_->SetMemory(offset, &shdr, sizeof(shdr));
+ offset += ehdr->e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_name = 0x100;
+ shdr.sh_addr = 0x5000;
+ shdr.sh_offset = 0x5000;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x800;
+ memory_->SetMemory(offset, &shdr, sizeof(shdr));
+ offset += ehdr->e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 0x200000;
+ shdr.sh_offset = 0xf000;
+ shdr.sh_size = 0x1000;
+ memory_->SetMemory(offset, &shdr, sizeof(shdr));
+ offset += ehdr->e_shentsize;
+
+ memory_->SetMemory(0xf100, ".gnu_debugdata", sizeof(".gnu_debugdata"));
+
+ ASSERT_TRUE(elf.Init());
+ ASSERT_TRUE(elf.interface() != nullptr);
+ ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
+ EXPECT_EQ(0x5000U, elf.interface()->gnu_debugdata_offset());
+ EXPECT_EQ(0x800U, elf.interface()->gnu_debugdata_size());
+
+ elf.InitGnuDebugdata();
+}
+
+TEST_F(ElfTest, gnu_debugdata_init_fail32) {
+ Elf32_Ehdr ehdr;
+ InitEhdr<Elf32_Ehdr>(&ehdr);
+ ehdr.e_ident[EI_CLASS] = ELFCLASS32;
+ ehdr.e_machine = EM_ARM;
+
+ GnuDebugdataInitFail<Elf32_Ehdr, Elf32_Shdr>(&ehdr);
+}
+
+TEST_F(ElfTest, gnu_debugdata_init_fail64) {
+ Elf64_Ehdr ehdr;
+ InitEhdr<Elf64_Ehdr>(&ehdr);
+ ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+ ehdr.e_machine = EM_AARCH64;
+
+ GnuDebugdataInitFail<Elf64_Ehdr, Elf64_Shdr>(&ehdr);
+}
+
+template <typename Ehdr, typename Shdr>
+void ElfTest::GnuDebugdataInit(Ehdr* ehdr) {
+ Elf elf(memory_);
+
+ uint64_t offset = 0x2000;
+
+ ehdr->e_shoff = offset;
+ ehdr->e_shnum = 3;
+ ehdr->e_shentsize = sizeof(Shdr);
+ ehdr->e_shstrndx = 2;
+ memory_->SetMemory(0, ehdr, sizeof(*ehdr));
+
+ Shdr shdr;
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_NULL;
+ memory_->SetMemory(offset, &shdr, sizeof(shdr));
+ offset += ehdr->e_shentsize;
+
+ uint64_t gnu_offset = offset;
+ offset += ehdr->e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 0x200000;
+ shdr.sh_offset = 0xf000;
+ shdr.sh_size = 0x1000;
+ memory_->SetMemory(offset, &shdr, sizeof(shdr));
+ offset += ehdr->e_shentsize;
+
+ memory_->SetMemory(0xf100, ".gnu_debugdata", sizeof(".gnu_debugdata"));
+
+ // Read in the compressed elf data and put it in our fake memory.
+ std::string name("tests/");
+ if (sizeof(Ehdr) == sizeof(Elf32_Ehdr)) {
+ name += "elf32.xz";
+ } else {
+ name += "elf64.xz";
+ }
+ int fd = TEMP_FAILURE_RETRY(open(name.c_str(), O_RDONLY));
+ ASSERT_NE(-1, fd) << "Cannot open " + name;
+ // Assumes the file is less than 1024 bytes.
+ std::vector<uint8_t> buf(1024);
+ ssize_t bytes = TEMP_FAILURE_RETRY(read(fd, buf.data(), buf.size()));
+ ASSERT_GT(bytes, 0);
+ // Make sure the file isn't too big.
+ ASSERT_NE(static_cast<size_t>(bytes), buf.size())
+ << "File " + name + " is too big, increase buffer size.";
+ close(fd);
+ buf.resize(bytes);
+ memory_->SetMemory(0x5000, buf);
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_name = 0x100;
+ shdr.sh_addr = 0x5000;
+ shdr.sh_offset = 0x5000;
+ shdr.sh_size = bytes;
+ memory_->SetMemory(gnu_offset, &shdr, sizeof(shdr));
+
+ ASSERT_TRUE(elf.Init());
+ ASSERT_TRUE(elf.interface() != nullptr);
+ ASSERT_TRUE(elf.gnu_debugdata_interface() == nullptr);
+ EXPECT_EQ(0x5000U, elf.interface()->gnu_debugdata_offset());
+
+ elf.InitGnuDebugdata();
+ ASSERT_TRUE(elf.gnu_debugdata_interface() != nullptr);
+}
+
+TEST_F(ElfTest, gnu_debugdata_init32) {
+ Elf32_Ehdr ehdr;
+ InitEhdr<Elf32_Ehdr>(&ehdr);
+ ehdr.e_ident[EI_CLASS] = ELFCLASS32;
+ ehdr.e_machine = EM_ARM;
+
+ GnuDebugdataInit<Elf32_Ehdr, Elf32_Shdr>(&ehdr);
+}
+
+TEST_F(ElfTest, gnu_debugdata_init64) {
+ Elf64_Ehdr ehdr;
+ InitEhdr<Elf64_Ehdr>(&ehdr);
+ ehdr.e_ident[EI_CLASS] = ELFCLASS64;
+ ehdr.e_machine = EM_AARCH64;
+
+ GnuDebugdataInit<Elf64_Ehdr, Elf64_Shdr>(&ehdr);
+}
diff --git a/libunwindstack/tests/GenGnuDebugdata.cpp b/libunwindstack/tests/GenGnuDebugdata.cpp
new file mode 100644
index 0000000..2644582
--- /dev/null
+++ b/libunwindstack/tests/GenGnuDebugdata.cpp
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <elf.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <string>
+
+#if !defined(EM_AARCH64)
+#define EM_AARCH64 183
+#endif
+
+template <typename Ehdr>
+void InitEhdr(Ehdr* ehdr, uint32_t elf_class, uint32_t machine) {
+ memset(ehdr, 0, sizeof(Ehdr));
+ memcpy(&ehdr->e_ident[0], ELFMAG, SELFMAG);
+ ehdr->e_ident[EI_DATA] = ELFDATA2LSB;
+ ehdr->e_ident[EI_VERSION] = EV_CURRENT;
+ ehdr->e_ident[EI_OSABI] = ELFOSABI_SYSV;
+ ehdr->e_ident[EI_CLASS] = elf_class;
+ ehdr->e_type = ET_DYN;
+ ehdr->e_machine = machine;
+ ehdr->e_version = EV_CURRENT;
+ ehdr->e_ehsize = sizeof(Ehdr);
+}
+
+template <typename Ehdr, typename Shdr>
+void GenElf(Ehdr* ehdr, int fd) {
+ uint64_t offset = sizeof(Ehdr);
+ ehdr->e_shoff = offset;
+ ehdr->e_shnum = 3;
+ ehdr->e_shentsize = sizeof(Shdr);
+ ehdr->e_shstrndx = 2;
+ TEMP_FAILURE_RETRY(write(fd, ehdr, sizeof(Ehdr)));
+
+ Shdr shdr;
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_name = 0;
+ shdr.sh_type = SHT_NULL;
+ TEMP_FAILURE_RETRY(write(fd, &shdr, sizeof(Shdr)));
+ offset += ehdr->e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_name = 11;
+ shdr.sh_addr = 0x5000;
+ shdr.sh_offset = 0x5000;
+ shdr.sh_entsize = 0x100;
+ shdr.sh_size = 0x800;
+ TEMP_FAILURE_RETRY(write(fd, &shdr, sizeof(Shdr)));
+ offset += ehdr->e_shentsize;
+
+ memset(&shdr, 0, sizeof(shdr));
+ shdr.sh_type = SHT_STRTAB;
+ shdr.sh_name = 1;
+ shdr.sh_offset = 0x200;
+ shdr.sh_size = 24;
+ TEMP_FAILURE_RETRY(write(fd, &shdr, sizeof(Shdr)));
+
+ // Write out the name entries information.
+ lseek(fd, 0x200, SEEK_SET);
+ std::string name;
+ TEMP_FAILURE_RETRY(write(fd, name.data(), name.size() + 1));
+ name = ".shstrtab";
+ TEMP_FAILURE_RETRY(write(fd, name.data(), name.size() + 1));
+ name = ".debug_frame";
+ TEMP_FAILURE_RETRY(write(fd, name.data(), name.size() + 1));
+}
+
+int main() {
+ int elf32_fd = TEMP_FAILURE_RETRY(open("elf32", O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644));
+ if (elf32_fd == -1) {
+ printf("Failed to create elf32: %s\n", strerror(errno));
+ return 1;
+ }
+
+ int elf64_fd = TEMP_FAILURE_RETRY(open("elf64", O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, 0644));
+ if (elf64_fd == -1) {
+ printf("Failed to create elf64: %s\n", strerror(errno));
+ return 1;
+ }
+
+ Elf32_Ehdr ehdr32;
+ InitEhdr<Elf32_Ehdr>(&ehdr32, ELFCLASS32, EM_ARM);
+ GenElf<Elf32_Ehdr, Elf32_Shdr>(&ehdr32, elf32_fd);
+ close(elf32_fd);
+
+ Elf64_Ehdr ehdr64;
+ InitEhdr<Elf64_Ehdr>(&ehdr64, ELFCLASS64, EM_AARCH64);
+ GenElf<Elf64_Ehdr, Elf64_Shdr>(&ehdr64, elf64_fd);
+ close(elf64_fd);
+}
diff --git a/libunwindstack/tests/elf32.xz b/libunwindstack/tests/elf32.xz
new file mode 100644
index 0000000..f25d433
--- /dev/null
+++ b/libunwindstack/tests/elf32.xz
Binary files differ
diff --git a/libunwindstack/tests/elf64.xz b/libunwindstack/tests/elf64.xz
new file mode 100644
index 0000000..eb1618e
--- /dev/null
+++ b/libunwindstack/tests/elf64.xz
Binary files differ
diff --git a/libunwindstack/unwind_info.cpp b/libunwindstack/unwind_info.cpp
index 6f158b0..da1522b 100644
--- a/libunwindstack/unwind_info.cpp
+++ b/libunwindstack/unwind_info.cpp
@@ -26,6 +26,8 @@
#include <unistd.h>
#include "ArmExidx.h"
+#include "DwarfSection.h"
+#include "DwarfStructs.h"
#include "Elf.h"
#include "ElfInterface.h"
#include "ElfInterfaceArm.h"
@@ -46,12 +48,14 @@
std::string name;
printf(" PC 0x%" PRIx64, addr + load_bias);
uint64_t func_offset;
- if (interface->GetFunctionName(addr + load_bias + 1, &name, &func_offset) && !name.empty()) {
+ uint64_t pc = addr + load_bias;
+ // This might be a thumb function, so set the low bit.
+ if (interface->GetFunctionName(pc | 1, &name, &func_offset) && !name.empty()) {
printf(" <%s>", name.c_str());
}
printf("\n");
uint64_t entry;
- if (!interface->FindEntry(addr + load_bias, &entry)) {
+ if (!interface->FindEntry(pc, &entry)) {
printf(" Cannot find entry for address.\n");
continue;
}
@@ -75,6 +79,27 @@
printf("\n");
}
+void DumpDwarfSection(ElfInterface* interface, DwarfSection* section, uint64_t load_bias) {
+ for (const DwarfFde* fde : *section) {
+ // Sometimes there are entries that have empty length, skip those since
+ // they don't contain any interesting information.
+ if (fde->pc_start == fde->pc_end) {
+ continue;
+ }
+ printf("\n PC 0x%" PRIx64, fde->pc_start + load_bias);
+ std::string name;
+ uint64_t func_offset;
+ if (interface->GetFunctionName(fde->pc_start + load_bias, &name, &func_offset) &&
+ !name.empty()) {
+ printf(" <%s>", name.c_str());
+ }
+ printf("\n");
+ if (!section->Log(2, UINT64_MAX, load_bias, fde)) {
+ printf("Failed to process cfa information for entry at 0x%" PRIx64 "\n", fde->pc_start);
+ }
+ }
+}
+
int main(int argc, char** argv) {
if (argc != 2) {
printf("Need to pass the name of an elf file to the program.\n");
@@ -117,5 +142,38 @@
printf("\n");
}
+ if (interface->eh_frame() != nullptr) {
+ printf("eh_frame information:\n");
+ DumpDwarfSection(interface, interface->eh_frame(), interface->load_bias());
+ printf("\n");
+ } else {
+ printf("\nno eh_frame information\n");
+ }
+
+ if (interface->debug_frame() != nullptr) {
+ printf("\ndebug_frame information:\n");
+ DumpDwarfSection(interface, interface->debug_frame(), interface->load_bias());
+ printf("\n");
+ } else {
+ printf("\nno debug_frame information\n");
+ }
+
+ // If there is a gnu_debugdata interface, dump the information for that.
+ ElfInterface* gnu_debugdata_interface = elf.gnu_debugdata_interface();
+ if (gnu_debugdata_interface != nullptr) {
+ if (gnu_debugdata_interface->eh_frame() != nullptr) {
+ printf("\ngnu_debugdata (eh_frame):\n");
+ DumpDwarfSection(gnu_debugdata_interface, gnu_debugdata_interface->eh_frame(), 0);
+ printf("\n");
+ }
+ if (gnu_debugdata_interface->debug_frame() != nullptr) {
+ printf("\ngnu_debugdata (debug_frame):\n");
+ DumpDwarfSection(gnu_debugdata_interface, gnu_debugdata_interface->debug_frame(), 0);
+ printf("\n");
+ }
+ } else {
+ printf("\nno valid gnu_debugdata information\n");
+ }
+
return 0;
}
diff --git a/libziparchive/Android.bp b/libziparchive/Android.bp
index 1084d59..84a9a2f 100644
--- a/libziparchive/Android.bp
+++ b/libziparchive/Android.bp
@@ -65,6 +65,7 @@
"liblog",
"libbase",
],
+ export_include_dirs: ["include"],
target: {
android: {
shared_libs: [
diff --git a/libziparchive/entry_name_utils-inl.h b/libziparchive/entry_name_utils-inl.h
index ddbc286..5fc2fb4 100644
--- a/libziparchive/entry_name_utils-inl.h
+++ b/libziparchive/entry_name_utils-inl.h
@@ -55,5 +55,4 @@
return true;
}
-
#endif // LIBZIPARCHIVE_ENTRY_NAME_UTILS_INL_H_
diff --git a/libziparchive/entry_name_utils_test.cc b/libziparchive/entry_name_utils_test.cc
index 20715bb..d83d854 100644
--- a/libziparchive/entry_name_utils_test.cc
+++ b/libziparchive/entry_name_utils_test.cc
@@ -20,44 +20,43 @@
TEST(entry_name_utils, NullChars) {
// 'A', 'R', '\0', 'S', 'E'
- const uint8_t zeroes[] = { 0x41, 0x52, 0x00, 0x53, 0x45 };
+ const uint8_t zeroes[] = {0x41, 0x52, 0x00, 0x53, 0x45};
ASSERT_FALSE(IsValidEntryName(zeroes, sizeof(zeroes)));
- const uint8_t zeroes_continuation_chars[] = { 0xc2, 0xa1, 0xc2, 0x00 };
- ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars,
- sizeof(zeroes_continuation_chars)));
+ const uint8_t zeroes_continuation_chars[] = {0xc2, 0xa1, 0xc2, 0x00};
+ ASSERT_FALSE(IsValidEntryName(zeroes_continuation_chars, sizeof(zeroes_continuation_chars)));
}
TEST(entry_name_utils, InvalidSequence) {
// 0xfe is an invalid start byte
- const uint8_t invalid[] = { 0x41, 0xfe };
+ const uint8_t invalid[] = {0x41, 0xfe};
ASSERT_FALSE(IsValidEntryName(invalid, sizeof(invalid)));
// 0x91 is an invalid start byte (it's a valid continuation byte).
- const uint8_t invalid2[] = { 0x41, 0x91 };
+ const uint8_t invalid2[] = {0x41, 0x91};
ASSERT_FALSE(IsValidEntryName(invalid2, sizeof(invalid2)));
}
TEST(entry_name_utils, TruncatedContinuation) {
// Malayalam script with truncated bytes. There should be 2 bytes
// after 0xe0
- const uint8_t truncated[] = { 0xe0, 0xb4, 0x85, 0xe0, 0xb4 };
+ const uint8_t truncated[] = {0xe0, 0xb4, 0x85, 0xe0, 0xb4};
ASSERT_FALSE(IsValidEntryName(truncated, sizeof(truncated)));
// 0xc2 is the start of a 2 byte sequence that we've subsequently
// dropped.
- const uint8_t truncated2[] = { 0xc2, 0xc2, 0xa1 };
+ const uint8_t truncated2[] = {0xc2, 0xc2, 0xa1};
ASSERT_FALSE(IsValidEntryName(truncated2, sizeof(truncated2)));
}
TEST(entry_name_utils, BadContinuation) {
// 0x41 is an invalid continuation char, since it's MSBs
// aren't "10..." (are 01).
- const uint8_t bad[] = { 0xc2, 0xa1, 0xc2, 0x41 };
+ const uint8_t bad[] = {0xc2, 0xa1, 0xc2, 0x41};
ASSERT_FALSE(IsValidEntryName(bad, sizeof(bad)));
// 0x41 is an invalid continuation char, since it's MSBs
// aren't "10..." (are 11).
- const uint8_t bad2[] = { 0xc2, 0xa1, 0xc2, 0xfe };
+ const uint8_t bad2[] = {0xc2, 0xa1, 0xc2, 0xfe};
ASSERT_FALSE(IsValidEntryName(bad2, sizeof(bad2)));
}
diff --git a/include/ziparchive/zip_archive.h b/libziparchive/include/ziparchive/zip_archive.h
similarity index 90%
rename from include/ziparchive/zip_archive.h
rename to libziparchive/include/ziparchive/zip_archive.h
index ece8693..73ae68d 100644
--- a/include/ziparchive/zip_archive.h
+++ b/libziparchive/include/ziparchive/zip_archive.h
@@ -28,8 +28,8 @@
/* Zip compression methods we support */
enum {
- kCompressStored = 0, // no compression
- kCompressDeflated = 8, // standard deflate
+ kCompressStored = 0, // no compression
+ kCompressDeflated = 8, // standard deflate
};
struct ZipString {
@@ -44,19 +44,17 @@
explicit ZipString(const char* entry_name);
bool operator==(const ZipString& rhs) const {
- return name && (name_length == rhs.name_length) &&
- (memcmp(name, rhs.name, name_length) == 0);
+ return name && (name_length == rhs.name_length) && (memcmp(name, rhs.name, name_length) == 0);
}
bool StartsWith(const ZipString& prefix) const {
return name && (name_length >= prefix.name_length) &&
- (memcmp(name, prefix.name, prefix.name_length) == 0);
+ (memcmp(name, prefix.name, prefix.name_length) == 0);
}
bool EndsWith(const ZipString& suffix) const {
return name && (name_length >= suffix.name_length) &&
- (memcmp(name + name_length - suffix.name_length, suffix.name,
- suffix.name_length) == 0);
+ (memcmp(name + name_length - suffix.name_length, suffix.name, suffix.name_length) == 0);
}
};
@@ -134,11 +132,11 @@
*
* Returns 0 on success, and negative values on failure.
*/
-int32_t OpenArchiveFd(const int fd, const char* debugFileName,
- ZipArchiveHandle *handle, bool assume_ownership = true);
+int32_t OpenArchiveFd(const int fd, const char* debugFileName, ZipArchiveHandle* handle,
+ bool assume_ownership = true);
int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debugFileName,
- ZipArchiveHandle *handle);
+ ZipArchiveHandle* handle);
/*
* Close archive, releasing resources associated with it. This will
* unmap the central directory of the zipfile and free all internal
@@ -164,8 +162,7 @@
* On non-Windows platforms this method does not modify internal state and
* can be called concurrently.
*/
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
- ZipEntry* data);
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName, ZipEntry* data);
/*
* Start iterating over all entries of a zip file. The order of iteration
@@ -180,8 +177,7 @@
*
* Returns 0 on success and negative values on failure.
*/
-int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
- const ZipString* optional_prefix,
+int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, const ZipString* optional_prefix,
const ZipString* optional_suffix);
/*
@@ -217,8 +213,7 @@
*
* Returns 0 on success and negative values on failure.
*/
-int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
- uint8_t* begin, uint32_t size);
+int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry, uint8_t* begin, uint32_t size);
int GetFileDescriptor(const ZipArchiveHandle handle);
@@ -230,9 +225,9 @@
/*
* Stream the uncompressed data through the supplied function,
* passing cookie to it each time it gets called.
-*/
+ */
int32_t ProcessZipEntryContents(ZipArchiveHandle handle, ZipEntry* entry,
- ProcessZipEntryFunction func, void* cookie);
+ ProcessZipEntryFunction func, void* cookie);
#endif
#endif // LIBZIPARCHIVE_ZIPARCHIVE_H_
diff --git a/include/ziparchive/zip_archive_stream_entry.h b/libziparchive/include/ziparchive/zip_archive_stream_entry.h
similarity index 100%
rename from include/ziparchive/zip_archive_stream_entry.h
rename to libziparchive/include/ziparchive/zip_archive_stream_entry.h
diff --git a/include/ziparchive/zip_writer.h b/libziparchive/include/ziparchive/zip_writer.h
similarity index 96%
rename from include/ziparchive/zip_writer.h
rename to libziparchive/include/ziparchive/zip_writer.h
index 08ead48..c350a27 100644
--- a/include/ziparchive/zip_writer.h
+++ b/libziparchive/include/ziparchive/zip_writer.h
@@ -19,7 +19,6 @@
#include <cstdio>
#include <ctime>
-#include <zlib.h>
#include <memory>
#include <string>
@@ -28,6 +27,9 @@
#include "android-base/macros.h"
#include "utils/Compat.h"
+struct z_stream_s;
+typedef struct z_stream_s z_stream;
+
/**
* Writes a Zip file via a stateful interface.
*
@@ -50,7 +52,7 @@
* fclose(file);
*/
class ZipWriter {
-public:
+ public:
enum {
/**
* Flag to compress the zip entry using deflate.
@@ -120,8 +122,7 @@
/**
* Same as StartAlignedEntry(const char*, size_t), but sets a last modified time for the entry.
*/
- int32_t StartAlignedEntryWithTime(const char* path, size_t flags, time_t time,
- uint32_t alignment);
+ int32_t StartAlignedEntryWithTime(const char* path, size_t flags, time_t time, uint32_t alignment);
/**
* Writes bytes to the zip file for the previously started zip entry.
@@ -156,7 +157,7 @@
*/
int32_t Finish();
-private:
+ private:
DISALLOW_COPY_AND_ASSIGN(ZipWriter);
int32_t HandleError(int32_t error_code);
@@ -179,7 +180,7 @@
std::vector<FileEntry> files_;
FileEntry current_file_entry_;
- std::unique_ptr<z_stream, void(*)(z_stream*)> z_stream_;
+ std::unique_ptr<z_stream, void (*)(z_stream*)> z_stream_;
std::vector<uint8_t> buffer_;
};
diff --git a/libziparchive/testdata/bad_filename.zip b/libziparchive/testdata/bad_filename.zip
new file mode 100644
index 0000000..294eaf5
--- /dev/null
+++ b/libziparchive/testdata/bad_filename.zip
Binary files differ
diff --git a/libziparchive/testdata/crash.apk b/libziparchive/testdata/crash.apk
new file mode 100644
index 0000000..d6dd52d
--- /dev/null
+++ b/libziparchive/testdata/crash.apk
Binary files differ
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index efe1096..17c268b 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -115,8 +115,7 @@
* Convert a ZipEntry to a hash table index, verifying that it's in a
* valid range.
*/
-static int64_t EntryToIndex(const ZipString* hash_table,
- const uint32_t hash_table_size,
+static int64_t EntryToIndex(const ZipString* hash_table, const uint32_t hash_table_size,
const ZipString& name) {
const uint32_t hash = ComputeHash(name);
@@ -137,7 +136,7 @@
/*
* Add a new entry to the hash table.
*/
-static int32_t AddToHash(ZipString *hash_table, const uint64_t hash_table_size,
+static int32_t AddToHash(ZipString* hash_table, const uint64_t hash_table_size,
const ZipString& name) {
const uint64_t hash = ComputeHash(name);
uint32_t ent = hash & (hash_table_size - 1);
@@ -161,13 +160,12 @@
}
static int32_t MapCentralDirectory0(const char* debug_file_name, ZipArchive* archive,
- off64_t file_length, off64_t read_amount,
- uint8_t* scan_buffer) {
+ off64_t file_length, off64_t read_amount, uint8_t* scan_buffer) {
const off64_t search_start = file_length - read_amount;
- if(!archive->mapped_zip.ReadAtOffset(scan_buffer, read_amount, search_start)) {
- ALOGE("Zip: read %" PRId64 " from offset %" PRId64 " failed",
- static_cast<int64_t>(read_amount), static_cast<int64_t>(search_start));
+ if (!archive->mapped_zip.ReadAtOffset(scan_buffer, read_amount, search_start)) {
+ ALOGE("Zip: read %" PRId64 " from offset %" PRId64 " failed", static_cast<int64_t>(read_amount),
+ static_cast<int64_t>(search_start));
return kIoError;
}
@@ -198,8 +196,7 @@
* Verify that there's no trailing space at the end of the central directory
* and its comment.
*/
- const off64_t calculated_length = eocd_offset + sizeof(EocdRecord)
- + eocd->comment_length;
+ const off64_t calculated_length = eocd_offset + sizeof(EocdRecord) + eocd->comment_length;
if (calculated_length != file_length) {
ALOGW("Zip: %" PRId64 " extraneous bytes at the end of the central directory",
static_cast<int64_t>(file_length - calculated_length));
@@ -212,7 +209,7 @@
*/
if (static_cast<off64_t>(eocd->cd_start_offset) + eocd->cd_size > eocd_offset) {
ALOGW("Zip: bad offsets (dir %" PRIu32 ", size %" PRIu32 ", eocd %" PRId64 ")",
- eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
+ eocd->cd_start_offset, eocd->cd_size, static_cast<int64_t>(eocd_offset));
#if defined(__ANDROID__)
if (eocd->cd_start_offset + eocd->cd_size <= eocd_offset) {
android_errorWriteLog(0x534e4554, "31251826");
@@ -225,8 +222,8 @@
return kEmptyArchive;
}
- ALOGV("+++ num_entries=%" PRIu32 " dir_size=%" PRIu32 " dir_offset=%" PRIu32,
- eocd->num_records, eocd->cd_size, eocd->cd_start_offset);
+ ALOGV("+++ num_entries=%" PRIu32 " dir_size=%" PRIu32 " dir_offset=%" PRIu32, eocd->num_records,
+ eocd->cd_size, eocd->cd_start_offset);
/*
* It all looks good. Create a mapping for the CD, and set the fields
@@ -255,7 +252,6 @@
* num_entries
*/
static int32_t MapCentralDirectory(const char* debug_file_name, ZipArchive* archive) {
-
// Test file length. We use lseek64 to make sure the file
// is small enough to be a zip file (Its size must be less than
// 0xffffffff bytes).
@@ -292,8 +288,8 @@
}
std::vector<uint8_t> scan_buffer(read_amount);
- int32_t result = MapCentralDirectory0(debug_file_name, archive, file_length, read_amount,
- scan_buffer.data());
+ int32_t result =
+ MapCentralDirectory0(debug_file_name, archive, file_length, read_amount, scan_buffer.data());
return result;
}
@@ -314,8 +310,13 @@
* least one unused entry to avoid an infinite loop during creation.
*/
archive->hash_table_size = RoundUpPower2(1 + (num_entries * 4) / 3);
- archive->hash_table = reinterpret_cast<ZipString*>(calloc(archive->hash_table_size,
- sizeof(ZipString)));
+ archive->hash_table =
+ reinterpret_cast<ZipString*>(calloc(archive->hash_table_size, sizeof(ZipString)));
+ if (archive->hash_table == nullptr) {
+ ALOGW("Zip: unable to allocate the %u-entry hash_table, entry size: %zu",
+ archive->hash_table_size, sizeof(ZipString));
+ return -1;
+ }
/*
* Walk through the central directory, adding entries to the hash
@@ -324,22 +325,24 @@
const uint8_t* const cd_end = cd_ptr + cd_length;
const uint8_t* ptr = cd_ptr;
for (uint16_t i = 0; i < num_entries; i++) {
- const CentralDirectoryRecord* cdr =
- reinterpret_cast<const CentralDirectoryRecord*>(ptr);
- if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
- ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
+ if (ptr > cd_end - sizeof(CentralDirectoryRecord)) {
+ ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
+#if defined(__ANDROID__)
+ android_errorWriteLog(0x534e4554, "36392138");
+#endif
return -1;
}
- if (ptr + sizeof(CentralDirectoryRecord) > cd_end) {
- ALOGW("Zip: ran off the end (at %" PRIu16 ")", i);
+ const CentralDirectoryRecord* cdr = reinterpret_cast<const CentralDirectoryRecord*>(ptr);
+ if (cdr->record_signature != CentralDirectoryRecord::kSignature) {
+ ALOGW("Zip: missed a central dir sig (at %" PRIu16 ")", i);
return -1;
}
const off64_t local_header_offset = cdr->local_file_header_offset;
if (local_header_offset >= archive->directory_offset) {
ALOGW("Zip: bad LFH offset %" PRId64 " at entry %" PRIu16,
- static_cast<int64_t>(local_header_offset), i);
+ static_cast<int64_t>(local_header_offset), i);
return -1;
}
@@ -348,6 +351,13 @@
const uint16_t comment_length = cdr->comment_length;
const uint8_t* file_name = ptr + sizeof(CentralDirectoryRecord);
+ if (file_name + file_name_length > cd_end) {
+ ALOGW(
+ "Zip: file name boundary exceeds the central directory range, file_name_length: "
+ "%" PRIx16 ", cd_length: %zu",
+ file_name_length, cd_length);
+ return -1;
+ }
/* check that file name is valid UTF-8 and doesn't contain NUL (U+0000) characters */
if (!IsValidEntryName(file_name, file_name_length)) {
return -1;
@@ -357,8 +367,7 @@
ZipString entry_name;
entry_name.name = file_name;
entry_name.name_length = file_name_length;
- const int add_result = AddToHash(archive->hash_table,
- archive->hash_table_size, entry_name);
+ const int add_result = AddToHash(archive->hash_table, archive->hash_table_size, entry_name);
if (add_result != 0) {
ALOGW("Zip: Error adding entry to hash table %d", add_result);
return add_result;
@@ -366,8 +375,7 @@
ptr += sizeof(CentralDirectoryRecord) + file_name_length + extra_length + comment_length;
if ((ptr - cd_ptr) > static_cast<int64_t>(cd_length)) {
- ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16,
- ptr - cd_ptr, cd_length, i);
+ ALOGW("Zip: bad CD advance (%tu vs %zu) at entry %" PRIu16, ptr - cd_ptr, cd_length, i);
return -1;
}
}
@@ -376,8 +384,7 @@
return 0;
}
-static int32_t OpenArchiveInternal(ZipArchive* archive,
- const char* debug_file_name) {
+static int32_t OpenArchiveInternal(ZipArchive* archive, const char* debug_file_name) {
int32_t result = -1;
if ((result = MapCentralDirectory(debug_file_name, archive)) != 0) {
return result;
@@ -390,8 +397,8 @@
return 0;
}
-int32_t OpenArchiveFd(int fd, const char* debug_file_name,
- ZipArchiveHandle* handle, bool assume_ownership) {
+int32_t OpenArchiveFd(int fd, const char* debug_file_name, ZipArchiveHandle* handle,
+ bool assume_ownership) {
ZipArchive* archive = new ZipArchive(fd, assume_ownership);
*handle = archive;
return OpenArchiveInternal(archive, debug_file_name);
@@ -411,7 +418,7 @@
}
int32_t OpenArchiveFromMemory(void* address, size_t length, const char* debug_file_name,
- ZipArchiveHandle *handle) {
+ ZipArchiveHandle* handle) {
ZipArchive* archive = new ZipArchive(address, length);
*handle = archive;
return OpenArchiveInternal(archive, debug_file_name);
@@ -451,8 +458,7 @@
return 0;
}
-static int32_t FindEntry(const ZipArchive* archive, const int ent,
- ZipEntry* data) {
+static int32_t FindEntry(const ZipArchive* archive, const int ent, ZipEntry* data) {
const uint16_t nameLen = archive->hash_table[ent].name_length;
// Recover the start of the central directory entry from the filename
@@ -470,8 +476,7 @@
return kInvalidOffset;
}
- const CentralDirectoryRecord *cdr =
- reinterpret_cast<const CentralDirectoryRecord*>(ptr);
+ const CentralDirectoryRecord* cdr = reinterpret_cast<const CentralDirectoryRecord*>(ptr);
// The offset of the start of the central directory in the zipfile.
// We keep this lying around so that we can sanity check all our lengths
@@ -499,15 +504,15 @@
uint8_t lfh_buf[sizeof(LocalFileHeader)];
if (!archive->mapped_zip.ReadAtOffset(lfh_buf, sizeof(lfh_buf), local_header_offset)) {
ALOGW("Zip: failed reading lfh name from offset %" PRId64,
- static_cast<int64_t>(local_header_offset));
+ static_cast<int64_t>(local_header_offset));
return kIoError;
}
- const LocalFileHeader *lfh = reinterpret_cast<const LocalFileHeader*>(lfh_buf);
+ const LocalFileHeader* lfh = reinterpret_cast<const LocalFileHeader*>(lfh_buf);
if (lfh->lfh_signature != LocalFileHeader::kSignature) {
ALOGW("Zip: didn't find signature at start of lfh, offset=%" PRId64,
- static_cast<int64_t>(local_header_offset));
+ static_cast<int64_t>(local_header_offset));
return kInvalidOffset;
}
@@ -536,13 +541,12 @@
// header agree on the crc, compressed, and uncompressed sizes of the entry.
if ((lfh->gpb_flags & kGPBDDFlagMask) == 0) {
data->has_data_descriptor = 0;
- if (data->compressed_length != lfh->compressed_size
- || data->uncompressed_length != lfh->uncompressed_size
- || data->crc32 != lfh->crc32) {
- ALOGW("Zip: size/crc32 mismatch. expected {%" PRIu32 ", %" PRIu32
- ", %" PRIx32 "}, was {%" PRIu32 ", %" PRIu32 ", %" PRIx32 "}",
- data->compressed_length, data->uncompressed_length, data->crc32,
- lfh->compressed_size, lfh->uncompressed_size, lfh->crc32);
+ if (data->compressed_length != lfh->compressed_size ||
+ data->uncompressed_length != lfh->uncompressed_size || data->crc32 != lfh->crc32) {
+ ALOGW("Zip: size/crc32 mismatch. expected {%" PRIu32 ", %" PRIu32 ", %" PRIx32
+ "}, was {%" PRIu32 ", %" PRIu32 ", %" PRIx32 "}",
+ data->compressed_length, data->uncompressed_length, data->crc32, lfh->compressed_size,
+ lfh->uncompressed_size, lfh->crc32);
return kInconsistentInformation;
}
} else {
@@ -580,8 +584,8 @@
return kInconsistentInformation;
}
- const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader)
- + lfh->file_name_length + lfh->extra_field_length;
+ const off64_t data_offset = local_header_offset + sizeof(LocalFileHeader) +
+ lfh->file_name_length + lfh->extra_field_length;
if (data_offset > cd_offset) {
ALOGW("Zip: bad data offset %" PRId64 " in zip", static_cast<int64_t>(data_offset));
return kInvalidOffset;
@@ -589,16 +593,17 @@
if (static_cast<off64_t>(data_offset + data->compressed_length) > cd_offset) {
ALOGW("Zip: bad compressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
- static_cast<int64_t>(data_offset), data->compressed_length, static_cast<int64_t>(cd_offset));
+ static_cast<int64_t>(data_offset), data->compressed_length,
+ static_cast<int64_t>(cd_offset));
return kInvalidOffset;
}
if (data->method == kCompressStored &&
- static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {
- ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
- static_cast<int64_t>(data_offset), data->uncompressed_length,
- static_cast<int64_t>(cd_offset));
- return kInvalidOffset;
+ static_cast<off64_t>(data_offset + data->uncompressed_length) > cd_offset) {
+ ALOGW("Zip: bad uncompressed length in zip (%" PRId64 " + %" PRIu32 " > %" PRId64 ")",
+ static_cast<int64_t>(data_offset), data->uncompressed_length,
+ static_cast<int64_t>(cd_offset));
+ return kInvalidOffset;
}
data->offset = data_offset;
@@ -613,8 +618,7 @@
ZipString suffix;
ZipArchive* archive;
- IterationHandle(const ZipString* in_prefix,
- const ZipString* in_suffix) {
+ IterationHandle(const ZipString* in_prefix, const ZipString* in_suffix) {
if (in_prefix) {
uint8_t* name_copy = new uint8_t[in_prefix->name_length];
memcpy(name_copy, in_prefix->name, in_prefix->name_length);
@@ -641,8 +645,7 @@
}
};
-int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
- const ZipString* optional_prefix,
+int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr, const ZipString* optional_prefix,
const ZipString* optional_suffix) {
ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
@@ -655,7 +658,7 @@
cookie->position = 0;
cookie->archive = archive;
- *cookie_ptr = cookie ;
+ *cookie_ptr = cookie;
return 0;
}
@@ -663,16 +666,14 @@
delete reinterpret_cast<IterationHandle*>(cookie);
}
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
- ZipEntry* data) {
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName, ZipEntry* data) {
const ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
if (entryName.name_length == 0) {
ALOGW("Zip: Invalid filename %.*s", entryName.name_length, entryName.name);
return kInvalidEntryName;
}
- const int64_t ent = EntryToIndex(archive->hash_table,
- archive->hash_table_size, entryName);
+ const int64_t ent = EntryToIndex(archive->hash_table, archive->hash_table_size, entryName);
if (ent < 0) {
ALOGV("Zip: Could not find entry %.*s", entryName.name_length, entryName.name);
@@ -700,10 +701,8 @@
for (uint32_t i = currentOffset; i < hash_table_length; ++i) {
if (hash_table[i].name != NULL &&
- (handle->prefix.name_length == 0 ||
- hash_table[i].StartsWith(handle->prefix)) &&
- (handle->suffix.name_length == 0 ||
- hash_table[i].EndsWith(handle->suffix))) {
+ (handle->prefix.name_length == 0 || hash_table[i].StartsWith(handle->prefix)) &&
+ (handle->suffix.name_length == 0 || hash_table[i].EndsWith(handle->suffix))) {
handle->position = (i + 1);
const int error = FindEntry(archive, i, data);
if (!error) {
@@ -723,8 +722,10 @@
public:
virtual bool Append(uint8_t* buf, size_t buf_size) = 0;
virtual ~Writer() {}
+
protected:
Writer() = default;
+
private:
DISALLOW_COPY_AND_ASSIGN(Writer);
};
@@ -734,14 +735,12 @@
// the data appended to it.
class MemoryWriter : public Writer {
public:
- MemoryWriter(uint8_t* buf, size_t size) : Writer(),
- buf_(buf), size_(size), bytes_written_(0) {
- }
+ MemoryWriter(uint8_t* buf, size_t size) : Writer(), buf_(buf), size_(size), bytes_written_(0) {}
virtual bool Append(uint8_t* buf, size_t buf_size) override {
if (bytes_written_ + buf_size > size_) {
- ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
- size_, bytes_written_ + buf_size);
+ ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", size_,
+ bytes_written_ + buf_size);
return false;
}
@@ -760,7 +759,6 @@
// The file will be truncated to the end of the written data.
class FileWriter : public Writer {
public:
-
// Creates a FileWriter for |fd| and prepare to write |entry| to it,
// guaranteeing that the file descriptor is valid and that there's enough
// space on the volume to write out the entry completely and that the file
@@ -819,8 +817,8 @@
virtual bool Append(uint8_t* buf, size_t buf_size) override {
if (total_bytes_written_ + buf_size > declared_length_) {
- ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)",
- declared_length_, total_bytes_written_ + buf_size);
+ ALOGW("Zip: Unexpected size " ZD " (declared) vs " ZD " (actual)", declared_length_,
+ total_bytes_written_ + buf_size);
return false;
}
@@ -833,13 +831,10 @@
return result;
}
+
private:
- FileWriter(const int fd, const size_t declared_length) :
- Writer(),
- fd_(fd),
- declared_length_(declared_length),
- total_bytes_written_(0) {
- }
+ FileWriter(const int fd, const size_t declared_length)
+ : Writer(), fd_(fd), declared_length_(declared_length), total_bytes_written_(0) {}
const int fd_;
const size_t declared_length_;
@@ -882,8 +877,7 @@
zerr = zlib_inflateInit2(&zstream, -MAX_WBITS);
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
- ALOGE("Installed zlib is not compatible with linked version (%s)",
- ZLIB_VERSION);
+ ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
} else {
ALOGW("Call to inflateInit2 failed (zerr=%d)", zerr);
}
@@ -892,7 +886,7 @@
}
auto zstream_deleter = [](z_stream* stream) {
- inflateEnd(stream); /* free up any allocated structures */
+ inflateEnd(stream); /* free up any allocated structures */
};
std::unique_ptr<z_stream, decltype(zstream_deleter)> zstream_guard(&zstream, zstream_deleter);
@@ -919,15 +913,13 @@
/* uncompress the data */
zerr = inflate(&zstream, Z_NO_FLUSH);
if (zerr != Z_OK && zerr != Z_STREAM_END) {
- ALOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
- zerr, zstream.next_in, zstream.avail_in,
- zstream.next_out, zstream.avail_out);
+ ALOGW("Zip: inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)", zerr, zstream.next_in,
+ zstream.avail_in, zstream.next_out, zstream.avail_out);
return kZlibError;
}
/* write when we're full or when we're done */
- if (zstream.avail_out == 0 ||
- (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
+ if (zstream.avail_out == 0 || (zerr == Z_STREAM_END && zstream.avail_out != kBufSize)) {
const size_t write_size = zstream.next_out - &write_buf[0];
if (!writer->Append(&write_buf[0], write_size)) {
// The file might have declared a bogus length.
@@ -941,7 +933,7 @@
}
} while (zerr == Z_OK);
- assert(zerr == Z_STREAM_END); /* other errors should've been caught */
+ assert(zerr == Z_STREAM_END); /* other errors should've been caught */
// NOTE: zstream.adler is always set to 0, because we're using the -MAX_WBITS
// "feature" of zlib to tell it there won't be a zlib file header. zlib
@@ -952,8 +944,8 @@
*crc_out = crc;
if (zstream.total_out != uncompressed_length || compressed_length != 0) {
- ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")",
- zstream.total_out, uncompressed_length);
+ ALOGW("Zip: size mismatch on inflated file (%lu vs %" PRIu32 ")", zstream.total_out,
+ uncompressed_length);
return kInconsistentInformation;
}
@@ -961,7 +953,7 @@
}
static int32_t CopyEntryToWriter(MappedZipFile& mapped_zip, const ZipEntry* entry, Writer* writer,
- uint64_t *crc_out) {
+ uint64_t* crc_out) {
static const uint32_t kBufSize = 32768;
std::vector<uint8_t> buf(kBufSize);
@@ -991,8 +983,7 @@
return 0;
}
-int32_t ExtractToWriter(ZipArchiveHandle handle,
- ZipEntry* entry, Writer* writer) {
+int32_t ExtractToWriter(ZipArchiveHandle handle, ZipEntry* entry, Writer* writer) {
ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
const uint16_t method = entry->method;
off64_t data_offset = entry->offset;
@@ -1027,14 +1018,12 @@
return return_value;
}
-int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry,
- uint8_t* begin, uint32_t size) {
+int32_t ExtractToMemory(ZipArchiveHandle handle, ZipEntry* entry, uint8_t* begin, uint32_t size) {
std::unique_ptr<Writer> writer(new MemoryWriter(begin, size));
return ExtractToWriter(handle, entry, writer.get());
}
-int32_t ExtractEntryToFile(ZipArchiveHandle handle,
- ZipEntry* entry, int fd) {
+int32_t ExtractEntryToFile(ZipArchiveHandle handle, ZipEntry* entry, int fd) {
std::unique_ptr<Writer> writer(FileWriter::Create(fd, entry));
if (writer.get() == nullptr) {
return kIoError;
@@ -1061,8 +1050,7 @@
return reinterpret_cast<ZipArchive*>(handle)->mapped_zip.GetFileDescriptor();
}
-ZipString::ZipString(const char* entry_name)
- : name(reinterpret_cast<const uint8_t*>(entry_name)) {
+ZipString::ZipString(const char* entry_name) : name(reinterpret_cast<const uint8_t*>(entry_name)) {
size_t len = strlen(entry_name);
CHECK_LE(len, static_cast<size_t>(UINT16_MAX));
name_length = static_cast<uint16_t>(len);
@@ -1071,10 +1059,8 @@
#if !defined(_WIN32)
class ProcessWriter : public Writer {
public:
- ProcessWriter(ProcessZipEntryFunction func, void* cookie) : Writer(),
- proc_function_(func),
- cookie_(cookie) {
- }
+ ProcessWriter(ProcessZipEntryFunction func, void* cookie)
+ : Writer(), proc_function_(func), cookie_(cookie) {}
virtual bool Append(uint8_t* buf, size_t buf_size) override {
return proc_function_(buf, buf_size, cookie_);
@@ -1091,7 +1077,7 @@
return ExtractToWriter(handle, entry, &writer);
}
-#endif //!defined(_WIN32)
+#endif //! defined(_WIN32)
int MappedZipFile::GetFileDescriptor() const {
if (!has_fd_) {
@@ -1134,8 +1120,7 @@
return true;
} else {
if (offset < 0 || offset > static_cast<off64_t>(data_length_)) {
- ALOGE("Zip: invalid offset: %" PRId64 ", data length: %" PRId64 "\n" , offset,
- data_length_);
+ ALOGE("Zip: invalid offset: %" PRId64 ", data length: %" PRId64 "\n", offset, data_length_);
return false;
}
@@ -1146,7 +1131,7 @@
bool MappedZipFile::ReadData(uint8_t* buffer, size_t read_amount) {
if (has_fd_) {
- if(!android::base::ReadFully(fd_, buffer, read_amount)) {
+ if (!android::base::ReadFully(fd_, buffer, read_amount)) {
ALOGE("Zip: read from %d failed\n", fd_);
return false;
}
@@ -1172,7 +1157,6 @@
return false;
}
return ReadData(buf, len);
-
}
void CentralDirectory::Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size) {
@@ -1183,13 +1167,13 @@
bool ZipArchive::InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
size_t cd_size) {
if (mapped_zip.HasFd()) {
- if (!directory_map->create(debug_file_name, mapped_zip.GetFileDescriptor(),
- cd_start_offset, cd_size, true /* read only */)) {
+ if (!directory_map->create(debug_file_name, mapped_zip.GetFileDescriptor(), cd_start_offset,
+ cd_size, true /* read only */)) {
return false;
}
CHECK_EQ(directory_map->getDataLength(), cd_size);
- central_directory.Initialize(directory_map->getDataPtr(), 0/*offset*/, cd_size);
+ central_directory.Initialize(directory_map->getDataPtr(), 0 /*offset*/, cd_size);
} else {
if (mapped_zip.GetBasePtr() == nullptr) {
ALOGE("Zip: Failed to map central directory, bad mapped_zip base pointer\n");
@@ -1197,9 +1181,10 @@
}
if (static_cast<off64_t>(cd_start_offset) + static_cast<off64_t>(cd_size) >
mapped_zip.GetFileLength()) {
- ALOGE("Zip: Failed to map central directory, offset exceeds mapped memory region ("
- "start_offset %" PRId64 ", cd_size %zu, mapped_region_size %" PRId64 ")",
- static_cast<int64_t>(cd_start_offset), cd_size, mapped_zip.GetFileLength());
+ ALOGE(
+ "Zip: Failed to map central directory, offset exceeds mapped memory region ("
+ "start_offset %" PRId64 ", cd_size %zu, mapped_region_size %" PRId64 ")",
+ static_cast<int64_t>(cd_start_offset), cd_size, mapped_zip.GetFileLength());
return false;
}
diff --git a/libziparchive/zip_archive_common.h b/libziparchive/zip_archive_common.h
index bc1ebb4..8b99bde 100644
--- a/libziparchive/zip_archive_common.h
+++ b/libziparchive/zip_archive_common.h
@@ -57,6 +57,7 @@
uint32_t cd_start_offset;
// Length of the central directory comment.
uint16_t comment_length;
+
private:
EocdRecord() = default;
DISALLOW_COPY_AND_ASSIGN(EocdRecord);
@@ -111,6 +112,7 @@
// The offset to the local file header for this entry, from the
// beginning of this archive.
uint32_t local_file_header_offset;
+
private:
CentralDirectoryRecord() = default;
DISALLOW_COPY_AND_ASSIGN(CentralDirectoryRecord);
@@ -149,6 +151,7 @@
// The length of the extra field info (in bytes). This data
// will appear immediately after the entry file name.
uint16_t extra_field_length;
+
private:
LocalFileHeader() = default;
DISALLOW_COPY_AND_ASSIGN(LocalFileHeader);
@@ -164,6 +167,7 @@
uint32_t compressed_size;
// Uncompressed size of the entry.
uint32_t uncompressed_size;
+
private:
DataDescriptor() = default;
DISALLOW_COPY_AND_ASSIGN(DataDescriptor);
diff --git a/libziparchive/zip_archive_private.h b/libziparchive/zip_archive_private.h
index de93ecd..840f1af 100644
--- a/libziparchive/zip_archive_private.h
+++ b/libziparchive/zip_archive_private.h
@@ -92,21 +92,17 @@
class MappedZipFile {
public:
- explicit MappedZipFile(const int fd) :
- has_fd_(true),
- fd_(fd),
- base_ptr_(nullptr),
- data_length_(0),
- read_pos_(0) {}
+ explicit MappedZipFile(const int fd)
+ : has_fd_(true), fd_(fd), base_ptr_(nullptr), data_length_(0), read_pos_(0) {}
- explicit MappedZipFile(void* address, size_t length) :
- has_fd_(false),
- fd_(-1),
- base_ptr_(address),
- data_length_(static_cast<off64_t>(length)),
- read_pos_(0) {}
+ explicit MappedZipFile(void* address, size_t length)
+ : has_fd_(false),
+ fd_(-1),
+ base_ptr_(address),
+ data_length_(static_cast<off64_t>(length)),
+ read_pos_(0) {}
- bool HasFd() const {return has_fd_;}
+ bool HasFd() const { return has_fd_; }
int GetFileDescriptor() const;
@@ -137,13 +133,11 @@
class CentralDirectory {
public:
- CentralDirectory(void) :
- base_ptr_(nullptr),
- length_(0) {}
+ CentralDirectory(void) : base_ptr_(nullptr), length_(0) {}
- const uint8_t* GetBasePtr() const {return base_ptr_;}
+ const uint8_t* GetBasePtr() const { return base_ptr_; }
- size_t GetMapLength() const {return length_;}
+ size_t GetMapLength() const { return length_; }
void Initialize(void* map_base_ptr, off64_t cd_start_offset, size_t cd_size);
@@ -172,25 +166,25 @@
uint32_t hash_table_size;
ZipString* hash_table;
- ZipArchive(const int fd, bool assume_ownership) :
- mapped_zip(fd),
- close_file(assume_ownership),
- directory_offset(0),
- central_directory(),
- directory_map(new android::FileMap()),
- num_entries(0),
- hash_table_size(0),
- hash_table(nullptr) {}
+ ZipArchive(const int fd, bool assume_ownership)
+ : mapped_zip(fd),
+ close_file(assume_ownership),
+ directory_offset(0),
+ central_directory(),
+ directory_map(new android::FileMap()),
+ num_entries(0),
+ hash_table_size(0),
+ hash_table(nullptr) {}
- ZipArchive(void* address, size_t length) :
- mapped_zip(address, length),
- close_file(false),
- directory_offset(0),
- central_directory(),
- directory_map(new android::FileMap()),
- num_entries(0),
- hash_table_size(0),
- hash_table(nullptr) {}
+ ZipArchive(void* address, size_t length)
+ : mapped_zip(address, length),
+ close_file(false),
+ directory_offset(0),
+ central_directory(),
+ directory_map(new android::FileMap()),
+ num_entries(0),
+ hash_table_size(0),
+ hash_table(nullptr) {}
~ZipArchive() {
if (close_file && mapped_zip.GetFileDescriptor() >= 0) {
@@ -202,7 +196,6 @@
bool InitializeCentralDirectory(const char* debug_file_name, off64_t cd_start_offset,
size_t cd_size);
-
};
#endif // LIBZIPARCHIVE_ZIPARCHIVE_PRIVATE_H_
diff --git a/libziparchive/zip_archive_stream_entry.cc b/libziparchive/zip_archive_stream_entry.cc
index 3f336a6..50352ef 100644
--- a/libziparchive/zip_archive_stream_entry.cc
+++ b/libziparchive/zip_archive_stream_entry.cc
@@ -162,8 +162,7 @@
int zerr = zlib_inflateInit2(&z_stream_, -MAX_WBITS);
if (zerr != Z_OK) {
if (zerr == Z_VERSION_ERROR) {
- ALOGE("Installed zlib is not compatible with linked version (%s)",
- ZLIB_VERSION);
+ ALOGE("Installed zlib is not compatible with linked version (%s)", ZLIB_VERSION);
} else {
ALOGE("Call to inflateInit2 failed (zerr=%d)", zerr);
}
@@ -193,13 +192,14 @@
bool ZipArchiveStreamEntryCompressed::Verify() {
return z_stream_init_ && uncompressed_length_ == 0 && compressed_length_ == 0 &&
- crc32_ == computed_crc32_;
+ crc32_ == computed_crc32_;
}
const std::vector<uint8_t>* ZipArchiveStreamEntryCompressed::Read() {
if (z_stream_.avail_out == 0) {
z_stream_.next_out = out_.data();
- z_stream_.avail_out = out_.size();;
+ z_stream_.avail_out = out_.size();
+ ;
}
while (true) {
@@ -226,9 +226,8 @@
int zerr = inflate(&z_stream_, Z_NO_FLUSH);
if (zerr != Z_OK && zerr != Z_STREAM_END) {
- ALOGE("inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)",
- zerr, z_stream_.next_in, z_stream_.avail_in,
- z_stream_.next_out, z_stream_.avail_out);
+ ALOGE("inflate zerr=%d (nIn=%p aIn=%u nOut=%p aOut=%u)", zerr, z_stream_.next_in,
+ z_stream_.avail_in, z_stream_.next_out, z_stream_.avail_out);
return nullptr;
}
@@ -276,8 +275,8 @@
return length_ == 0;
}
-ZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(
- ZipArchiveHandle handle, const ZipEntry& entry) {
+ZipArchiveStreamEntry* ZipArchiveStreamEntry::Create(ZipArchiveHandle handle,
+ const ZipEntry& entry) {
ZipArchiveStreamEntry* stream = nullptr;
if (entry.method != kCompressStored) {
stream = new ZipArchiveStreamEntryCompressed(handle);
@@ -292,8 +291,8 @@
return stream;
}
-ZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(
- ZipArchiveHandle handle, const ZipEntry& entry) {
+ZipArchiveStreamEntry* ZipArchiveStreamEntry::CreateRaw(ZipArchiveHandle handle,
+ const ZipEntry& entry) {
ZipArchiveStreamEntry* stream = nullptr;
if (entry.method == kCompressStored) {
// Not compressed, don't need to do anything special.
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index 52099c3..dbc14f0 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -40,23 +40,17 @@
static const std::string kValidZip = "valid.zip";
static const std::string kLargeZip = "large.zip";
static const std::string kBadCrcZip = "bad_crc.zip";
+static const std::string kCrashApk = "crash.apk";
+static const std::string kBadFilenameZip = "bad_filename.zip";
static const std::string kUpdateZip = "dummy-update.zip";
-static const std::vector<uint8_t> kATxtContents {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- '\n'
-};
+static const std::vector<uint8_t> kATxtContents{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'a',
+ 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\n'};
-static const std::vector<uint8_t> kATxtContentsCompressed {
- 'K', 'L', 'J', 'N', 'I', 'M', 'K', 207, 'H',
- 132, 210, '\\', '\0'
-};
+static const std::vector<uint8_t> kATxtContentsCompressed{'K', 'L', 'J', 'N', 'I', 'M', 'K',
+ 207, 'H', 132, 210, '\\', '\0'};
-static const std::vector<uint8_t> kBTxtContents {
- 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
- '\n'
-};
+static const std::vector<uint8_t> kBTxtContents{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', '\n'};
static const std::string kATxtName("a.txt");
static const std::string kBTxtName("b.txt");
@@ -65,14 +59,12 @@
static const std::string kLargeCompressTxtName("compress.txt");
static const std::string kLargeUncompressTxtName("uncompress.txt");
-static int32_t OpenArchiveWrapper(const std::string& name,
- ZipArchiveHandle* handle) {
+static int32_t OpenArchiveWrapper(const std::string& name, ZipArchiveHandle* handle) {
const std::string abs_path = test_data_dir + "/" + name;
return OpenArchive(abs_path.c_str(), handle);
}
-static void AssertNameEquals(const std::string& name_str,
- const ZipString& name) {
+static void AssertNameEquals(const std::string& name_str, const ZipString& name) {
ASSERT_EQ(name_str.size(), name.name_length);
ASSERT_EQ(0, memcmp(name_str.c_str(), name.name, name.name_length));
}
@@ -85,7 +77,15 @@
TEST(ziparchive, Open) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+ CloseArchive(handle);
+ ASSERT_EQ(-1, OpenArchiveWrapper(kBadFilenameZip, &handle));
+ CloseArchive(handle);
+}
+
+TEST(ziparchive, OutOfBound) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(-8, OpenArchiveWrapper(kCrashApk, &handle));
CloseArchive(handle);
}
@@ -335,47 +335,36 @@
}
static const uint32_t kEmptyEntriesZip[] = {
- 0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000,
- 0x00090000, 0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13,
- 0x52e25c24, 0x000b7875, 0x42890401, 0x88040000, 0x50000013, 0x1e02014b,
- 0x00000a03, 0x60000000, 0x00443863, 0x00000000, 0x00000000, 0x09000000,
- 0x00001800, 0x00000000, 0xa0000000, 0x00000081, 0x706d6500, 0x742e7974,
- 0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904, 0x13880400,
- 0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000 };
+ 0x04034b50, 0x0000000a, 0x63600000, 0x00004438, 0x00000000, 0x00000000, 0x00090000,
+ 0x6d65001c, 0x2e797470, 0x55747874, 0x03000954, 0x52e25c13, 0x52e25c24, 0x000b7875,
+ 0x42890401, 0x88040000, 0x50000013, 0x1e02014b, 0x00000a03, 0x60000000, 0x00443863,
+ 0x00000000, 0x00000000, 0x09000000, 0x00001800, 0x00000000, 0xa0000000, 0x00000081,
+ 0x706d6500, 0x742e7974, 0x54557478, 0x13030005, 0x7552e25c, 0x01000b78, 0x00428904,
+ 0x13880400, 0x4b500000, 0x00000605, 0x00010000, 0x004f0001, 0x00430000, 0x00000000};
// This is a zip file containing a single entry (ab.txt) that contains
// 90072 repetitions of the string "ab\n" and has an uncompressed length
// of 270216 bytes.
static const uint16_t kAbZip[] = {
- 0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0,
- 0x2cda, 0x011b, 0x0000, 0x1f88, 0x0004, 0x0006, 0x001c, 0x6261,
- 0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,
- 0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000,
- 0xc2ed, 0x0d31, 0x0000, 0x030c, 0x7fa0, 0x3b2e, 0x22ff, 0xa2aa,
- 0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
- 0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02,
- 0x1403, 0x0000, 0x0800, 0xd200, 0x9851, 0xb046, 0xdac4, 0x1b2c,
- 0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,
- 0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574,
- 0x0554, 0x0300, 0x097c, 0x553a, 0x7875, 0x000b, 0x0401, 0x4289,
- 0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,
- 0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000
-};
+ 0x4b50, 0x0403, 0x0014, 0x0000, 0x0008, 0x51d2, 0x4698, 0xc4b0, 0x2cda, 0x011b, 0x0000, 0x1f88,
+ 0x0004, 0x0006, 0x001c, 0x6261, 0x742e, 0x7478, 0x5455, 0x0009, 0x7c03, 0x3a09, 0x7c55, 0x3a09,
+ 0x7555, 0x0b78, 0x0100, 0x8904, 0x0042, 0x0400, 0x1388, 0x0000, 0xc2ed, 0x0d31, 0x0000, 0x030c,
+ 0x7fa0, 0x3b2e, 0x22ff, 0xa2aa, 0x841f, 0x45fc, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555, 0x5555,
+ 0x5555, 0x5555, 0x5555, 0x5555, 0xdd55, 0x502c, 0x014b, 0x1e02, 0x1403, 0x0000, 0x0800, 0xd200,
+ 0x9851, 0xb046, 0xdac4, 0x1b2c, 0x0001, 0x8800, 0x041f, 0x0600, 0x1800, 0x0000, 0x0000, 0x0100,
+ 0x0000, 0xa000, 0x0081, 0x0000, 0x6100, 0x2e62, 0x7874, 0x5574, 0x0554, 0x0300, 0x097c, 0x553a,
+ 0x7875, 0x000b, 0x0401, 0x4289, 0x0000, 0x8804, 0x0013, 0x5000, 0x054b, 0x0006, 0x0000, 0x0100,
+ 0x0100, 0x4c00, 0x0000, 0x5b00, 0x0001, 0x0000, 0x0000};
static const std::string kAbTxtName("ab.txt");
static const size_t kAbUncompressedSize = 270216;
@@ -396,7 +385,6 @@
uint8_t buffer[1];
ASSERT_EQ(0, ExtractToMemory(handle, &entry, buffer, 1));
-
TemporaryFile tmp_output_file;
ASSERT_NE(-1, tmp_output_file.fd);
ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_output_file.fd));
@@ -410,7 +398,7 @@
TemporaryFile tmp_file;
ASSERT_NE(-1, tmp_file.fd);
ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, reinterpret_cast<const uint8_t*>(kAbZip),
- sizeof(kAbZip) - 1));
+ sizeof(kAbZip) - 1));
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveFd(tmp_file.fd, "EntryLargerThan32KTest", &handle));
@@ -438,8 +426,7 @@
// the same as the memory buffer we extracted directly to.
std::vector<uint8_t> file_contents(kAbUncompressedSize);
ASSERT_EQ(0, lseek64(tmp_output_file.fd, 0, SEEK_SET));
- ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0],
- file_contents.size()));
+ ASSERT_TRUE(android::base::ReadFully(tmp_output_file.fd, &file_contents[0], file_contents.size()));
ASSERT_EQ(file_contents, buffer);
for (int i = 0; i < 90072; ++i) {
@@ -455,7 +442,7 @@
ASSERT_NE(-1, tmp_file.fd);
// Create a file with 8 bytes of random garbage.
- static const uint8_t trailer[] = { 'A' ,'n', 'd', 'r', 'o', 'i', 'd', 'z' };
+ static const uint8_t trailer[] = {'A', 'n', 'd', 'r', 'o', 'i', 'd', 'z'};
ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, kEmptyEntriesZip, sizeof(kEmptyEntriesZip)));
ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, trailer, sizeof(trailer)));
@@ -466,7 +453,7 @@
TEST(ziparchive, ExtractToFile) {
TemporaryFile tmp_file;
ASSERT_NE(-1, tmp_file.fd);
- const uint8_t data[8] = { '1', '2', '3', '4', '5', '6', '7', '8' };
+ const uint8_t data[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
const size_t data_size = sizeof(data);
ASSERT_TRUE(android::base::WriteFully(tmp_file.fd, data, data_size));
@@ -480,7 +467,6 @@
ASSERT_EQ(0, FindEntry(handle, name, &entry));
ASSERT_EQ(0, ExtractEntryToFile(handle, &entry, tmp_file.fd));
-
// Assert that the first 8 bytes of the file haven't been clobbered.
uint8_t read_buffer[data_size];
ASSERT_EQ(0, lseek64(tmp_file.fd, 0, SEEK_SET));
@@ -489,10 +475,9 @@
// Assert that the remainder of the file contains the incompressed data.
std::vector<uint8_t> uncompressed_data(entry.uncompressed_length);
- ASSERT_TRUE(android::base::ReadFully(tmp_file.fd, uncompressed_data.data(),
- entry.uncompressed_length));
- ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(),
- kATxtContents.size()));
+ ASSERT_TRUE(
+ android::base::ReadFully(tmp_file.fd, uncompressed_data.data(), entry.uncompressed_length));
+ ASSERT_EQ(0, memcmp(&uncompressed_data[0], kATxtContents.data(), kATxtContents.size()));
// Assert that the total length of the file is sane
ASSERT_EQ(static_cast<ssize_t>(data_size + kATxtContents.size()),
@@ -509,7 +494,7 @@
// Memory map the file first and open the archive from the memory region.
android::FileMap file_map;
- file_map.create(zip_path.c_str(), fd, 0/*offset*/, sb.st_size, true);
+ file_map.create(zip_path.c_str(), fd, 0 /*offset*/, sb.st_size, true);
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveFromMemory(file_map.getDataPtr(), file_map.getDataLength(),
zip_path.c_str(), &handle));
@@ -525,9 +510,8 @@
}
#endif
-static void ZipArchiveStreamTest(
- ZipArchiveHandle& handle, const std::string& entry_name, bool raw,
- bool verified, ZipEntry* entry, std::vector<uint8_t>* read_data) {
+static void ZipArchiveStreamTest(ZipArchiveHandle& handle, const std::string& entry_name, bool raw,
+ bool verified, ZipEntry* entry, std::vector<uint8_t>* read_data) {
ZipString name;
SetZipString(&name, entry_name);
ASSERT_EQ(0, FindEntry(handle, name, entry));
@@ -556,9 +540,9 @@
ASSERT_EQ(total_size, read_data->size());
}
-static void ZipArchiveStreamTestUsingContents(
- const std::string& zip_file, const std::string& entry_name,
- const std::vector<uint8_t>& contents, bool raw) {
+static void ZipArchiveStreamTestUsingContents(const std::string& zip_file,
+ const std::string& entry_name,
+ const std::vector<uint8_t>& contents, bool raw) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));
@@ -572,7 +556,8 @@
CloseArchive(handle);
}
-static void ZipArchiveStreamTestUsingMemory(const std::string& zip_file, const std::string& entry_name) {
+static void ZipArchiveStreamTestUsingMemory(const std::string& zip_file,
+ const std::string& entry_name) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(zip_file, &handle));
@@ -735,10 +720,8 @@
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
- static struct option options[] = {
- { "test_data_dir", required_argument, nullptr, 't' },
- { nullptr, 0, nullptr, 0 }
- };
+ static struct option options[] = {{"test_data_dir", required_argument, nullptr, 't'},
+ {nullptr, 0, nullptr, 0}};
while (true) {
int option_index;
diff --git a/libziparchive/zip_writer.cc b/libziparchive/zip_writer.cc
index 6d28bdb..6ad3366 100644
--- a/libziparchive/zip_writer.cc
+++ b/libziparchive/zip_writer.cc
@@ -16,11 +16,11 @@
#include "ziparchive/zip_writer.h"
-#include <cstdio>
#include <sys/param.h>
#include <sys/stat.h>
#include <zlib.h>
-#define DEF_MEM_LEVEL 8 // normally in zutil.h?
+#include <cstdio>
+#define DEF_MEM_LEVEL 8 // normally in zutil.h?
#include <memory>
#include <vector>
@@ -33,13 +33,13 @@
#include "zip_archive_common.h"
#if !defined(powerof2)
-#define powerof2(x) ((((x)-1)&(x))==0)
+#define powerof2(x) ((((x)-1) & (x)) == 0)
#endif
/* Zip compression methods we support */
enum {
- kCompressStored = 0, // no compression
- kCompressDeflated = 8, // standard deflate
+ kCompressStored = 0, // no compression
+ kCompressDeflated = 8, // standard deflate
};
// Size of the output buffer used for compression.
@@ -67,10 +67,7 @@
static const int32_t kInvalidAlignment = -6;
static const char* sErrorCodes[] = {
- "Invalid state",
- "IO error",
- "Invalid entry name",
- "Zlib error",
+ "Invalid state", "IO error", "Invalid entry name", "Zlib error",
};
const char* ZipWriter::ErrorCodeString(int32_t error_code) {
@@ -85,9 +82,13 @@
delete stream;
}
-ZipWriter::ZipWriter(FILE* f) : file_(f), seekable_(false), current_offset_(0),
- state_(State::kWritingZip), z_stream_(nullptr, DeleteZStream),
- buffer_(kBufSize) {
+ZipWriter::ZipWriter(FILE* f)
+ : file_(f),
+ seekable_(false),
+ current_offset_(0),
+ state_(State::kWritingZip),
+ z_stream_(nullptr, DeleteZStream),
+ buffer_(kBufSize) {
// Check if the file is seekable (regular file). If fstat fails, that's fine, subsequent calls
// will fail as well.
struct stat file_stats;
@@ -96,13 +97,14 @@
}
}
-ZipWriter::ZipWriter(ZipWriter&& writer) : file_(writer.file_),
- seekable_(writer.seekable_),
- current_offset_(writer.current_offset_),
- state_(writer.state_),
- files_(std::move(writer.files_)),
- z_stream_(std::move(writer.z_stream_)),
- buffer_(std::move(writer.buffer_)){
+ZipWriter::ZipWriter(ZipWriter&& writer)
+ : file_(writer.file_),
+ seekable_(writer.seekable_),
+ current_offset_(writer.current_offset_),
+ state_(writer.state_),
+ files_(std::move(writer.files_)),
+ z_stream_(std::move(writer.z_stream_)),
+ buffer_(std::move(writer.buffer_)) {
writer.file_ = nullptr;
writer.state_ = State::kError;
}
@@ -154,10 +156,10 @@
struct tm* ptm;
#if !defined(_WIN32)
- struct tm tm_result;
- ptm = localtime_r(&when, &tm_result);
+ struct tm tm_result;
+ ptm = localtime_r(&when, &tm_result);
#else
- ptm = localtime(&when);
+ ptm = localtime(&when);
#endif
int year = ptm->tm_year;
@@ -193,8 +195,8 @@
dst->extra_field_length = src.padding_length;
}
-int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags,
- time_t time, uint32_t alignment) {
+int32_t ZipWriter::StartAlignedEntryWithTime(const char* path, size_t flags, time_t time,
+ uint32_t alignment) {
if (state_ != State::kWritingZip) {
return kInvalidState;
}
@@ -252,9 +254,8 @@
return HandleError(kIoError);
}
- if (file_entry.padding_length != 0 &&
- fwrite(zero_padding.data(), 1, file_entry.padding_length, file_)
- != file_entry.padding_length) {
+ if (file_entry.padding_length != 0 && fwrite(zero_padding.data(), 1, file_entry.padding_length,
+ file_) != file_entry.padding_length) {
return HandleError(kIoError);
}
@@ -292,7 +293,7 @@
CHECK(state_ == State::kWritingZip);
// Initialize the z_stream for compression.
- z_stream_ = std::unique_ptr<z_stream, void(*)(z_stream*)>(new z_stream(), DeleteZStream);
+ z_stream_ = std::unique_ptr<z_stream, void (*)(z_stream*)>(new z_stream(), DeleteZStream);
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wold-style-cast"
@@ -331,8 +332,8 @@
return result;
}
- current_file_entry_.crc32 = crc32(current_file_entry_.crc32,
- reinterpret_cast<const Bytef*>(data), len);
+ current_file_entry_.crc32 =
+ crc32(current_file_entry_.crc32, reinterpret_cast<const Bytef*>(data), len);
current_file_entry_.uncompressed_size += len;
return kNoError;
}
diff --git a/libziparchive/zip_writer_test.cc b/libziparchive/zip_writer_test.cc
index 9ad0252..c284273 100644
--- a/libziparchive/zip_writer_test.cc
+++ b/libziparchive/zip_writer_test.cc
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#include "ziparchive/zip_archive.h"
#include "ziparchive/zip_writer.h"
+#include "ziparchive/zip_archive.h"
#include <android-base/test_utils.h>
#include <gtest/gtest.h>
@@ -361,7 +361,7 @@
ASSERT_EQ(0, writer.StartEntry("large.txt", 0));
std::vector<uint8_t> data;
- data.resize(1024*1024, 0xef);
+ data.resize(1024 * 1024, 0xef);
ASSERT_EQ(0, writer.WriteBytes(data.data(), data.size()));
ASSERT_EQ(0, writer.FinishEntry());
@@ -382,8 +382,9 @@
ZipArchiveHandle handle,
ZipEntry* zip_entry) {
if (expected.size() != zip_entry->uncompressed_length) {
- return ::testing::AssertionFailure() << "uncompressed entry size "
- << zip_entry->uncompressed_length << " does not match expected size " << expected.size();
+ return ::testing::AssertionFailure()
+ << "uncompressed entry size " << zip_entry->uncompressed_length
+ << " does not match expected size " << expected.size();
}
std::string actual;
@@ -396,7 +397,7 @@
if (expected != actual) {
return ::testing::AssertionFailure() << "actual zip_entry data '" << actual
- << "' does not match expected '" << expected << "'";
+ << "' does not match expected '" << expected << "'";
}
return ::testing::AssertionSuccess();
}
diff --git a/logd/Android.bp b/logd/Android.bp
new file mode 100644
index 0000000..68b79d3
--- /dev/null
+++ b/logd/Android.bp
@@ -0,0 +1,78 @@
+// Copyright (C) 2017 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// This is what we want to do:
+// event_logtags = $(shell
+// sed -n
+// "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p"
+// $(LOCAL_PATH)/$2/event.logtags)
+// event_flag := $(call event_logtags,auditd)
+// event_flag += $(call event_logtags,logd)
+// event_flag += $(call event_logtags,tag_def)
+// so make sure we do not regret hard-coding it as follows:
+event_flag = [
+ "-DAUDITD_LOG_TAG=1003",
+ "-DCHATTY_LOG_TAG=1004",
+ "-DTAG_DEF_LOG_TAG=1005",
+ "-DLIBLOG_LOG_TAG=1006"
+]
+
+cc_library_static {
+ name: "liblogd",
+
+ srcs: [
+ "LogCommand.cpp",
+ "CommandListener.cpp",
+ "LogListener.cpp",
+ "LogReader.cpp",
+ "FlushCommand.cpp",
+ "LogBuffer.cpp",
+ "LogBufferElement.cpp",
+ "LogBufferInterface.cpp",
+ "LogTimes.cpp",
+ "LogStatistics.cpp",
+ "LogWhiteBlackList.cpp",
+ "libaudit.c",
+ "LogAudit.cpp",
+ "LogKlog.cpp",
+ "LogTags.cpp",
+ ],
+ logtags: ["event.logtags"],
+
+ shared_libs: ["libbase"],
+
+ export_include_dirs: ["."],
+
+ cflags: ["-Werror"] + event_flag,
+}
+
+cc_binary {
+ name: "logd",
+ init_rc: ["logd.rc"],
+
+ srcs: ["main.cpp"],
+
+ static_libs: ["liblogd"],
+
+ shared_libs: [
+ "libsysutils",
+ "liblog",
+ "libcutils",
+ "libbase",
+ "libpackagelistparser",
+ "libcap",
+ ],
+
+ cflags: ["-Werror"],
+}
diff --git a/logd/Android.mk b/logd/Android.mk
index fb51992..1bca891 100644
--- a/logd/Android.mk
+++ b/logd/Android.mk
@@ -2,73 +2,6 @@
include $(CLEAR_VARS)
-LOCAL_MODULE:= liblogd
-
-LOCAL_SRC_FILES := \
- LogCommand.cpp \
- CommandListener.cpp \
- LogListener.cpp \
- LogReader.cpp \
- FlushCommand.cpp \
- LogBuffer.cpp \
- LogBufferElement.cpp \
- LogBufferInterface.cpp \
- LogTimes.cpp \
- LogStatistics.cpp \
- LogWhiteBlackList.cpp \
- libaudit.c \
- LogAudit.cpp \
- LogKlog.cpp \
- LogTags.cpp \
- event.logtags
-
-LOCAL_SHARED_LIBRARIES := \
- libbase
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-
-# This is what we want to do:
-# event_logtags = $(shell \
-# sed -n \
-# "s/^\([0-9]*\)[ \t]*$1[ \t].*/-D`echo $1 | tr a-z A-Z`_LOG_TAG=\1/p" \
-# $(LOCAL_PATH)/$2/event.logtags)
-# event_flag := $(call event_logtags,auditd)
-# event_flag += $(call event_logtags,logd)
-# event_flag += $(call event_logtags,tag_def)
-# so make sure we do not regret hard-coding it as follows:
-event_flag := -DAUDITD_LOG_TAG=1003 -DCHATTY_LOG_TAG=1004 -DTAG_DEF_LOG_TAG=1005
-event_flag += -DLIBLOG_LOG_TAG=1006
-
-LOCAL_CFLAGS := -Werror $(event_flag)
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_MODULE:= logd
-
-LOCAL_INIT_RC := logd.rc
-
-LOCAL_SRC_FILES := \
- main.cpp
-
-LOCAL_STATIC_LIBRARIES := \
- liblogd
-
-LOCAL_SHARED_LIBRARIES := \
- libsysutils \
- liblog \
- libcutils \
- libbase \
- libpackagelistparser \
- libcap
-
-LOCAL_CFLAGS := -Werror
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
LOCAL_MODULE := logtagd.rc
LOCAL_SRC_FILES := $(LOCAL_MODULE)
LOCAL_MODULE_CLASS := ETC
diff --git a/rootdir/init.rc b/rootdir/init.rc
index d9fe090..ebbec35 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -36,6 +36,8 @@
mount cgroup none /dev/memcg memory
# app mem cgroups, used by activity manager, lmkd and zygote
mkdir /dev/memcg/apps/ 0755 system system
+ # cgroup for system_server and surfaceflinger
+ mkdir /dev/memcg/system 0755 system system
start ueventd