From d2babc4d5af615babbbf422e5894f1a9e4557ed2 Mon Sep 17 00:00:00 2001 From: Doug Zongker Date: Thu, 2 Aug 2012 14:50:24 -0700 Subject: [PATCH 01/10] add command-line arguments to mkbootimg to move kernel, ramdisk, etc. Bug: 6918260 Change-Id: I5d4af6314fded027952941110a520dc9aa234a14 --- mkbootimg/mkbootimg.c | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/mkbootimg/mkbootimg.c b/mkbootimg/mkbootimg.c index d72e3176c..2c32ce35b 100644 --- a/mkbootimg/mkbootimg.c +++ b/mkbootimg/mkbootimg.c @@ -109,18 +109,17 @@ int main(int argc, char **argv) int fd; SHA_CTX ctx; uint8_t* sha; + unsigned base = 0x10000000; + unsigned kernel_offset = 0x00008000; + unsigned ramdisk_offset = 0x01000000; + unsigned second_offset = 0x00f00000; + unsigned tags_offset = 0x00000100; argc--; argv++; memset(&hdr, 0, sizeof(hdr)); - /* default load addresses */ - hdr.kernel_addr = 0x10008000; - hdr.ramdisk_addr = 0x11000000; - hdr.second_addr = 0x10F00000; - hdr.tags_addr = 0x10000100; - while(argc > 0){ char *arg = argv[0]; char *val = argv[1]; @@ -140,11 +139,15 @@ int main(int argc, char **argv) } else if(!strcmp(arg, "--cmdline")) { cmdline = val; } else if(!strcmp(arg, "--base")) { - unsigned base = strtoul(val, 0, 16); - hdr.kernel_addr = base + 0x00008000; - hdr.ramdisk_addr = base + 0x01300000; - hdr.second_addr = base + 0x00F00000; - hdr.tags_addr = base + 0x00000100; + base = strtoul(val, 0, 16); + } else if(!strcmp(arg, "--kernel_offset")) { + kernel_offset = strtoul(val, 0, 16); + } else if(!strcmp(arg, "--ramdisk_offset")) { + ramdisk_offset = strtoul(val, 0, 16); + } else if(!strcmp(arg, "--second_offset")) { + second_offset = strtoul(val, 0, 16); + } else if(!strcmp(arg, "--tags_offset")) { + tags_offset = strtoul(val, 0, 16); } else if(!strcmp(arg, "--board")) { board = val; } else if(!strcmp(arg,"--pagesize")) { @@ -159,6 +162,10 @@ int main(int argc, char **argv) } hdr.page_size = pagesize; + hdr.kernel_addr = base + kernel_offset; + hdr.ramdisk_addr = base + ramdisk_offset; + hdr.second_addr = base + second_offset; + hdr.tags_addr = base + tags_offset; if(bootimg == 0) { fprintf(stderr,"error: no output filename specified\n"); From 81b1996827941070851fbbae04fcef24f371843b Mon Sep 17 00:00:00 2001 From: Jeonghoon lim Date: Tue, 14 Aug 2012 18:12:33 -0700 Subject: [PATCH 02/10] bluetooth: bring up with bluedroid stack - change permission of "bluetooth." property to AID_BLUETOOTH Change-Id: Ifcd97f136cfc3372412fe500e4f800d1bbbd065c --- init/property_service.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/property_service.c b/init/property_service.c index 5eb0a8ac1..c378aeb38 100755 --- a/init/property_service.c +++ b/init/property_service.c @@ -81,7 +81,7 @@ struct { { "sys.", AID_SYSTEM, 0 }, { "service.", AID_SYSTEM, 0 }, { "wlan.", AID_SYSTEM, 0 }, - { "bluetooth.", AID_SYSTEM, 0 }, + { "bluetooth.", AID_BLUETOOTH, 0 }, { "dhcp.", AID_SYSTEM, 0 }, { "dhcp.", AID_DHCP, 0 }, { "debug.", AID_SYSTEM, 0 }, From 5e3d90c8bea40874ecfe950136029f093ab17824 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Wed, 22 Aug 2012 12:10:19 -0700 Subject: [PATCH 03/10] Revert "Upgrade to dlmalloc 2.8.5." This reverts commit 2d13791ce7ff61221ca047553891f31a23b2e943. --- include/cutils/mspace.h | 128 ++++++++++ libcutils/Android.mk | 1 + libcutils/dlmalloc_stubs.c | 20 +- libcutils/mspace.c | 286 ++++++++++++++++++++++ libpixelflinger/codeflinger/CodeCache.cpp | 89 ++----- libpixelflinger/codeflinger/CodeCache.h | 4 + 6 files changed, 448 insertions(+), 80 deletions(-) create mode 100644 include/cutils/mspace.h create mode 100644 libcutils/mspace.c diff --git a/include/cutils/mspace.h b/include/cutils/mspace.h new file mode 100644 index 000000000..93fe48eed --- /dev/null +++ b/include/cutils/mspace.h @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2006 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. + */ + +/* A wrapper file for dlmalloc.h that defines prototypes for the + * mspace_*() functions, which provide an interface for creating + * multiple heaps. + */ + +#ifndef MSPACE_H_ +#define MSPACE_H_ + +/* It's a pain getting the mallinfo stuff to work + * with Linux, OSX, and klibc, so just turn it off + * for now. + * TODO: make mallinfo work + */ +#define NO_MALLINFO 1 + +/* Allow setting the maximum heap footprint. + */ +#define USE_MAX_ALLOWED_FOOTPRINT 1 + +#define USE_CONTIGUOUS_MSPACES 1 +#if USE_CONTIGUOUS_MSPACES +#define HAVE_MMAP 0 +#define HAVE_MORECORE 1 +#define MORECORE_CONTIGUOUS 0 +#endif + +#define MSPACES 1 +#define ONLY_MSPACES 1 +#include "../../../../bionic/libc/bionic/dlmalloc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* + mspace_usable_size(void* p); + + Returns the number of bytes you can actually use in + an allocated chunk, which may be more than you requested (although + often not) due to alignment and minimum size constraints. + You can use this many bytes without worrying about + overwriting other allocated objects. This is not a particularly great + programming practice. mspace_usable_size can be more useful in + debugging and assertions, for example: + + p = mspace_malloc(msp, n); + assert(mspace_usable_size(msp, p) >= 256); +*/ +size_t mspace_usable_size(mspace, const void*); + +#if USE_CONTIGUOUS_MSPACES +/* + Similar to create_mspace(), but the underlying memory is + guaranteed to be contiguous. No more than max_capacity + bytes is ever allocated to the mspace. + */ +mspace create_contiguous_mspace(size_t starting_capacity, size_t max_capacity, + int locked); + +/* + Identical to create_contiguous_mspace, but labels the mapping 'mspace/name' + instead of 'mspace' +*/ +mspace create_contiguous_mspace_with_name(size_t starting_capacity, + size_t max_capacity, int locked, const char *name); + +/* + Identical to create_contiguous_mspace, but uses previously mapped memory. +*/ +mspace create_contiguous_mspace_with_base(size_t starting_capacity, + size_t max_capacity, int locked, void *base); + +size_t destroy_contiguous_mspace(mspace msp); + +/* + Returns the position of the "break" within the given mspace. +*/ +void *contiguous_mspace_sbrk0(mspace msp); +#endif + +/* + Call the handler for each block in the specified mspace. + chunkptr and chunklen refer to the heap-level chunk including + the chunk overhead, and userptr and userlen refer to the + user-usable part of the chunk. If the chunk is free, userptr + will be NULL and userlen will be 0. userlen is not guaranteed + to be the same value passed into malloc() for a given chunk; + it is >= the requested size. + */ +void mspace_walk_heap(mspace msp, + void(*handler)(const void *chunkptr, size_t chunklen, + const void *userptr, size_t userlen, void *arg), void *harg); + +/* + mspace_walk_free_pages(handler, harg) + + Calls the provided handler on each free region in the specified + mspace. The memory between start and end are guaranteed not to + contain any important data, so the handler is free to alter the + contents in any way. This can be used to advise the OS that large + free regions may be swapped out. + + The value in harg will be passed to each call of the handler. + */ +void mspace_walk_free_pages(mspace msp, + void(*handler)(void *start, void *end, void *arg), void *harg); + +#ifdef __cplusplus +}; /* end of extern "C" */ +#endif + +#endif /* MSPACE_H_ */ diff --git a/libcutils/Android.mk b/libcutils/Android.mk index 9c48ad27b..78bae8a6f 100644 --- a/libcutils/Android.mk +++ b/libcutils/Android.mk @@ -75,6 +75,7 @@ ifeq ($(WINDOWS_HOST_ONLY),1) else commonSources += \ abort_socket.c \ + mspace.c \ selector.c \ tztime.c \ multiuser.c \ diff --git a/libcutils/dlmalloc_stubs.c b/libcutils/dlmalloc_stubs.c index c327a55a7..1ced147b8 100644 --- a/libcutils/dlmalloc_stubs.c +++ b/libcutils/dlmalloc_stubs.c @@ -14,22 +14,16 @@ * limitations under the License. */ -#include "../../../bionic/libc/bionic/dlmalloc.h" -#include "cutils/log.h" - -/* - * Stubs for functions defined in bionic/libc/bionic/dlmalloc.c. These - * are used in host builds, as the host libc will not contain these - * functions. +/* No-op stubs for functions defined in system/bionic/bionic/dlmalloc.c. */ -void dlmalloc_inspect_all(void(*handler)(void*, void *, size_t, void*), - void* arg) +void dlmalloc_walk_free_pages() { - ALOGW("Called host unimplemented stub: dlmalloc_inspect_all"); } -int dlmalloc_trim(size_t unused) +void dlmalloc_walk_heap() +{ +} + +void dlmalloc_trim() { - ALOGW("Called host unimplemented stub: dlmalloc_trim"); - return 0; } diff --git a/libcutils/mspace.c b/libcutils/mspace.c new file mode 100644 index 000000000..6d3b35c84 --- /dev/null +++ b/libcutils/mspace.c @@ -0,0 +1,286 @@ +/* Copyright 2006 The Android Open Source Project */ + +/* A wrapper file for dlmalloc.c that compiles in the + * mspace_*() functions, which provide an interface for + * creating multiple heaps. + */ +#include +#include +#include +#include +#include +#include + +#include + +/* It's a pain getting the mallinfo stuff to work + * with Linux, OSX, and klibc, so just turn it off + * for now. + * TODO: make mallinfo work + */ +#define NO_MALLINFO 1 + +/* Allow setting the maximum heap footprint. + */ +#define USE_MAX_ALLOWED_FOOTPRINT 1 + +/* Don't try to trim memory. + * TODO: support this. + */ +#define MORECORE_CANNOT_TRIM 1 + +/* Use mmap()d anonymous memory to guarantee + * that an mspace is contiguous. + * + * create_mspace() won't work right if this is + * defined, so hide the definition of it and + * break any users at build time. + */ +#define USE_CONTIGUOUS_MSPACES 1 +#if USE_CONTIGUOUS_MSPACES +/* This combination of settings forces sys_alloc() + * to always use MORECORE(). It won't expect the + * results to be contiguous, but we'll guarantee + * that they are. + */ +#define HAVE_MMAP 0 +#define HAVE_MORECORE 1 +#define MORECORE_CONTIGUOUS 0 +/* m is always the appropriate local when MORECORE() is called. */ +#define MORECORE(S) contiguous_mspace_morecore(m, S) +#define create_mspace HIDDEN_create_mspace_HIDDEN +#define destroy_mspace HIDDEN_destroy_mspace_HIDDEN +typedef struct malloc_state *mstate0; +static void *contiguous_mspace_morecore(mstate0 m, ssize_t nb); +#endif + +#define MSPACES 1 +#define ONLY_MSPACES 1 +#include "../../../bionic/libc/bionic/dlmalloc.c" + +#ifndef PAGESIZE +#define PAGESIZE mparams.page_size +#endif + +#define ALIGN_UP(p, alignment) \ + (((uintptr_t)(p) + (alignment)-1) & ~((alignment)-1)) + +/* A direct copy of dlmalloc_usable_size(), + * which isn't compiled in when ONLY_MSPACES is set. + * The mspace parameter isn't actually necessary, + * but we include it to be consistent with the + * rest of the mspace_*() functions. + */ +size_t mspace_usable_size(mspace _unused, const void* mem) { + if (mem != 0) { + const mchunkptr p = mem2chunk(mem); + if (cinuse(p)) + return chunksize(p) - overhead_for(p); + } + return 0; +} + +#if USE_CONTIGUOUS_MSPACES +#include +#include + +#define CONTIG_STATE_MAGIC 0xf00dd00d +struct mspace_contig_state { + unsigned int magic; + char *brk; + char *top; + mspace m; +}; + +static void *contiguous_mspace_morecore(mstate m, ssize_t nb) { + struct mspace_contig_state *cs; + char *oldbrk; + const unsigned int pagesize = PAGESIZE; + + cs = (struct mspace_contig_state *)((uintptr_t)m & ~(pagesize-1)); + assert(cs->magic == CONTIG_STATE_MAGIC); + assert(cs->m == m); +assert(nb >= 0); //xxx deal with the trim case + + oldbrk = cs->brk; + if (nb > 0) { + /* Break to the first page boundary that satisfies the request. + */ + char *newbrk = (char *)ALIGN_UP(oldbrk + nb, pagesize); + if (newbrk > cs->top) + return CMFAIL; + + /* Update the protection on the underlying memory. + * Pages we've given to dlmalloc are read/write, and + * pages we haven't are not accessable (read or write + * will cause a seg fault). + */ + if (mprotect(cs, newbrk - (char *)cs, PROT_READ | PROT_WRITE) < 0) + return CMFAIL; + if (newbrk != cs->top) { + if (mprotect(newbrk, cs->top - newbrk, PROT_NONE) < 0) + return CMFAIL; + } + + cs->brk = newbrk; + + /* Make sure that dlmalloc will merge this block with the + * initial block that was passed to create_mspace_with_base(). + * We don't care about extern vs. non-extern, so just clear it. + */ + m->seg.sflags &= ~EXTERN_BIT; + } + + return oldbrk; +} + +mspace create_contiguous_mspace_with_base(size_t starting_capacity, + size_t max_capacity, int locked, void *base) { + struct mspace_contig_state *cs; + unsigned int pagesize; + mstate m; + + init_mparams(); + pagesize = PAGESIZE; + assert(starting_capacity <= max_capacity); + assert(((uintptr_t)base & (pagesize-1)) == 0); + assert(((uintptr_t)max_capacity & (pagesize-1)) == 0); + starting_capacity = (size_t)ALIGN_UP(starting_capacity, pagesize); + + /* Make the first page read/write. dlmalloc needs to use that page. + */ + if (mprotect(base, starting_capacity, PROT_READ | PROT_WRITE) < 0) { + goto error; + } + + /* Create the mspace, pointing to the memory given. + */ + m = create_mspace_with_base((char *)base + sizeof(*cs), starting_capacity, + locked); + if (m == (mspace)0) { + goto error; + } + /* Make sure that m is in the same page as base. + */ + assert(((uintptr_t)m & (uintptr_t)~(pagesize-1)) == (uintptr_t)base); + /* Use some space for the information that our MORECORE needs. + */ + cs = (struct mspace_contig_state *)base; + + /* Find out exactly how much of the memory the mspace + * is using. + */ + cs->brk = m->seg.base + m->seg.size; + cs->top = (char *)base + max_capacity; + + assert((char *)base <= cs->brk); + assert(cs->brk <= cs->top); + /* Prevent access to the memory we haven't handed out yet. + */ + if (cs->brk != cs->top) { + /* mprotect() requires page-aligned arguments, but it's possible + * for cs->brk not to be page-aligned at this point. + */ + char *prot_brk = (char *)ALIGN_UP(cs->brk, pagesize); + if ((mprotect(base, prot_brk - (char *)base, PROT_READ | PROT_WRITE) < 0) || + (mprotect(prot_brk, cs->top - prot_brk, PROT_NONE) < 0)) { + goto error; + } + } + + cs->m = m; + cs->magic = CONTIG_STATE_MAGIC; + + return (mspace)m; + +error: + return (mspace)0; +} + + +mspace create_contiguous_mspace_with_name(size_t starting_capacity, + size_t max_capacity, int locked, char const *name) { + int fd, ret; + char buf[ASHMEM_NAME_LEN] = "mspace"; + void *base; + unsigned int pagesize; + mstate m; + + if (starting_capacity > max_capacity) + return (mspace)0; + + init_mparams(); + pagesize = PAGESIZE; + + /* Create the anonymous memory that will back the mspace. + * This reserves all of the virtual address space we could + * ever need. Physical pages will be mapped as the memory + * is touched. + * + * Align max_capacity to a whole page. + */ + max_capacity = (size_t)ALIGN_UP(max_capacity, pagesize); + + if (name) + snprintf(buf, sizeof(buf), "mspace/%s", name); + fd = ashmem_create_region(buf, max_capacity); + if (fd < 0) + return (mspace)0; + + base = mmap(NULL, max_capacity, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); + close(fd); + if (base == MAP_FAILED) + return (mspace)0; + + /* Make sure that base is at the beginning of a page. + */ + assert(((uintptr_t)base & (pagesize-1)) == 0); + + m = create_contiguous_mspace_with_base(starting_capacity, max_capacity, + locked, base); + if (m == 0) { + munmap(base, max_capacity); + } + return m; +} + +mspace create_contiguous_mspace(size_t starting_capacity, + size_t max_capacity, int locked) { + return create_contiguous_mspace_with_name(starting_capacity, + max_capacity, locked, NULL); +} + +size_t destroy_contiguous_mspace(mspace msp) { + mstate ms = (mstate)msp; + + if (ok_magic(ms)) { + struct mspace_contig_state *cs; + size_t length; + const unsigned int pagesize = PAGESIZE; + + cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1)); + assert(cs->magic == CONTIG_STATE_MAGIC); + assert(cs->m == ms); + + length = cs->top - (char *)cs; + if (munmap((char *)cs, length) != 0) + return length; + } + else { + USAGE_ERROR_ACTION(ms, ms); + } + return 0; +} + +void *contiguous_mspace_sbrk0(mspace msp) { + struct mspace_contig_state *cs; + mstate ms; + const unsigned int pagesize = PAGESIZE; + + ms = (mstate)msp; + cs = (struct mspace_contig_state *)((uintptr_t)ms & ~(pagesize-1)); + assert(cs->magic == CONTIG_STATE_MAGIC); + assert(cs->m == ms); + return cs->brk; +} +#endif diff --git a/libpixelflinger/codeflinger/CodeCache.cpp b/libpixelflinger/codeflinger/CodeCache.cpp index 60fc7717e..a713febaf 100644 --- a/libpixelflinger/codeflinger/CodeCache.cpp +++ b/libpixelflinger/codeflinger/CodeCache.cpp @@ -23,13 +23,10 @@ #include #include -#include #include #include "codeflinger/CodeCache.h" -#define LOG_TAG "CodeCache" - namespace android { // ---------------------------------------------------------------------------- @@ -41,72 +38,12 @@ namespace android { // ---------------------------------------------------------------------------- -// A dlmalloc mspace is used to manage the code cache over a mmaped region. -#define HAVE_MMAP 0 -#define HAVE_MREMAP 0 -#define HAVE_MORECORE 0 -#define MALLOC_ALIGNMENT 16 -#define MSPACES 1 -#define NO_MALLINFO 1 -#define ONLY_MSPACES 1 -// Custom heap error handling. -#define PROCEED_ON_ERROR 0 -static void heap_error(const char* msg, const char* function, void* p); -#define CORRUPTION_ERROR_ACTION(m) \ - heap_error("HEAP MEMORY CORRUPTION", __FUNCTION__, NULL) -#define USAGE_ERROR_ACTION(m,p) \ - heap_error("ARGUMENT IS INVALID HEAP ADDRESS", __FUNCTION__, p) - - -#pragma GCC diagnostic ignored "-Wstrict-aliasing" -#pragma GCC diagnostic ignored "-Wempty-body" -#include "../../../../bionic/libc/upstream-dlmalloc/malloc.c" -#pragma GCC diagnostic warning "-Wstrict-aliasing" -#pragma GCC diagnostic warning "-Wempty-body" - -static void heap_error(const char* msg, const char* function, void* p) { - ALOG(LOG_FATAL, LOG_TAG, "@@@ ABORTING: CODE FLINGER: %s IN %s addr=%p", - msg, function, p); - /* So that we can get a memory dump around p */ - *((int **) 0xdeadbaad) = (int *) p; -} - -// ---------------------------------------------------------------------------- - -static void* gExecutableStore = NULL; -static mspace gMspace = NULL; -const size_t kMaxCodeCacheCapacity = 1024 * 1024; - -static mspace getMspace() -{ - if (gExecutableStore == NULL) { - int fd = ashmem_create_region("CodeFlinger code cache", - kMaxCodeCacheCapacity); - LOG_ALWAYS_FATAL_IF(fd < 0, - "Creating code cache, ashmem_create_region " - "failed with error '%s'", strerror(errno)); - gExecutableStore = mmap(NULL, kMaxCodeCacheCapacity, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_PRIVATE, fd, 0); - LOG_ALWAYS_FATAL_IF(gExecutableStore == NULL, - "Creating code cache, mmap failed with error " - "'%s'", strerror(errno)); - close(fd); - gMspace = create_mspace_with_base(gExecutableStore, kMaxCodeCacheCapacity, - /*locked=*/ false); - mspace_set_footprint_limit(gMspace, kMaxCodeCacheCapacity); - } - return gMspace; -} - Assembly::Assembly(size_t size) : mCount(1), mSize(0) { mBase = (uint32_t*)mspace_malloc(getMspace(), size); - LOG_ALWAYS_FATAL_IF(mBase == NULL, - "Failed to create Assembly of size %zd in executable " - "store of size %zd", size, kMaxCodeCacheCapacity); mSize = size; + ensureMbaseExecutable(); } Assembly::~Assembly() @@ -140,13 +77,31 @@ uint32_t* Assembly::base() const ssize_t Assembly::resize(size_t newSize) { mBase = (uint32_t*)mspace_realloc(getMspace(), mBase, newSize); - LOG_ALWAYS_FATAL_IF(mBase == NULL, - "Failed to resize Assembly to %zd in code cache " - "of size %zd", newSize, kMaxCodeCacheCapacity); mSize = newSize; + ensureMbaseExecutable(); return size(); } +mspace Assembly::getMspace() +{ + static mspace msp = create_contiguous_mspace(2 * 1024, 1024 * 1024, /*locked=*/ false); + return msp; +} + +void Assembly::ensureMbaseExecutable() +{ + long pagesize = sysconf(_SC_PAGESIZE); + long pagemask = ~(pagesize - 1); // assumes pagesize is a power of 2 + + uint32_t* pageStart = (uint32_t*) (((uintptr_t) mBase) & pagemask); + size_t adjustedLength = (mBase - pageStart) * sizeof(uint32_t) + mSize; + + if (mBase && mprotect(pageStart, adjustedLength, PROT_READ | PROT_WRITE | PROT_EXEC) != 0) { + mspace_free(getMspace(), mBase); + mBase = NULL; + } +} + // ---------------------------------------------------------------------------- CodeCache::CodeCache(size_t size) diff --git a/libpixelflinger/codeflinger/CodeCache.h b/libpixelflinger/codeflinger/CodeCache.h index 54fd69b04..aaafd26cc 100644 --- a/libpixelflinger/codeflinger/CodeCache.h +++ b/libpixelflinger/codeflinger/CodeCache.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "tinyutils/KeyedVector.h" #include "tinyutils/smartpointer.h" @@ -67,6 +68,9 @@ public: typedef void weakref_type; private: + static mspace getMspace(); + void ensureMbaseExecutable(); + mutable int32_t mCount; uint32_t* mBase; size_t mSize; From 707b2582b345b0ecdd6af0584d52a17fccb22153 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 6 Sep 2012 13:05:40 -0700 Subject: [PATCH 04/10] Bring back ADB_EXTERNAL_STORAGE. Bug: 7119408 Change-Id: Ic9a23fb6adfb1db771e1e278179586bca69a5edd --- adb/adb.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/adb/adb.c b/adb/adb.c index e7d948553..07bfbe5d5 100644 --- a/adb/adb.c +++ b/adb/adb.c @@ -1122,6 +1122,16 @@ int adb_main(int is_daemon, int server_port) if (auth_enabled) adb_auth_init(); + // Our external storage path may be different than apps, since + // we aren't able to bind mount after dropping root. + const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE"); + if (NULL != adb_external_storage) { + setenv("EXTERNAL_STORAGE", adb_external_storage, 1); + } else { + D("Warning: ADB_EXTERNAL_STORAGE is not set. Leaving EXTERNAL_STORAGE" + " unchanged.\n"); + } + /* don't listen on a port (default 5037) if running in secure mode */ /* don't run as root if we are running in secure mode */ if (should_drop_privileges()) { From 4a31de849610fc195bf0a48b41f1ecb307635623 Mon Sep 17 00:00:00 2001 From: Jeff Sharkey Date: Thu, 13 Sep 2012 14:47:23 -0700 Subject: [PATCH 05/10] Wrap system calls in TEMP_FAILURE_RETRY. fs_prepare_dir() is used heavily during Zygote init, and can easily run into EINTR. Bug: 7151474 Change-Id: I7aac43a43483d55db47ca20456fff68ce51bbc46 --- include/cutils/fs.h | 15 +++++++++++++++ libcutils/fs.c | 14 ++++++++------ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/include/cutils/fs.h b/include/cutils/fs.h index 04c883994..fd5296bb9 100644 --- a/include/cutils/fs.h +++ b/include/cutils/fs.h @@ -19,6 +19,21 @@ #include +/* + * TEMP_FAILURE_RETRY is defined by some, but not all, versions of + * . (Alas, it is not as standard as we'd hoped!) So, if it's + * not already defined, then define it here. + */ +#ifndef TEMP_FAILURE_RETRY +/* Used to retry syscalls that can return EINTR. */ +#define TEMP_FAILURE_RETRY(exp) ({ \ + typeof (exp) _rc; \ + do { \ + _rc = (exp); \ + } while (_rc == -1 && errno == EINTR); \ + _rc; }) +#endif + #ifdef __cplusplus extern "C" { #endif diff --git a/libcutils/fs.c b/libcutils/fs.c index 1788eca1a..6508b6787 100644 --- a/libcutils/fs.c +++ b/libcutils/fs.c @@ -14,6 +14,8 @@ * limitations under the License. */ +#define LOG_TAG "cutils" + #include #include @@ -31,11 +33,11 @@ int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) { // Check if path needs to be created struct stat sb; - if (lstat(path, &sb) == -1) { + if (TEMP_FAILURE_RETRY(lstat(path, &sb)) == -1) { if (errno == ENOENT) { goto create; } else { - ALOGE("Failed to stat(%s): %s", path, strerror(errno)); + ALOGE("Failed to lstat(%s): %s", path, strerror(errno)); return -1; } } @@ -52,17 +54,17 @@ int fs_prepare_dir(const char* path, mode_t mode, uid_t uid, gid_t gid) { } create: - if (mkdir(path, mode) == -1) { + if (TEMP_FAILURE_RETRY(mkdir(path, mode)) == -1) { ALOGE("Failed to mkdir(%s): %s", path, strerror(errno)); return -1; } fixup: - if (chmod(path, mode) == -1) { - ALOGE("Failed to chown(%s, %d): %s", path, mode, strerror(errno)); + if (TEMP_FAILURE_RETRY(chmod(path, mode)) == -1) { + ALOGE("Failed to chmod(%s, %d): %s", path, mode, strerror(errno)); return -1; } - if (chown(path, uid, gid) == -1) { + if (TEMP_FAILURE_RETRY(chown(path, uid, gid)) == -1) { ALOGE("Failed to chown(%s, %d, %d): %s", path, uid, gid, strerror(errno)); return -1; } From fdd2ff45c734063f405712a58785deaf19d4abab Mon Sep 17 00:00:00 2001 From: Ben Cheng Date: Mon, 24 Sep 2012 14:13:37 -0700 Subject: [PATCH 06/10] Dump 256 bytes per chunk pointed by general-purpose registers. Bug: 7216522 Change-Id: Iddcec8399b00ad411be6863dd866a3f74377ba03 --- debuggerd/arm/machine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/debuggerd/arm/machine.c b/debuggerd/arm/machine.c index 1c2e13ff0..160db7b1e 100644 --- a/debuggerd/arm/machine.c +++ b/debuggerd/arm/machine.c @@ -53,7 +53,8 @@ static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, bool at_fault) { /* catch underflow */ p = 0; } - end = p + 80; + /* Dump more memory content for the crashing thread. */ + end = p + 256; /* catch overflow; 'end - p' has to be multiples of 16 */ while (end < p) end -= 16; @@ -81,6 +82,8 @@ static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, bool at_fault) { long data = ptrace(PTRACE_PEEKTEXT, tid, (void*)p, NULL); sprintf(code_buffer + strlen(code_buffer), "%08lx ", data); + /* Enable the following code blob to dump ASCII values */ +#if 0 int j; for (j = 0; j < 4; j++) { /* @@ -95,6 +98,7 @@ static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, bool at_fault) { *asc_out++ = '.'; } } +#endif p += 4; } *asc_out = '\0'; From 33978c428310d4ecbf8cb45cabb3c906e800b3e9 Mon Sep 17 00:00:00 2001 From: Nick Kralevich Date: Fri, 5 Oct 2012 11:17:21 -0700 Subject: [PATCH 07/10] init: Set ADDR_COMPAT_LAYOUT before spawning processes. Some Android programs have problems with memory which grows from the top down. Temporarily set ADDR_COMPAT_LAYOUT to avoid breaking those programs. Bug: 7188322 Change-Id: I61760500e670b4563838c63b82d4a0b6e354a86e --- init/init.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/init/init.c b/init/init.c index 6127fd38e..1c80d9cc4 100755 --- a/init/init.c +++ b/init/init.c @@ -31,6 +31,7 @@ #include #include #include +#include #ifdef HAVE_SELINUX #include @@ -242,6 +243,21 @@ void service_start(struct service *svc, const char *dynamic_args) int fd, sz; umask(077); +#ifdef __arm__ + /* + * b/7188322 - Temporarily revert to the compat memory layout + * to avoid breaking third party apps. + * + * THIS WILL GO AWAY IN A FUTURE ANDROID RELEASE. + * + * http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=7dbaa466 + * changes the kernel mapping from bottom up to top-down. + * This breaks some programs which improperly embed + * an out of date copy of Android's linker. + */ + int current = personality(0xffffFFFF); + personality(current | ADDR_COMPAT_LAYOUT); +#endif if (properties_inited()) { get_property_workspace(&fd, &sz); sprintf(tmp, "%d,%d", dup(fd), sz); From aae1ce43a45f38b3b4c0fac90e208253fa02ffe6 Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Wed, 5 Dec 2012 15:19:07 -0800 Subject: [PATCH 08/10] libsuspend: compile as a static library Compile libsuspend as a static library as well, currently needed by the charger code in some cases. Related-to-bug: 7429504 Change-Id: I113017c2c855f915b77c76d8934b6e57c0bb532c Signed-off-by: Iliyan Malchev --- libsuspend/Android.mk | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/libsuspend/Android.mk b/libsuspend/Android.mk index 45cb70116..a2fa3e0d8 100644 --- a/libsuspend/Android.mk +++ b/libsuspend/Android.mk @@ -12,7 +12,6 @@ libsuspend_libraries := \ liblog libcutils include $(CLEAR_VARS) - LOCAL_SRC_FILES := $(libsuspend_src_files) LOCAL_MODULE := libsuspend LOCAL_MODULE_TAGS := optional @@ -21,3 +20,12 @@ LOCAL_C_INCLUDES += $(LOCAL_PATH)/include LOCAL_SHARED_LIBRARIES := $(libsuspend_libraries) #LOCAL_CFLAGS += -DLOG_NDEBUG=0 include $(BUILD_SHARED_LIBRARY) + +include $(CLEAR_VARS) +LOCAL_SRC_FILES := $(libsuspend_src_files) +LOCAL_MODULE := libsuspend +LOCAL_MODULE_TAGS := optional +LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include +LOCAL_C_INCLUDES += $(LOCAL_PATH)/include +#LOCAL_CFLAGS += -DLOG_NDEBUG=0 +include $(BUILD_STATIC_LIBRARY) From 3493f18985973e35f83b34b737c8fbcb179007c3 Mon Sep 17 00:00:00 2001 From: "choongryeol.lee" Date: Thu, 15 Nov 2012 17:03:03 -0800 Subject: [PATCH 09/10] charger: suspend enable in charger mode To reduce power consumption after charging completion, enable suspend when LCD is turned off. Bug: 7429504 Change-Id: I34731dc392661c9051a20cea74f70d94a8aaeb42 Signed-off-by: Iliyan Malchev --- charger/Android.mk | 7 +++++++ charger/charger.c | 25 ++++++++++++++++++++++++- 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/charger/Android.mk b/charger/Android.mk index fe0c91d93..02586042f 100644 --- a/charger/Android.mk +++ b/charger/Android.mk @@ -12,6 +12,10 @@ ifeq ($(strip $(BOARD_CHARGER_DISABLE_INIT_BLANK)),true) LOCAL_CFLAGS := -DCHARGER_DISABLE_INIT_BLANK endif +ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true) +LOCAL_CFLAGS += -DCHARGER_ENABLE_SUSPEND +endif + LOCAL_MODULE := charger LOCAL_MODULE_TAGS := optional LOCAL_FORCE_STATIC_EXECUTABLE := true @@ -21,6 +25,9 @@ LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) LOCAL_C_INCLUDES := bootable/recovery LOCAL_STATIC_LIBRARIES := libminui libpixelflinger_static libpng +ifeq ($(strip $(BOARD_CHARGER_ENABLE_SUSPEND)),true) +LOCAL_STATIC_LIBRARIES += libsuspend +endif LOCAL_STATIC_LIBRARIES += libz libstdc++ libcutils libm libc include $(BUILD_EXECUTABLE) diff --git a/charger/charger.c b/charger/charger.c index c5e4ec276..25b3b1aaf 100644 --- a/charger/charger.c +++ b/charger/charger.c @@ -41,6 +41,10 @@ #include #include +#ifdef CHARGER_ENABLE_SUSPEND +#include +#endif + #include "minui/minui.h" #ifndef max @@ -352,6 +356,21 @@ static void remove_supply(struct charger *charger, struct power_supply *supply) free(supply); } +#ifdef CHARGER_ENABLE_SUSPEND +static int request_suspend(bool enable) +{ + if (enable) + return autosuspend_enable(); + else + return autosuspend_disable(); +} +#else +static int request_suspend(bool enable) +{ + return 0; +} +#endif + static void parse_uevent(const char *msg, struct uevent *uevent) { uevent->action = ""; @@ -685,6 +704,7 @@ static void update_screen_state(struct charger *charger, int64_t now) charger->next_screen_transition = -1; gr_fb_blank(true); LOGV("[%lld] animation done\n", now); + request_suspend(true); return; } @@ -824,8 +844,10 @@ static void process_key(struct charger *charger, int code, int64_t now) } } else { /* if the power key got released, force screen state cycle */ - if (key->pending) + if (key->pending) { + request_suspend(false); kick_animation(charger->batt_anim); + } } } @@ -843,6 +865,7 @@ static void handle_input_state(struct charger *charger, int64_t now) static void handle_power_supply_state(struct charger *charger, int64_t now) { if (charger->num_supplies_online == 0) { + request_suspend(false); if (charger->next_pwr_check == -1) { charger->next_pwr_check = now + UNPLUGGED_SHUTDOWN_TIME; LOGI("[%lld] device unplugged: shutting down in %lld (@ %lld)\n", From 7d5f33ed55b9511a64d3e73b33366718972f74af Mon Sep 17 00:00:00 2001 From: Devin Kim Date: Fri, 7 Dec 2012 09:25:06 -0800 Subject: [PATCH 10/10] charger: Do not suspend when disconnecting from charger The device should be power off when disconnecting from charger. If the device enter to suspend, the device couldn't handle the power off process. So the device shouldn't suspend to handle the power off at that time Bug: 7429504 Change-Id: I9a0a60e53f315cd83550dc730a33bc7bd464ef67 --- charger/charger.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/charger/charger.c b/charger/charger.c index 25b3b1aaf..353bdf086 100644 --- a/charger/charger.c +++ b/charger/charger.c @@ -704,7 +704,8 @@ static void update_screen_state(struct charger *charger, int64_t now) charger->next_screen_transition = -1; gr_fb_blank(true); LOGV("[%lld] animation done\n", now); - request_suspend(true); + if (charger->num_supplies_online > 0) + request_suspend(true); return; }