diff options
Diffstat (limited to 'include')
34 files changed, 836 insertions, 542 deletions
diff --git a/include/android/log.h b/include/android/log.h index 0ea4c29..1c171b7 100644 --- a/include/android/log.h +++ b/include/android/log.h @@ -98,8 +98,16 @@ int __android_log_write(int prio, const char *tag, const char *text); */ int __android_log_print(int prio, const char *tag, const char *fmt, ...) #if defined(__GNUC__) +#ifdef __USE_MINGW_ANSI_STDIO +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format(gnu_printf, 3, 4))) +#else __attribute__ ((format(printf, 3, 4))) #endif +#else + __attribute__ ((format(printf, 3, 4))) +#endif +#endif ; /* @@ -110,15 +118,23 @@ int __android_log_vprint(int prio, const char *tag, const char *fmt, va_list ap); /* - * Log an assertion failure and SIGTRAP the process to have a chance - * to inspect it, if a debugger is attached. This uses the FATAL priority. + * Log an assertion failure and abort the process to have a chance + * to inspect it if a debugger is attached. This uses the FATAL priority. */ void __android_log_assert(const char *cond, const char *tag, - const char *fmt, ...) + const char *fmt, ...) #if defined(__GNUC__) __attribute__ ((noreturn)) +#ifdef __USE_MINGW_ANSI_STDIO +#if __USE_MINGW_ANSI_STDIO + __attribute__ ((format(gnu_printf, 3, 4))) +#else __attribute__ ((format(printf, 3, 4))) #endif +#else + __attribute__ ((format(printf, 3, 4))) +#endif +#endif ; #ifdef __cplusplus diff --git a/include/backtrace/Backtrace.h b/include/backtrace/Backtrace.h index bd4134c..e07d322 100644 --- a/include/backtrace/Backtrace.h +++ b/include/backtrace/Backtrace.h @@ -17,6 +17,7 @@ #ifndef _BACKTRACE_BACKTRACE_H #define _BACKTRACE_BACKTRACE_H +#include <inttypes.h> #include <stdint.h> #include <string> @@ -25,6 +26,14 @@ #include <backtrace/backtrace_constants.h> #include <backtrace/BacktraceMap.h> +#if __LP64__ +#define PRIPTR "016" PRIxPTR +typedef uint64_t word_t; +#else +#define PRIPTR "08" PRIxPTR +typedef uint32_t word_t; +#endif + struct backtrace_frame_data_t { size_t num; // The current fame number. uintptr_t pc; // The absolute pc. @@ -38,6 +47,14 @@ struct backtrace_frame_data_t { // Forward declarations. class BacktraceImpl; +#if defined(__APPLE__) +struct __darwin_ucontext; +typedef __darwin_ucontext ucontext_t; +#else +struct ucontext; +typedef ucontext ucontext_t; +#endif + class Backtrace { public: // Create the correct Backtrace object based on what is to be unwound. @@ -55,7 +72,7 @@ public: virtual ~Backtrace(); // Get the current stack trace and store in the backtrace_ structure. - virtual bool Unwind(size_t num_ignore_frames); + virtual bool Unwind(size_t num_ignore_frames, ucontext_t* context = NULL); // Get the function name and offset into the function given the pc. // If the string is empty, then no valid function name was found. @@ -65,7 +82,7 @@ public: virtual const backtrace_map_t* FindMap(uintptr_t pc); // Read the data at a specific address. - virtual bool ReadWord(uintptr_t ptr, uint32_t* out_value) = 0; + virtual bool ReadWord(uintptr_t ptr, word_t* out_value) = 0; // Create a string representing the formatted line of backtrace information // for a single frame. @@ -96,7 +113,7 @@ public: protected: Backtrace(BacktraceImpl* impl, pid_t pid, BacktraceMap* map); - virtual bool VerifyReadWordArgs(uintptr_t ptr, uint32_t* out_value); + virtual bool VerifyReadWordArgs(uintptr_t ptr, word_t* out_value); bool BuildMap(); diff --git a/include/backtrace/BacktraceMap.h b/include/backtrace/BacktraceMap.h index 06da2f4..c717f09 100644 --- a/include/backtrace/BacktraceMap.h +++ b/include/backtrace/BacktraceMap.h @@ -18,6 +18,7 @@ #define _BACKTRACE_BACKTRACE_MAP_H #include <stdint.h> +#include <sys/types.h> #ifdef USE_MINGW // MINGW does not define these constants. #define PROT_NONE 0 @@ -45,7 +46,7 @@ public: virtual ~BacktraceMap(); // Get the map data structure for the given address. - const backtrace_map_t* Find(uintptr_t addr); + virtual const backtrace_map_t* Find(uintptr_t addr); // The flags returned are the same flags as used by the mmap call. // The values are PROT_*. diff --git a/include/corkscrew/backtrace.h b/include/corkscrew/backtrace.h deleted file mode 100644 index 556ad04..0000000 --- a/include/corkscrew/backtrace.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2011 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 stack unwinder. */ - -#ifndef _CORKSCREW_BACKTRACE_H -#define _CORKSCREW_BACKTRACE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include <sys/types.h> -#include <corkscrew/ptrace.h> -#include <corkscrew/map_info.h> -#include <corkscrew/symbol_table.h> - -/* - * Describes a single frame of a backtrace. - */ -typedef struct { - uintptr_t absolute_pc; /* absolute PC offset */ - uintptr_t stack_top; /* top of stack for this frame */ - size_t stack_size; /* size of this stack frame */ -} backtrace_frame_t; - -/* - * Describes the symbols associated with a backtrace frame. - */ -typedef struct { - uintptr_t relative_pc; /* relative frame PC offset from the start of the library, - or the absolute PC if the library is unknown */ - uintptr_t relative_symbol_addr; /* relative offset of the symbol from the start of the - library or 0 if the library is unknown */ - char* map_name; /* executable or library name, or NULL if unknown */ - char* symbol_name; /* symbol name, or NULL if unknown */ - char* demangled_name; /* demangled symbol name, or NULL if unknown */ -} backtrace_symbol_t; - -/* - * Unwinds the call stack for the current thread of execution. - * Populates the backtrace array with the program counters from the call stack. - * Returns the number of frames collected, or -1 if an error occurred. - */ -ssize_t unwind_backtrace(backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth); - -/* - * Unwinds the call stack for a thread within this process. - * Populates the backtrace array with the program counters from the call stack. - * Returns the number of frames collected, or -1 if an error occurred. - * - * The task is briefly suspended while the backtrace is being collected. - */ -ssize_t unwind_backtrace_thread(pid_t tid, backtrace_frame_t* backtrace, - size_t ignore_depth, size_t max_depth); - -/* - * Unwinds the call stack of a task within a remote process using ptrace(). - * Populates the backtrace array with the program counters from the call stack. - * Returns the number of frames collected, or -1 if an error occurred. - */ -ssize_t unwind_backtrace_ptrace(pid_t tid, const ptrace_context_t* context, - backtrace_frame_t* backtrace, size_t ignore_depth, size_t max_depth); - -/* - * Gets the symbols for each frame of a backtrace. - * The symbols array must be big enough to hold one symbol record per frame. - * The symbols must later be freed using free_backtrace_symbols. - */ -void get_backtrace_symbols(const backtrace_frame_t* backtrace, size_t frames, - backtrace_symbol_t* backtrace_symbols); - -/* - * Gets the symbols for each frame of a backtrace from a remote process. - * The symbols array must be big enough to hold one symbol record per frame. - * The symbols must later be freed using free_backtrace_symbols. - */ -void get_backtrace_symbols_ptrace(const ptrace_context_t* context, - const backtrace_frame_t* backtrace, size_t frames, - backtrace_symbol_t* backtrace_symbols); - -/* - * Frees the storage associated with backtrace symbols. - */ -void free_backtrace_symbols(backtrace_symbol_t* backtrace_symbols, size_t frames); - -enum { - // A hint for how big to make the line buffer for format_backtrace_line - MAX_BACKTRACE_LINE_LENGTH = 800, -}; - -/** - * Formats a line from a backtrace as a zero-terminated string into the specified buffer. - */ -void format_backtrace_line(unsigned frameNumber, const backtrace_frame_t* frame, - const backtrace_symbol_t* symbol, char* buffer, size_t bufferSize); - -#ifdef __cplusplus -} -#endif - -#endif // _CORKSCREW_BACKTRACE_H diff --git a/include/corkscrew/demangle.h b/include/corkscrew/demangle.h deleted file mode 100644 index 04b0225..0000000 --- a/include/corkscrew/demangle.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* C++ symbol name demangling. */ - -#ifndef _CORKSCREW_DEMANGLE_H -#define _CORKSCREW_DEMANGLE_H - -#include <sys/types.h> -#include <stdbool.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Demangles a C++ symbol name. - * If name is NULL or if the name cannot be demangled, returns NULL. - * Otherwise, returns a newly allocated string that contains the demangled name. - * - * The caller must free the returned string using free(). - */ -char* demangle_symbol_name(const char* name); - -#ifdef __cplusplus -} -#endif - -#endif // _CORKSCREW_DEMANGLE_H diff --git a/include/corkscrew/map_info.h b/include/corkscrew/map_info.h deleted file mode 100644 index 14bfad6..0000000 --- a/include/corkscrew/map_info.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* Process memory map. */ - -#ifndef _CORKSCREW_MAP_INFO_H -#define _CORKSCREW_MAP_INFO_H - -#include <sys/types.h> -#include <stdbool.h> -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct map_info { - struct map_info* next; - uintptr_t start; - uintptr_t end; - bool is_readable; - bool is_writable; - bool is_executable; - void* data; // arbitrary data associated with the map by the user, initially NULL - char name[]; -} map_info_t; - -/* Loads memory map from /proc/<tid>/maps. */ -map_info_t* load_map_info_list(pid_t tid); - -/* Frees memory map. */ -void free_map_info_list(map_info_t* milist); - -/* Finds the memory map that contains the specified address. */ -const map_info_t* find_map_info(const map_info_t* milist, uintptr_t addr); - -/* Returns true if the addr is in a readable map. */ -bool is_readable_map(const map_info_t* milist, uintptr_t addr); -/* Returns true if the addr is in a writable map. */ -bool is_writable_map(const map_info_t* milist, uintptr_t addr); -/* Returns true if the addr is in an executable map. */ -bool is_executable_map(const map_info_t* milist, uintptr_t addr); - -/* Acquires a reference to the memory map for this process. - * The result is cached and refreshed automatically. - * Make sure to release the map info when done. */ -map_info_t* acquire_my_map_info_list(); - -/* Releases a reference to the map info for this process that was - * previous acquired using acquire_my_map_info_list(). */ -void release_my_map_info_list(map_info_t* milist); - -/* Flushes the cached memory map so the next call to - * acquire_my_map_info_list() gets fresh data. */ -void flush_my_map_info_list(); - -#ifdef __cplusplus -} -#endif - -#endif // _CORKSCREW_MAP_INFO_H diff --git a/include/corkscrew/ptrace.h b/include/corkscrew/ptrace.h deleted file mode 100644 index 76276d8..0000000 --- a/include/corkscrew/ptrace.h +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (C) 2011 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. - */ - -/* Useful ptrace() utility functions. */ - -#ifndef _CORKSCREW_PTRACE_H -#define _CORKSCREW_PTRACE_H - -#include <corkscrew/map_info.h> -#include <corkscrew/symbol_table.h> - -#include <sys/types.h> -#include <stdbool.h> -#include <stdint.h> - -#ifdef __cplusplus -extern "C" { -#endif - -/* Stores information about a process that is used for several different - * ptrace() based operations. */ -typedef struct { - map_info_t* map_info_list; -} ptrace_context_t; - -/* Describes how to access memory from a process. */ -typedef struct { - pid_t tid; - const map_info_t* map_info_list; -} memory_t; - -#if __i386__ -/* ptrace() register context. */ -typedef struct pt_regs_x86 { - uint32_t ebx; - uint32_t ecx; - uint32_t edx; - uint32_t esi; - uint32_t edi; - uint32_t ebp; - uint32_t eax; - uint32_t xds; - uint32_t xes; - uint32_t xfs; - uint32_t xgs; - uint32_t orig_eax; - uint32_t eip; - uint32_t xcs; - uint32_t eflags; - uint32_t esp; - uint32_t xss; -} pt_regs_x86_t; -#endif - -#if __mips__ -/* ptrace() GET_REGS context. */ -typedef struct pt_regs_mips { - uint64_t regs[32]; - uint64_t lo; - uint64_t hi; - uint64_t cp0_epc; - uint64_t cp0_badvaddr; - uint64_t cp0_status; - uint64_t cp0_cause; -} pt_regs_mips_t; -#endif - -/* - * Initializes a memory structure for accessing memory from this process. - */ -void init_memory(memory_t* memory, const map_info_t* map_info_list); - -/* - * Initializes a memory structure for accessing memory from another process - * using ptrace(). - */ -void init_memory_ptrace(memory_t* memory, pid_t tid); - -/* - * Reads a word of memory safely. - * If the memory is local, ensures that the address is readable before dereferencing it. - * Returns false and a value of 0xffffffff if the word could not be read. - */ -bool try_get_word(const memory_t* memory, uintptr_t ptr, uint32_t* out_value); - -/* - * Reads a word of memory safely using ptrace(). - * Returns false and a value of 0xffffffff if the word could not be read. - */ -bool try_get_word_ptrace(pid_t tid, uintptr_t ptr, uint32_t* out_value); - -/* - * Loads information needed for examining a remote process using ptrace(). - * The caller must already have successfully attached to the process - * using ptrace(). - * - * The context can be used for any threads belonging to that process - * assuming ptrace() is attached to them before performing the actual - * unwinding. The context can continue to be used to decode backtraces - * even after ptrace() has been detached from the process. - */ -ptrace_context_t* load_ptrace_context(pid_t pid); - -/* - * Frees a ptrace context. - */ -void free_ptrace_context(ptrace_context_t* context); - -/* - * Finds a symbol using ptrace. - * Returns the containing map and information about the symbol, or - * NULL if one or the other is not available. - */ -void find_symbol_ptrace(const ptrace_context_t* context, - uintptr_t addr, const map_info_t** out_map_info, const symbol_t** out_symbol); - -#ifdef __cplusplus -} -#endif - -#endif // _CORKSCREW_PTRACE_H diff --git a/include/corkscrew/symbol_table.h b/include/corkscrew/symbol_table.h deleted file mode 100644 index 4998750..0000000 --- a/include/corkscrew/symbol_table.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2011 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 _CORKSCREW_SYMBOL_TABLE_H -#define _CORKSCREW_SYMBOL_TABLE_H - -#include <stdint.h> -#include <sys/types.h> - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct { - uintptr_t start; - uintptr_t end; - char* name; -} symbol_t; - -typedef struct { - symbol_t* symbols; - size_t num_symbols; -} symbol_table_t; - -/* - * Loads a symbol table from a given file. - * Returns NULL on error. - */ -symbol_table_t* load_symbol_table(const char* filename); - -/* - * Frees a symbol table. - */ -void free_symbol_table(symbol_table_t* table); - -/* - * Finds a symbol associated with an address in the symbol table. - * Returns NULL if not found. - */ -const symbol_t* find_symbol(const symbol_table_t* table, uintptr_t addr); - -#ifdef __cplusplus -} -#endif - -#endif // _CORKSCREW_SYMBOL_TABLE_H diff --git a/include/cutils/atomic-inline.h b/include/cutils/atomic-inline.h index ae79e00..007a905 100644 --- a/include/cutils/atomic-inline.h +++ b/include/cutils/atomic-inline.h @@ -47,8 +47,12 @@ extern "C" { #include <cutils/atomic-arm64.h> #elif defined(__arm__) #include <cutils/atomic-arm.h> -#elif defined(__i386__) || defined(__x86_64__) +#elif defined(__i386__) #include <cutils/atomic-x86.h> +#elif defined(__x86_64__) +#include <cutils/atomic-x86_64.h> +#elif defined(__mips64) +#include <cutils/atomic-mips64.h> #elif defined(__mips__) #include <cutils/atomic-mips.h> #else diff --git a/include/cutils/atomic-mips.h b/include/cutils/atomic-mips.h index f9d3e25..1ed833d 100644 --- a/include/cutils/atomic-mips.h +++ b/include/cutils/atomic-mips.h @@ -117,23 +117,6 @@ android_atomic_release_cas(int32_t old_value, extern ANDROID_ATOMIC_INLINE int32_t -android_atomic_swap(int32_t new_value, volatile int32_t *ptr) -{ - int32_t prev, status; - do { - __asm__ __volatile__ ( - " move %[status], %[new_value]\n" - " ll %[prev], (%[ptr])\n" - " sc %[status], (%[ptr])\n" - : [prev] "=&r" (prev), [status] "=&r" (status) - : [ptr] "r" (ptr), [new_value] "r" (new_value) - ); - } while (__builtin_expect(status == 0, 0)); - android_memory_barrier(); - return prev; -} - -extern ANDROID_ATOMIC_INLINE int32_t android_atomic_add(int32_t increment, volatile int32_t *ptr) { int32_t prev, status; diff --git a/include/cutils/atomic-mips64.h b/include/cutils/atomic-mips64.h new file mode 100644 index 0000000..99bbe3a --- /dev/null +++ b/include/cutils/atomic-mips64.h @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2010 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 ANDROID_CUTILS_ATOMIC_MIPS64_H +#define ANDROID_CUTILS_ATOMIC_MIPS64_H + +#include <stdint.h> + +#ifndef ANDROID_ATOMIC_INLINE +#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline)) +#endif + +extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void) +{ + __asm__ __volatile__ ("" : : : "memory"); +} + +#if ANDROID_SMP == 0 +extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void) +{ + android_compiler_barrier(); +} +extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void) +{ + android_compiler_barrier(); +} +#else +extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void) +{ + __asm__ __volatile__ ("sync" : : : "memory"); +} +extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void) +{ + __asm__ __volatile__ ("sync" : : : "memory"); +} +#endif + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_acquire_load(volatile const int32_t *ptr) +{ + int32_t value = *ptr; + android_memory_barrier(); + return value; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_acquire_load64(volatile const int64_t *ptr) +{ + int64_t value = *ptr; + android_memory_barrier(); + return value; +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_release_load(volatile const int32_t *ptr) +{ + android_memory_barrier(); + return *ptr; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_release_load64(volatile const int64_t *ptr) +{ + android_memory_barrier(); + return *ptr; +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_acquire_store(int32_t value, volatile int32_t *ptr) +{ + *ptr = value; + android_memory_barrier(); +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_acquire_store64(int64_t value, volatile int64_t *ptr) +{ + *ptr = value; + android_memory_barrier(); +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_release_store(int32_t value, volatile int32_t *ptr) +{ + android_memory_barrier(); + *ptr = value; +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_release_store64(int64_t value, volatile int64_t *ptr) +{ + android_memory_barrier(); + *ptr = value; +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr) +{ + int32_t prev, status; + do { + __asm__ __volatile__ ( + " ll %[prev], (%[ptr])\n" + " li %[status], 1\n" + " bne %[prev], %[old], 9f\n" + " move %[status], %[new_value]\n" + " sc %[status], (%[ptr])\n" + "9:\n" + : [prev] "=&r" (prev), [status] "=&r" (status) + : [ptr] "r" (ptr), [old] "r" (old_value), [new_value] "r" (new_value) + ); + } while (__builtin_expect(status == 0, 0)); + return prev != old_value; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + return __sync_val_compare_and_swap(ptr, old_value, new_value) != old_value; +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_acquire_cas(int32_t old_value, + int32_t new_value, + volatile int32_t *ptr) +{ + int status = android_atomic_cas(old_value, new_value, ptr); + android_memory_barrier(); + return status; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_acquire_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + int status = android_atomic_cas64(old_value, new_value, ptr); + android_memory_barrier(); + return status; +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_release_cas(int32_t old_value, + int32_t new_value, + volatile int32_t *ptr) +{ + android_memory_barrier(); + return android_atomic_cas(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_release_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + android_memory_barrier(); + return android_atomic_cas64(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_add(int32_t increment, volatile int32_t *ptr) +{ + int32_t prev, status; + android_memory_barrier(); + do { + __asm__ __volatile__ ( + " ll %[prev], (%[ptr])\n" + " addu %[status], %[prev], %[inc]\n" + " sc %[status], (%[ptr])\n" + : [status] "=&r" (status), [prev] "=&r" (prev) + : [ptr] "r" (ptr), [inc] "Ir" (increment) + ); + } while (__builtin_expect(status == 0, 0)); + return prev; +} + +extern ANDROID_ATOMIC_INLINE int32_t +android_atomic_inc(volatile int32_t *addr) +{ + return android_atomic_add(1, addr); +} + +extern ANDROID_ATOMIC_INLINE int32_t +android_atomic_dec(volatile int32_t *addr) +{ + return android_atomic_add(-1, addr); +} + +extern ANDROID_ATOMIC_INLINE int32_t +android_atomic_and(int32_t value, volatile int32_t *ptr) +{ + int32_t prev, status; + android_memory_barrier(); + do { + __asm__ __volatile__ ( + " ll %[prev], (%[ptr])\n" + " and %[status], %[prev], %[value]\n" + " sc %[status], (%[ptr])\n" + : [prev] "=&r" (prev), [status] "=&r" (status) + : [ptr] "r" (ptr), [value] "Ir" (value) + ); + } while (__builtin_expect(status == 0, 0)); + return prev; +} + +extern ANDROID_ATOMIC_INLINE int32_t +android_atomic_or(int32_t value, volatile int32_t *ptr) +{ + int32_t prev, status; + android_memory_barrier(); + do { + __asm__ __volatile__ ( + " ll %[prev], (%[ptr])\n" + " or %[status], %[prev], %[value]\n" + " sc %[status], (%[ptr])\n" + : [prev] "=&r" (prev), [status] "=&r" (status) + : [ptr] "r" (ptr), [value] "Ir" (value) + ); + } while (__builtin_expect(status == 0, 0)); + return prev; +} + +#endif /* ANDROID_CUTILS_ATOMIC_MIPS_H */ diff --git a/include/cutils/atomic-x86_64.h b/include/cutils/atomic-x86_64.h new file mode 100644 index 0000000..5b5c203 --- /dev/null +++ b/include/cutils/atomic-x86_64.h @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef ANDROID_CUTILS_ATOMIC_X86_64_H +#define ANDROID_CUTILS_ATOMIC_X86_64_H + +#include <stdint.h> + +#ifndef ANDROID_ATOMIC_INLINE +#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline)) +#endif + +extern ANDROID_ATOMIC_INLINE +void android_compiler_barrier(void) +{ + __asm__ __volatile__ ("" : : : "memory"); +} + +#if ANDROID_SMP == 0 +extern ANDROID_ATOMIC_INLINE +void android_memory_barrier(void) +{ + android_compiler_barrier(); +} +extern ANDROID_ATOMIC_INLINE +void android_memory_store_barrier(void) +{ + android_compiler_barrier(); +} +#else +extern ANDROID_ATOMIC_INLINE +void android_memory_barrier(void) +{ + __asm__ __volatile__ ("mfence" : : : "memory"); +} +extern ANDROID_ATOMIC_INLINE +void android_memory_store_barrier(void) +{ + android_compiler_barrier(); +} +#endif + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_acquire_load(volatile const int32_t *ptr) +{ + int32_t value = *ptr; + android_compiler_barrier(); + return value; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_acquire_load64(volatile const int64_t *ptr) +{ + int64_t value = *ptr; + android_compiler_barrier(); + return value; +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_release_load(volatile const int32_t *ptr) +{ + android_memory_barrier(); + return *ptr; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_release_load64(volatile const int64_t *ptr) +{ + android_memory_barrier(); + return *ptr; +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_acquire_store(int32_t value, volatile int32_t *ptr) +{ + *ptr = value; + android_memory_barrier(); +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_acquire_store64(int64_t value, volatile int64_t *ptr) +{ + *ptr = value; + android_memory_barrier(); +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_release_store(int32_t value, volatile int32_t *ptr) +{ + android_compiler_barrier(); + *ptr = value; +} + +extern ANDROID_ATOMIC_INLINE +void android_atomic_release_store64(int64_t value, volatile int64_t *ptr) +{ + android_compiler_barrier(); + *ptr = value; +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_cas(int32_t old_value, int32_t new_value, + volatile int32_t *ptr) +{ + int32_t prev; + __asm__ __volatile__ ("lock; cmpxchgl %1, %2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev != old_value; +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + int64_t prev; + __asm__ __volatile__ ("lock; cmpxchgq %1, %2" + : "=a" (prev) + : "q" (new_value), "m" (*ptr), "0" (old_value) + : "memory"); + return prev != old_value; +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_acquire_cas(int32_t old_value, int32_t new_value, + volatile int32_t *ptr) +{ + /* Loads are not reordered with other loads. */ + return android_atomic_cas(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_acquire_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + /* Loads are not reordered with other loads. */ + return android_atomic_cas64(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int android_atomic_release_cas(int32_t old_value, int32_t new_value, + volatile int32_t *ptr) +{ + /* Stores are not reordered with other stores. */ + return android_atomic_cas(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int64_t android_atomic_release_cas64(int64_t old_value, int64_t new_value, + volatile int64_t *ptr) +{ + /* Stores are not reordered with other stores. */ + return android_atomic_cas64(old_value, new_value, ptr); +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_add(int32_t increment, volatile int32_t *ptr) +{ + __asm__ __volatile__ ("lock; xaddl %0, %1" + : "+r" (increment), "+m" (*ptr) + : : "memory"); + /* increment now holds the old value of *ptr */ + return increment; +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_inc(volatile int32_t *addr) +{ + return android_atomic_add(1, addr); +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_dec(volatile int32_t *addr) +{ + return android_atomic_add(-1, addr); +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_and(int32_t value, volatile int32_t *ptr) +{ + int32_t prev, status; + do { + prev = *ptr; + status = android_atomic_cas(prev, prev & value, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + +extern ANDROID_ATOMIC_INLINE +int32_t android_atomic_or(int32_t value, volatile int32_t *ptr) +{ + int32_t prev, status; + do { + prev = *ptr; + status = android_atomic_cas(prev, prev | value, ptr); + } while (__builtin_expect(status != 0, 0)); + return prev; +} + +#endif /* ANDROID_CUTILS_ATOMIC_X86_64_H */ diff --git a/include/cutils/bitops.h b/include/cutils/bitops.h index c26dc54..045830d 100644 --- a/include/cutils/bitops.h +++ b/include/cutils/bitops.h @@ -59,7 +59,7 @@ static inline void bitmask_init(unsigned int *bitmask, int num_bits) static inline int bitmask_ffz(unsigned int *bitmask, int num_bits) { int bit, result; - unsigned int i; + size_t i; for (i = 0; i < BITS_TO_WORDS(num_bits); i++) { bit = ffs(~bitmask[i]); @@ -77,7 +77,7 @@ static inline int bitmask_ffz(unsigned int *bitmask, int num_bits) static inline int bitmask_weight(unsigned int *bitmask, int num_bits) { - int i; + size_t i; int weight = 0; for (i = 0; i < BITS_TO_WORDS(num_bits); i++) diff --git a/include/cutils/debugger.h b/include/cutils/debugger.h index 4eda523..ae6bfc4 100644 --- a/include/cutils/debugger.h +++ b/include/cutils/debugger.h @@ -23,7 +23,11 @@ extern "C" { #endif +#if __LP64__ +#define DEBUGGER_SOCKET_NAME "android:debuggerd64" +#else #define DEBUGGER_SOCKET_NAME "android:debuggerd" +#endif typedef enum { // dump a crash @@ -38,6 +42,7 @@ typedef struct { debugger_action_t action; pid_t tid; uintptr_t abort_msg_address; + int32_t original_si_code; } debugger_msg_t; /* Dumps a process backtrace, registers, and stack to a tombstone file (requires root). diff --git a/include/cutils/fs.h b/include/cutils/fs.h index d1d4cf2..70f0b92 100644 --- a/include/cutils/fs.h +++ b/include/cutils/fs.h @@ -18,6 +18,7 @@ #define __CUTILS_FS_H #include <sys/types.h> +#include <unistd.h> /* * TEMP_FAILURE_RETRY is defined by some, but not all, versions of diff --git a/include/cutils/klog.h b/include/cutils/klog.h index ba728ac..3635e89 100644 --- a/include/cutils/klog.h +++ b/include/cutils/klog.h @@ -18,22 +18,31 @@ #define _CUTILS_KLOG_H_ #include <sys/cdefs.h> +#include <stdarg.h> __BEGIN_DECLS void klog_init(void); +int klog_get_level(void); void klog_set_level(int level); void klog_close(void); void klog_write(int level, const char *fmt, ...) __attribute__ ((format(printf, 2, 3))); +void klog_vwrite(int level, const char *fmt, va_list ap); __END_DECLS -#define KLOG_ERROR(tag,x...) klog_write(3, "<3>" tag ": " x) -#define KLOG_WARNING(tag,x...) klog_write(4, "<4>" tag ": " x) -#define KLOG_NOTICE(tag,x...) klog_write(5, "<5>" tag ": " x) -#define KLOG_INFO(tag,x...) klog_write(6, "<6>" tag ": " x) -#define KLOG_DEBUG(tag,x...) klog_write(7, "<7>" tag ": " x) +#define KLOG_ERROR_LEVEL 3 +#define KLOG_WARNING_LEVEL 4 +#define KLOG_NOTICE_LEVEL 5 +#define KLOG_INFO_LEVEL 6 +#define KLOG_DEBUG_LEVEL 7 + +#define KLOG_ERROR(tag,x...) klog_write(KLOG_ERROR_LEVEL, "<3>" tag ": " x) +#define KLOG_WARNING(tag,x...) klog_write(KLOG_WARNING_LEVEL, "<4>" tag ": " x) +#define KLOG_NOTICE(tag,x...) klog_write(KLOG_NOTICE_LEVEL, "<5>" tag ": " x) +#define KLOG_INFO(tag,x...) klog_write(KLOG_INFO_LEVEL, "<6>" tag ": " x) +#define KLOG_DEBUG(tag,x...) klog_write(KLOG_DEBUG_LEVEL, "<7>" tag ": " x) #define KLOG_DEFAULT_LEVEL 3 /* messages <= this level are logged */ diff --git a/include/cutils/list.h b/include/cutils/list.h index 945729a..4ba2cfd 100644 --- a/include/cutils/list.h +++ b/include/cutils/list.h @@ -44,10 +44,10 @@ struct listnode #define list_for_each_reverse(node, list) \ for (node = (list)->prev; node != (list); node = node->prev) -#define list_for_each_safe(node, next, list) \ - for (node = (list)->next, next = node->next; \ +#define list_for_each_safe(node, n, list) \ + for (node = (list)->next, n = node->next; \ node != (list); \ - node = next, next = node->next) + node = n, n = node->next) static inline void list_init(struct listnode *node) { @@ -63,6 +63,14 @@ static inline void list_add_tail(struct listnode *head, struct listnode *item) head->prev = item; } +static inline void list_add_head(struct listnode *head, struct listnode *item) +{ + item->next = head->next; + item->prev = head; + head->next->prev = item; + head->next = item; +} + static inline void list_remove(struct listnode *item) { item->next->prev = item->prev; diff --git a/include/cutils/misc.h b/include/cutils/misc.h index 2c48dfa..0de505f 100644 --- a/include/cutils/misc.h +++ b/include/cutils/misc.h @@ -28,13 +28,6 @@ extern "C" { */ extern void *load_file(const char *fn, unsigned *sz); - /* Connects your process to the system debugger daemon - * so that on a crash it may be logged or interactively - * debugged (depending on system settings). - */ -extern void debuggerd_connect(void); - - /* This is the range of UIDs (and GIDs) that are reserved * for assigning to applications. */ diff --git a/include/cutils/properties.h b/include/cutils/properties.h index 2c70165..798db8b 100644 --- a/include/cutils/properties.h +++ b/include/cutils/properties.h @@ -20,6 +20,7 @@ #include <sys/cdefs.h> #include <stddef.h> #include <sys/system_properties.h> +#include <stdint.h> #ifdef __cplusplus extern "C" { @@ -44,6 +45,64 @@ extern "C" { */ int property_get(const char *key, char *value, const char *default_value); +/* property_get_bool: returns the value of key coerced into a +** boolean. If the property is not set, then the default value is returned. +** +* The following is considered to be true (1): +** "1", "true", "y", "yes", "on" +** +** The following is considered to be false (0): +** "0", "false", "n", "no", "off" +** +** The conversion is whitespace-sensitive (e.g. " off" will not be false). +** +** If no property with this key is set (or the key is NULL) or the boolean +** conversion fails, the default value is returned. +**/ +int8_t property_get_bool(const char *key, int8_t default_value); + +/* property_get_int64: returns the value of key truncated and coerced into a +** int64_t. If the property is not set, then the default value is used. +** +** The numeric conversion is identical to strtoimax with the base inferred: +** - All digits up to the first non-digit characters are read +** - The longest consecutive prefix of digits is converted to a long +** +** Valid strings of digits are: +** - An optional sign character + or - +** - An optional prefix indicating the base (otherwise base 10 is assumed) +** -- 0 prefix is octal +** -- 0x / 0X prefix is hex +** +** Leading/trailing whitespace is ignored. Overflow/underflow will cause +** numeric conversion to fail. +** +** If no property with this key is set (or the key is NULL) or the numeric +** conversion fails, the default value is returned. +**/ +int64_t property_get_int64(const char *key, int64_t default_value); + +/* property_get_int32: returns the value of key truncated and coerced into an +** int32_t. If the property is not set, then the default value is used. +** +** The numeric conversion is identical to strtoimax with the base inferred: +** - All digits up to the first non-digit characters are read +** - The longest consecutive prefix of digits is converted to a long +** +** Valid strings of digits are: +** - An optional sign character + or - +** - An optional prefix indicating the base (otherwise base 10 is assumed) +** -- 0 prefix is octal +** -- 0x / 0X prefix is hex +** +** Leading/trailing whitespace is ignored. Overflow/underflow will cause +** numeric conversion to fail. +** +** If no property with this key is set (or the key is NULL) or the numeric +** conversion fails, the default value is returned. +**/ +int32_t property_get_int32(const char *key, int32_t default_value); + /* property_set: returns 0 on success, < 0 on failure */ int property_set(const char *key, const char *value); diff --git a/include/cutils/sockets.h b/include/cutils/sockets.h index 19cae0c..daf43ec 100644 --- a/include/cutils/sockets.h +++ b/include/cutils/sockets.h @@ -86,6 +86,8 @@ static inline int android_get_control_socket(const char *name) extern int socket_loopback_client(int port, int type); extern int socket_network_client(const char *host, int port, int type); +extern int socket_network_client_timeout(const char *host, int port, int type, + int timeout); extern int socket_loopback_server(int port, int type); extern int socket_local_server(const char *name, int namespaceId, int type); extern int socket_local_server_bind(int s, const char *name, int namespaceId); diff --git a/include/cutils/trace.h b/include/cutils/trace.h index 1c8f107..fd9bc6a 100644 --- a/include/cutils/trace.h +++ b/include/cutils/trace.h @@ -17,13 +17,15 @@ #ifndef _LIBS_CUTILS_TRACE_H #define _LIBS_CUTILS_TRACE_H +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> +#include <stdio.h> #include <sys/cdefs.h> #include <sys/types.h> -#include <stdint.h> -#include <stdbool.h> #include <unistd.h> -#include <cutils/compiler.h> +#include <cutils/compiler.h> #ifdef ANDROID_SMP #include <cutils/atomic-inline.h> #else @@ -67,7 +69,8 @@ __BEGIN_DECLS #define ATRACE_TAG_RESOURCES (1<<13) #define ATRACE_TAG_DALVIK (1<<14) #define ATRACE_TAG_RS (1<<15) -#define ATRACE_TAG_LAST ATRACE_TAG_RS +#define ATRACE_TAG_BIONIC (1<<16) +#define ATRACE_TAG_LAST ATRACE_TAG_BIONIC // Reserved for initialization. #define ATRACE_TAG_NOT_READY (1LL<<63) @@ -217,8 +220,8 @@ static inline void atrace_async_begin(uint64_t tag, const char* name, char buf[ATRACE_MESSAGE_LENGTH]; size_t len; - len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%d", getpid(), - name, cookie); + len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%" PRId32, + getpid(), name, cookie); write(atrace_marker_fd, buf, len); } } @@ -235,8 +238,8 @@ static inline void atrace_async_end(uint64_t tag, const char* name, char buf[ATRACE_MESSAGE_LENGTH]; size_t len; - len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%d", getpid(), - name, cookie); + len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%" PRId32, + getpid(), name, cookie); write(atrace_marker_fd, buf, len); } } @@ -253,7 +256,7 @@ static inline void atrace_int(uint64_t tag, const char* name, int32_t value) char buf[ATRACE_MESSAGE_LENGTH]; size_t len; - len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%d", + len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId32, getpid(), name, value); write(atrace_marker_fd, buf, len); } @@ -270,7 +273,7 @@ static inline void atrace_int64(uint64_t tag, const char* name, int64_t value) char buf[ATRACE_MESSAGE_LENGTH]; size_t len; - len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%lld", + len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%" PRId64, getpid(), name, value); write(atrace_marker_fd, buf, len); } diff --git a/include/log/log.h b/include/log/log.h index 7f952ff..ace12d6 100644 --- a/include/log/log.h +++ b/include/log/log.h @@ -73,10 +73,11 @@ extern "C" { * Simplified macro to send a verbose log message using the current LOG_TAG. */ #ifndef ALOGV +#define __ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define ALOGV(...) ((void)0) +#define ALOGV(...) do { if (0) { __ALOGV(__VA_ARGS__); } } while (0) #else -#define ALOGV(...) ((void)ALOG(LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define ALOGV(...) __ALOGV(__VA_ARGS__) #endif #endif @@ -202,10 +203,11 @@ extern "C" { * Simplified macro to send a verbose system log message using the current LOG_TAG. */ #ifndef SLOGV +#define __SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define SLOGV(...) ((void)0) +#define SLOGV(...) do { if (0) { __SLOGV(__VA_ARGS__); } } while (0) #else -#define SLOGV(...) ((void)__android_log_buf_print(LOG_ID_SYSTEM, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define SLOGV(...) __SLOGV(__VA_ARGS__) #endif #endif @@ -284,10 +286,11 @@ extern "C" { * Simplified macro to send a verbose radio log message using the current LOG_TAG. */ #ifndef RLOGV +#define __RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) #if LOG_NDEBUG -#define RLOGV(...) ((void)0) +#define RLOGV(...) do { if (0) { __RLOGV(__VA_ARGS__); } } while (0) #else -#define RLOGV(...) ((void)__android_log_buf_print(LOG_ID_RADIO, ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)) +#define RLOGV(...) __RLOGV(__VA_ARGS__) #endif #endif @@ -488,7 +491,7 @@ typedef enum { #endif #ifndef LOG_EVENT_STRING #define LOG_EVENT_STRING(_tag, _value) \ - ((void) 0) /* not implemented -- must combine len with string */ + (void) __android_log_bswrite(_tag, _value); #endif /* TODO: something for LIST */ @@ -547,6 +550,7 @@ typedef enum log_id { LOG_ID_RADIO = 1, LOG_ID_EVENTS = 2, LOG_ID_SYSTEM = 3, + LOG_ID_CRASH = 4, LOG_ID_MAX } log_id_t; @@ -557,7 +561,11 @@ typedef enum log_id { * Send a simple string to the log. */ int __android_log_buf_write(int bufID, int prio, const char *tag, const char *text); -int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...); +int __android_log_buf_print(int bufID, int prio, const char *tag, const char *fmt, ...) +#if defined(__GNUC__) + __attribute__((__format__(printf, 4, 5))) +#endif + ; #ifdef __cplusplus } diff --git a/include/log/log_read.h b/include/log/log_read.h index 861c192..946711a 100644 --- a/include/log/log_read.h +++ b/include/log/log_read.h @@ -17,23 +17,45 @@ #ifndef _LIBS_LOG_LOG_READ_H #define _LIBS_LOG_LOG_READ_H +#include <stdint.h> #include <time.h> +/* struct log_time is a wire-format variant of struct timespec */ #define NS_PER_SEC 1000000000ULL + #ifdef __cplusplus -struct log_time : public timespec { + +// NB: do NOT define a copy constructor. This will result in structure +// no longer being compatible with pass-by-value which is desired +// efficient behavior. Also, pass-by-reference breaks C/C++ ABI. +struct log_time { public: - log_time(timespec &T) + uint32_t tv_sec; // good to Feb 5 2106 + uint32_t tv_nsec; + + static const uint32_t tv_sec_max = 0xFFFFFFFFUL; + static const uint32_t tv_nsec_max = 999999999UL; + + log_time(const timespec &T) { tv_sec = T.tv_sec; tv_nsec = T.tv_nsec; } - log_time(void) + log_time(uint32_t sec, uint32_t nsec) + { + tv_sec = sec; + tv_nsec = nsec; + } + static const timespec EPOCH; + log_time() { } log_time(clockid_t id) { - clock_gettime(id, (timespec *) this); + timespec T; + clock_gettime(id, &T); + tv_sec = T.tv_sec; + tv_nsec = T.tv_nsec; } log_time(const char *T) { @@ -41,9 +63,12 @@ public: tv_sec = c[0] | (c[1] << 8) | (c[2] << 16) | (c[3] << 24); tv_nsec = c[4] | (c[5] << 8) | (c[6] << 16) | (c[7] << 24); } + + // timespec bool operator== (const timespec &T) const { - return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + return (tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec == static_cast<uint32_t>(T.tv_nsec)); } bool operator!= (const timespec &T) const { @@ -51,8 +76,9 @@ public: } bool operator< (const timespec &T) const { - return (tv_sec < T.tv_sec) - || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + return (tv_sec < static_cast<uint32_t>(T.tv_sec)) + || ((tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec < static_cast<uint32_t>(T.tv_nsec))); } bool operator>= (const timespec &T) const { @@ -60,20 +86,73 @@ public: } bool operator> (const timespec &T) const { + return (tv_sec > static_cast<uint32_t>(T.tv_sec)) + || ((tv_sec == static_cast<uint32_t>(T.tv_sec)) + && (tv_nsec > static_cast<uint32_t>(T.tv_nsec))); + } + bool operator<= (const timespec &T) const + { + return !(*this > T); + } + log_time operator-= (const timespec &T); + log_time operator- (const timespec &T) const + { + log_time local(*this); + return local -= T; + } + + // log_time + bool operator== (const log_time &T) const + { + return (tv_sec == T.tv_sec) && (tv_nsec == T.tv_nsec); + } + bool operator!= (const log_time &T) const + { + return !(*this == T); + } + bool operator< (const log_time &T) const + { + return (tv_sec < T.tv_sec) + || ((tv_sec == T.tv_sec) && (tv_nsec < T.tv_nsec)); + } + bool operator>= (const log_time &T) const + { + return !(*this < T); + } + bool operator> (const log_time &T) const + { return (tv_sec > T.tv_sec) || ((tv_sec == T.tv_sec) && (tv_nsec > T.tv_nsec)); } - bool operator<= (const timespec &T) const + bool operator<= (const log_time &T) const { return !(*this > T); } - uint64_t nsec(void) const + log_time operator-= (const log_time &T); + log_time operator- (const log_time &T) const + { + log_time local(*this); + return local -= T; + } + + uint64_t nsec() const { return static_cast<uint64_t>(tv_sec) * NS_PER_SEC + tv_nsec; } -}; + + static const char default_format[]; + + // Add %#q for the fraction of a second to the standard library functions + char *strptime(const char *s, const char *format = default_format); +} __attribute__((__packed__)); + #else -typedef struct timespec log_time; + +typedef struct log_time { + uint32_t tv_sec; + uint32_t tv_nsec; +} __attribute__((__packed__)) log_time; + #endif #endif /* define _LIBS_LOG_LOG_READ_H */ diff --git a/include/log/logd.h b/include/log/logd.h index 379c373..2e6f220 100644 --- a/include/log/logd.h +++ b/include/log/logd.h @@ -41,6 +41,7 @@ extern "C" { int __android_log_bwrite(int32_t tag, const void *payload, size_t len); int __android_log_btwrite(int32_t tag, char type, const void *payload, size_t len); +int __android_log_bswrite(int32_t tag, const char *payload); #ifdef __cplusplus } diff --git a/include/log/logger.h b/include/log/logger.h index 966397a..53be1d3 100644 --- a/include/log/logger.h +++ b/include/log/logger.h @@ -12,6 +12,7 @@ #include <stdint.h> #include <log/log.h> +#include <log/log_read.h> #ifdef __cplusplus extern "C" { @@ -30,12 +31,12 @@ struct logger_entry { int32_t sec; /* seconds since Epoch */ int32_t nsec; /* nanoseconds */ char msg[0]; /* the entry's payload */ -}; +} __attribute__((__packed__)); /* * The userspace structure for version 2 of the logger_entry ABI. * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION) - * is called with version==2 + * is called with version==2; or used with the user space log daemon. */ struct logger_entry_v2 { uint16_t len; /* length of the payload */ @@ -46,13 +47,23 @@ struct logger_entry_v2 { int32_t nsec; /* nanoseconds */ uint32_t euid; /* effective UID of logger */ char msg[0]; /* the entry's payload */ -}; +} __attribute__((__packed__)); + +struct logger_entry_v3 { + uint16_t len; /* length of the payload */ + uint16_t hdr_size; /* sizeof(struct logger_entry_v3) */ + int32_t pid; /* generating process's pid */ + int32_t tid; /* generating process's tid */ + int32_t sec; /* seconds since Epoch */ + int32_t nsec; /* nanoseconds */ + uint32_t lid; /* log id of the payload */ + char msg[0]; /* the entry's payload */ +} __attribute__((__packed__)); /* * The maximum size of the log entry payload that can be - * written to the kernel logger driver. An attempt to write - * more than this amount to /dev/log/* will result in a - * truncated log entry. + * written to the logger. An attempt to write more than + * this amount will result in a truncated log entry. */ #define LOGGER_ENTRY_MAX_PAYLOAD 4076 @@ -68,13 +79,10 @@ struct logger_entry_v2 { struct log_msg { union { unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - struct logger_entry_v2 entry; + struct logger_entry_v3 entry; + struct logger_entry_v3 entry_v3; struct logger_entry_v2 entry_v2; struct logger_entry entry_v1; - struct { - unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1]; - log_id_t id; - } extra; } __attribute__((aligned(4))); #ifdef __cplusplus /* Matching log_time operators */ @@ -106,21 +114,21 @@ struct log_msg { { return !(*this > T); } - uint64_t nsec(void) const + uint64_t nsec() const { return static_cast<uint64_t>(entry.sec) * NS_PER_SEC + entry.nsec; } /* packet methods */ - log_id_t id(void) + log_id_t id() { - return extra.id; + return (log_id_t) entry.lid; } - char *msg(void) + char *msg() { return entry.hdr_size ? (char *) buf + entry.hdr_size : entry_v1.msg; } - unsigned int len(void) + unsigned int len() { return (entry.hdr_size ? entry.hdr_size : sizeof(entry_v1)) + entry.len; } @@ -132,15 +140,26 @@ struct logger; log_id_t android_logger_get_id(struct logger *logger); int android_logger_clear(struct logger *logger); -int android_logger_get_log_size(struct logger *logger); -int android_logger_get_log_readable_size(struct logger *logger); +long android_logger_get_log_size(struct logger *logger); +int android_logger_set_log_size(struct logger *logger, unsigned long size); +long android_logger_get_log_readable_size(struct logger *logger); int android_logger_get_log_version(struct logger *logger); struct logger_list; +ssize_t android_logger_get_statistics(struct logger_list *logger_list, + char *buf, size_t len); +ssize_t android_logger_get_prune_list(struct logger_list *logger_list, + char *buf, size_t len); +int android_logger_set_prune_list(struct logger_list *logger_list, + char *buf, size_t len); + struct logger_list *android_logger_list_alloc(int mode, unsigned int tail, pid_t pid); +struct logger_list *android_logger_list_alloc_time(int mode, + log_time start, + pid_t pid); void android_logger_list_free(struct logger_list *logger_list); /* In the purest sense, the following two are orthogonal interfaces */ int android_logger_list_read(struct logger_list *logger_list, diff --git a/include/private/android_filesystem_config.h b/include/private/android_filesystem_config.h index 0ed0d78..d8e938e 100644 --- a/include/private/android_filesystem_config.h +++ b/include/private/android_filesystem_config.h @@ -76,6 +76,8 @@ #define AID_SDCARD_PICS 1033 /* external storage photos access */ #define AID_SDCARD_AV 1034 /* external storage audio/video access */ #define AID_SDCARD_ALL 1035 /* access all users external storage */ +#define AID_LOGD 1036 /* log daemon */ +#define AID_SHARED_RELRO 1037 /* creator of shared GNU RELRO files */ #define AID_SHELL 2000 /* adb and debug shell user */ #define AID_CACHE 2001 /* cache access */ @@ -92,6 +94,7 @@ #define AID_NET_BW_ACCT 3007 /* change bandwidth statistics accounting */ #define AID_NET_BT_STACK 3008 /* bluetooth: access config files */ +#define AID_EVERYBODY 9997 /* shared between all apps in the same profile */ #define AID_MISC 9998 /* access to misc storage */ #define AID_NOBODY 9999 @@ -151,6 +154,8 @@ static const struct android_id_info android_ids[] = { { "sdcard_pics", AID_SDCARD_PICS, }, { "sdcard_av", AID_SDCARD_AV, }, { "sdcard_all", AID_SDCARD_ALL, }, + { "logd", AID_LOGD, }, + { "shared_relro", AID_SHARED_RELRO, }, { "shell", AID_SHELL, }, { "cache", AID_CACHE, }, @@ -165,6 +170,7 @@ static const struct android_id_info android_ids[] = { { "net_bw_acct", AID_NET_BW_ACCT, }, { "net_bt_stack", AID_NET_BT_STACK, }, + { "everybody", AID_EVERYBODY, }, { "misc", AID_MISC, }, { "nobody", AID_NOBODY, }, }; @@ -196,6 +202,7 @@ static const struct fs_path_config android_dirs[] = { { 00771, AID_SHELL, AID_SHELL, 0, "data/local" }, { 01771, AID_SYSTEM, AID_MISC, 0, "data/misc" }, { 00770, AID_DHCP, AID_DHCP, 0, "data/misc/dhcp" }, + { 00771, AID_SHARED_RELRO, AID_SHARED_RELRO, 0, "data/misc/shared_relro" }, { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" }, { 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" }, { 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" }, @@ -237,7 +244,7 @@ static const struct fs_path_config android_files[] = { /* the following five files are INTENTIONALLY set-uid, but they * are NOT included on user builds. */ - { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/su" }, + { 04750, AID_ROOT, AID_SHELL, 0, "system/xbin/su" }, { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/librank" }, { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procrank" }, { 06755, AID_ROOT, AID_ROOT, 0, "system/xbin/procmem" }, @@ -249,6 +256,7 @@ static const struct fs_path_config android_files[] = { { 00755, AID_ROOT, AID_SHELL, 0, "system/bin/*" }, { 00755, AID_ROOT, AID_ROOT, 0, "system/lib/valgrind/*" }, + { 00755, AID_ROOT, AID_ROOT, 0, "system/lib64/valgrind/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/xbin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "system/vendor/bin/*" }, { 00755, AID_ROOT, AID_SHELL, 0, "vendor/bin/*" }, diff --git a/include/system/audio.h b/include/system/audio.h index aa7ac02..8838e71 100644 --- a/include/system/audio.h +++ b/include/system/audio.h @@ -434,6 +434,14 @@ typedef struct { static const audio_offload_info_t AUDIO_INFO_INITIALIZER = { version: AUDIO_OFFLOAD_INFO_VERSION_CURRENT, size: sizeof(audio_offload_info_t), + sample_rate: 0, + channel_mask: 0, + format: AUDIO_FORMAT_DEFAULT, + stream_type: AUDIO_STREAM_VOICE_CALL, + bit_rate: 0, + duration_us: 0, + has_video: false, + is_streaming: false }; static inline bool audio_is_output_device(audio_devices_t device) @@ -471,12 +479,16 @@ static inline bool audio_is_a2dp_device(audio_devices_t device) static inline bool audio_is_bluetooth_sco_device(audio_devices_t device) { - device &= ~AUDIO_DEVICE_BIT_IN; - if ((popcount(device) == 1) && (device & (AUDIO_DEVICE_OUT_ALL_SCO | - AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET))) - return true; - else - return false; + if ((device & AUDIO_DEVICE_BIT_IN) == 0) { + if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_OUT_ALL_SCO) == 0)) + return true; + } else { + device &= ~AUDIO_DEVICE_BIT_IN; + if ((popcount(device) == 1) && ((device & ~AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) == 0)) + return true; + } + + return false; } static inline bool audio_is_usb_device(audio_devices_t device) diff --git a/include/system/window.h b/include/system/window.h index 588f9c6..31f202f 100644 --- a/include/system/window.h +++ b/include/system/window.h @@ -26,6 +26,13 @@ #include <system/graphics.h> #include <unistd.h> +#ifndef __UNUSED +#define __UNUSED __attribute__((__unused__)) +#endif +#ifndef __deprecated +#define __deprecated __attribute__((__deprecated__)) +#endif + __BEGIN_DECLS /*****************************************************************************/ @@ -89,10 +96,10 @@ typedef struct ANativeWindowBuffer // Implement the methods that sp<ANativeWindowBuffer> expects so that it // can be used to automatically refcount ANativeWindowBuffer's. - void incStrong(const void* id) const { + void incStrong(const void* /*id*/) const { common.incRef(const_cast<android_native_base_t*>(&common)); } - void decStrong(const void* id) const { + void decStrong(const void* /*id*/) const { common.decRef(const_cast<android_native_base_t*>(&common)); } #endif @@ -352,10 +359,10 @@ struct ANativeWindow /* Implement the methods that sp<ANativeWindow> expects so that it can be used to automatically refcount ANativeWindow's. */ - void incStrong(const void* id) const { + void incStrong(const void* /*id*/) const { common.incRef(const_cast<android_native_base_t*>(&common)); } - void decStrong(const void* id) const { + void decStrong(const void* /*id*/) const { common.decRef(const_cast<android_native_base_t*>(&common)); } #endif @@ -582,7 +589,7 @@ struct ANativeWindow * android_native_window_t is deprecated. */ typedef struct ANativeWindow ANativeWindow; -typedef struct ANativeWindow android_native_window_t; +typedef struct ANativeWindow android_native_window_t __deprecated; /* * native_window_set_usage(..., usage) @@ -603,13 +610,19 @@ static inline int native_window_set_usage( /* deprecated. Always returns 0. Don't call. */ static inline int native_window_connect( - struct ANativeWindow* window, int api) { + struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; + +static inline int native_window_connect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) { return 0; } /* deprecated. Always returns 0. Don't call. */ static inline int native_window_disconnect( - struct ANativeWindow* window, int api) { + struct ANativeWindow* window __UNUSED, int api __UNUSED) __deprecated; + +static inline int native_window_disconnect( + struct ANativeWindow* window __UNUSED, int api __UNUSED) { return 0; } @@ -664,6 +677,10 @@ static inline int native_window_set_post_transform_crop( */ static inline int native_window_set_active_rect( struct ANativeWindow* window, + android_native_rect_t const * active_rect) __deprecated; + +static inline int native_window_set_active_rect( + struct ANativeWindow* window, android_native_rect_t const * active_rect) { return native_window_set_post_transform_crop(window, active_rect); @@ -691,6 +708,10 @@ static inline int native_window_set_buffer_count( */ static inline int native_window_set_buffers_geometry( struct ANativeWindow* window, + int w, int h, int format) __deprecated; + +static inline int native_window_set_buffers_geometry( + struct ANativeWindow* window, int w, int h, int format) { return window->perform(window, NATIVE_WINDOW_SET_BUFFERS_GEOMETRY, diff --git a/include/sysutils/FrameworkListener.h b/include/sysutils/FrameworkListener.h index f1a4b43..18049cd 100644 --- a/include/sysutils/FrameworkListener.h +++ b/include/sysutils/FrameworkListener.h @@ -36,6 +36,7 @@ private: public: FrameworkListener(const char *socketName); FrameworkListener(const char *socketName, bool withSeq); + FrameworkListener(int sock); virtual ~FrameworkListener() {} protected: diff --git a/include/sysutils/SocketListener.h b/include/sysutils/SocketListener.h index c204a0f..bc93b86 100644 --- a/include/sysutils/SocketListener.h +++ b/include/sysutils/SocketListener.h @@ -38,6 +38,7 @@ public: virtual ~SocketListener(); int startListener(); + int startListener(int backlog); int stopListener(); void sendBroadcast(int code, const char *msg, bool addErrno); diff --git a/include/utils/Errors.h b/include/utils/Errors.h index 0b75b19..46173db 100644 --- a/include/utils/Errors.h +++ b/include/utils/Errors.h @@ -41,23 +41,23 @@ typedef int32_t status_t; #ifdef _WIN32 # undef NO_ERROR #endif - + enum { OK = 0, // Everything's swell. NO_ERROR = 0, // No errors. - - UNKNOWN_ERROR = 0x80000000, + + UNKNOWN_ERROR = (-2147483647-1), // INT32_MIN value NO_MEMORY = -ENOMEM, INVALID_OPERATION = -ENOSYS, BAD_VALUE = -EINVAL, - BAD_TYPE = 0x80000001, + BAD_TYPE = (UNKNOWN_ERROR + 1), NAME_NOT_FOUND = -ENOENT, PERMISSION_DENIED = -EPERM, NO_INIT = -ENODEV, ALREADY_EXISTS = -EEXIST, DEAD_OBJECT = -EPIPE, - FAILED_TRANSACTION = 0x80000002, + FAILED_TRANSACTION = (UNKNOWN_ERROR + 2), JPARKS_BROKE_IT = -EPIPE, #if !defined(HAVE_MS_C_RUNTIME) BAD_INDEX = -EOVERFLOW, @@ -67,12 +67,12 @@ enum { UNKNOWN_TRANSACTION = -EBADMSG, #else BAD_INDEX = -E2BIG, - NOT_ENOUGH_DATA = 0x80000003, - WOULD_BLOCK = 0x80000004, - TIMED_OUT = 0x80000005, - UNKNOWN_TRANSACTION = 0x80000006, + NOT_ENOUGH_DATA = (UNKNOWN_ERROR + 3), + WOULD_BLOCK = (UNKNOWN_ERROR + 4), + TIMED_OUT = (UNKNOWN_ERROR + 5), + UNKNOWN_TRANSACTION = (UNKNOWN_ERROR + 6), #endif - FDS_NOT_ALLOWED = 0x80000007, + FDS_NOT_ALLOWED = (UNKNOWN_ERROR + 7), }; // Restore define; enumeration is in "android" namespace, so the value defined diff --git a/include/utils/Functor.h b/include/utils/Functor.h index e24ded4..09ea614 100644 --- a/include/utils/Functor.h +++ b/include/utils/Functor.h @@ -25,7 +25,7 @@ class Functor { public: Functor() {} virtual ~Functor() {} - virtual status_t operator ()(int what, void* data) { return NO_ERROR; } + virtual status_t operator ()(int /*what*/, void* /*data*/) { return NO_ERROR; } }; }; // namespace android diff --git a/include/utils/LruCache.h b/include/utils/LruCache.h index 053bfaf..9248ac9 100644 --- a/include/utils/LruCache.h +++ b/include/utils/LruCache.h @@ -56,7 +56,7 @@ public: bool next() { mIndex = mCache.mTable->next(mIndex); - return mIndex != -1; + return (ssize_t)mIndex != -1; } size_t index() const { @@ -103,9 +103,13 @@ private: // Implementation is here, because it's fully templated template <typename TKey, typename TValue> -LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity): mMaxCapacity(maxCapacity), - mNullValue(NULL), mTable(new BasicHashtable<TKey, Entry>), mYoungest(NULL), mOldest(NULL), - mListener(NULL) { +LruCache<TKey, TValue>::LruCache(uint32_t maxCapacity) + : mTable(new BasicHashtable<TKey, Entry>) + , mListener(NULL) + , mOldest(NULL) + , mYoungest(NULL) + , mMaxCapacity(maxCapacity) + , mNullValue(NULL) { }; template<typename K, typename V> diff --git a/include/utils/Unicode.h b/include/utils/Unicode.h index c8c87c3..5b98de2 100644 --- a/include/utils/Unicode.h +++ b/include/utils/Unicode.h @@ -22,8 +22,11 @@ extern "C" { +// Definitions exist in C++11 +#if defined __cplusplus && __cplusplus < 201103L typedef uint32_t char32_t; typedef uint16_t char16_t; +#endif // Standard string functions on char16_t strings. int strcmp16(const char16_t *, const char16_t *); |