auto import from //branches/cupcake/...@132276
This commit is contained in:
parent
2489551343
commit
6f04a0f4c7
@ -216,22 +216,6 @@ int sched_get_priority_max(int policy) 159
|
|||||||
int sched_get_priority_min(int policy) 160
|
int sched_get_priority_min(int policy) 160
|
||||||
int sched_rr_get_interval(pid_t pid, struct timespec *interval) 161
|
int sched_rr_get_interval(pid_t pid, struct timespec *interval) 161
|
||||||
|
|
||||||
# system-V inter-process communication
|
|
||||||
# TODO: implement x86 stubs for these functions when needed (when ?)
|
|
||||||
#
|
|
||||||
int semctl(int semid, int semnum, int cmd, ...) 300,-1
|
|
||||||
int semget(key_t key, int nsems, int semflg) 299,-1
|
|
||||||
int semop(int semid, struct sembuf* sops, size_t nsops) 298,-1
|
|
||||||
void* shmat(int shmid, const void* shmaddr, int shmflg) 305,-1
|
|
||||||
int shmctl(int shmid, int cmd, struct shmid_ds* buf) 308,-1
|
|
||||||
int shmdt(const void* shmaddr) 306,-1
|
|
||||||
int shmget(key_t key, size_t size, int shmflg) 307,-1
|
|
||||||
int msgctl(int msqid, int cmd, struct msqid_ds *buf) 304,-1
|
|
||||||
int msgget(key_t key, int msgflg) 303,-1
|
|
||||||
int msgrcv(int msqid, void* msgp, size_t msgsz, long int msgtyp, int msgflg) 302,-1
|
|
||||||
int msgsnd(int msqid, const void* msgp, size_t msgsz, int msgflg) 301,-1
|
|
||||||
|
|
||||||
|
|
||||||
# other
|
# other
|
||||||
int uname(struct utsname *) 122
|
int uname(struct utsname *) 122
|
||||||
pid_t __wait4:wait4(pid_t pid, int *status, int options, struct rusage *rusage) 114
|
pid_t __wait4:wait4(pid_t pid, int *status, int options, struct rusage *rusage) 114
|
||||||
|
@ -150,17 +150,6 @@ syscall_src += arch-arm/syscalls/sched_getparam.S
|
|||||||
syscall_src += arch-arm/syscalls/sched_get_priority_max.S
|
syscall_src += arch-arm/syscalls/sched_get_priority_max.S
|
||||||
syscall_src += arch-arm/syscalls/sched_get_priority_min.S
|
syscall_src += arch-arm/syscalls/sched_get_priority_min.S
|
||||||
syscall_src += arch-arm/syscalls/sched_rr_get_interval.S
|
syscall_src += arch-arm/syscalls/sched_rr_get_interval.S
|
||||||
syscall_src += arch-arm/syscalls/semctl.S
|
|
||||||
syscall_src += arch-arm/syscalls/semget.S
|
|
||||||
syscall_src += arch-arm/syscalls/semop.S
|
|
||||||
syscall_src += arch-arm/syscalls/shmat.S
|
|
||||||
syscall_src += arch-arm/syscalls/shmctl.S
|
|
||||||
syscall_src += arch-arm/syscalls/shmdt.S
|
|
||||||
syscall_src += arch-arm/syscalls/shmget.S
|
|
||||||
syscall_src += arch-arm/syscalls/msgctl.S
|
|
||||||
syscall_src += arch-arm/syscalls/msgget.S
|
|
||||||
syscall_src += arch-arm/syscalls/msgrcv.S
|
|
||||||
syscall_src += arch-arm/syscalls/msgsnd.S
|
|
||||||
syscall_src += arch-arm/syscalls/uname.S
|
syscall_src += arch-arm/syscalls/uname.S
|
||||||
syscall_src += arch-arm/syscalls/__wait4.S
|
syscall_src += arch-arm/syscalls/__wait4.S
|
||||||
syscall_src += arch-arm/syscalls/umask.S
|
syscall_src += arch-arm/syscalls/umask.S
|
||||||
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type msgctl, #function
|
|
||||||
.globl msgctl
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
msgctl:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_msgctl
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type msgget, #function
|
|
||||||
.globl msgget
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
msgget:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_msgget
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,21 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type msgrcv, #function
|
|
||||||
.globl msgrcv
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
msgrcv:
|
|
||||||
mov ip, sp
|
|
||||||
.save {r4, r5, r6, r7}
|
|
||||||
stmfd sp!, {r4, r5, r6, r7}
|
|
||||||
ldmfd ip, {r4, r5, r6}
|
|
||||||
ldr r7, =__NR_msgrcv
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r5, r6, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type msgsnd, #function
|
|
||||||
.globl msgsnd
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
msgsnd:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_msgsnd
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type semctl, #function
|
|
||||||
.globl semctl
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
semctl:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_semctl
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type semget, #function
|
|
||||||
.globl semget
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
semget:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_semget
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type semop, #function
|
|
||||||
.globl semop
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
semop:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_semop
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type shmat, #function
|
|
||||||
.globl shmat
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
shmat:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_shmat
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type shmctl, #function
|
|
||||||
.globl shmctl
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
shmctl:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_shmctl
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type shmdt, #function
|
|
||||||
.globl shmdt
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
shmdt:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_shmdt
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -1,19 +0,0 @@
|
|||||||
/* autogenerated by gensyscalls.py */
|
|
||||||
#include <sys/linux-syscalls.h>
|
|
||||||
|
|
||||||
.text
|
|
||||||
.type shmget, #function
|
|
||||||
.globl shmget
|
|
||||||
.align 4
|
|
||||||
.fnstart
|
|
||||||
|
|
||||||
shmget:
|
|
||||||
.save {r4, r7}
|
|
||||||
stmfd sp!, {r4, r7}
|
|
||||||
ldr r7, =__NR_shmget
|
|
||||||
swi #0
|
|
||||||
ldmfd sp!, {r4, r7}
|
|
||||||
movs r0, r0
|
|
||||||
bxpl lr
|
|
||||||
b __set_syscall_errno
|
|
||||||
.fnend
|
|
@ -58,6 +58,8 @@
|
|||||||
#define SIZE_FLAG_ZYGOTE_CHILD (1<<31)
|
#define SIZE_FLAG_ZYGOTE_CHILD (1<<31)
|
||||||
#define SIZE_FLAG_MASK (SIZE_FLAG_ZYGOTE_CHILD)
|
#define SIZE_FLAG_MASK (SIZE_FLAG_ZYGOTE_CHILD)
|
||||||
|
|
||||||
|
#define MAX_SIZE_T (~(size_t)0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In a VM process, this is set to 1 after fork()ing out of zygote.
|
* In a VM process, this is set to 1 after fork()ing out of zygote.
|
||||||
*/
|
*/
|
||||||
@ -608,8 +610,16 @@ void chk_free(void* mem)
|
|||||||
|
|
||||||
void* chk_calloc(size_t n_elements, size_t elem_size)
|
void* chk_calloc(size_t n_elements, size_t elem_size)
|
||||||
{
|
{
|
||||||
size_t size = n_elements * elem_size;
|
size_t size;
|
||||||
void* ptr = chk_malloc(size);
|
void* ptr;
|
||||||
|
|
||||||
|
/* Fail on overflow - just to be safe even though this code runs only
|
||||||
|
* within the debugging C library, not the production one */
|
||||||
|
if (n_elements && MAX_SIZE_T / n_elements < elem_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = n_elements * elem_size;
|
||||||
|
ptr = chk_malloc(size);
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
}
|
}
|
||||||
@ -763,8 +773,16 @@ void leak_free(void* mem)
|
|||||||
|
|
||||||
void* leak_calloc(size_t n_elements, size_t elem_size)
|
void* leak_calloc(size_t n_elements, size_t elem_size)
|
||||||
{
|
{
|
||||||
size_t size = n_elements * elem_size;
|
size_t size;
|
||||||
void* ptr = leak_malloc(size);
|
void* ptr;
|
||||||
|
|
||||||
|
/* Fail on overflow - just to be safe even though this code runs only
|
||||||
|
* within the debugging C library, not the production one */
|
||||||
|
if (n_elements && MAX_SIZE_T / n_elements < elem_size) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
size = n_elements * elem_size;
|
||||||
|
ptr = leak_malloc(size);
|
||||||
if (ptr != NULL) {
|
if (ptr != NULL) {
|
||||||
memset(ptr, 0, size);
|
memset(ptr, 0, size);
|
||||||
}
|
}
|
||||||
|
@ -469,7 +469,7 @@ timer_settime( timer_t id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( __likely(!TIMER_ID_IS_WRAPPED(id)) ) {
|
if ( __likely(!TIMER_ID_IS_WRAPPED(id)) ) {
|
||||||
return __timer_gettime( id, ospec );
|
return __timer_settime( id, flags, spec, ospec );
|
||||||
} else {
|
} else {
|
||||||
thr_timer_t* timer = thr_timer_from_id(id);
|
thr_timer_t* timer = thr_timer_from_id(id);
|
||||||
struct timespec expires, now;
|
struct timespec expires, now;
|
||||||
@ -560,11 +560,11 @@ timer_thread_start( void* _arg )
|
|||||||
if (timespec_cmp( &expires, &now ) > 0)
|
if (timespec_cmp( &expires, &now ) > 0)
|
||||||
{
|
{
|
||||||
/* cool, there was no overrun, so compute the
|
/* cool, there was no overrun, so compute the
|
||||||
* relative timeout as 'now - expires', then wait
|
* relative timeout as 'expires - now', then wait
|
||||||
*/
|
*/
|
||||||
int ret;
|
int ret;
|
||||||
struct timespec diff = now;
|
struct timespec diff = expires;
|
||||||
timespec_sub( &diff, &expires );
|
timespec_sub( &diff, &now );
|
||||||
|
|
||||||
ret = __pthread_cond_timedwait_relative(
|
ret = __pthread_cond_timedwait_relative(
|
||||||
&timer->cond, &timer->mutex, &diff);
|
&timer->cond, &timer->mutex, &diff);
|
||||||
|
@ -7,89 +7,93 @@ Core Philosophy:
|
|||||||
|
|
||||||
The core idea behind Bionic's design is: KEEP IT REALLY SIMPLE.
|
The core idea behind Bionic's design is: KEEP IT REALLY SIMPLE.
|
||||||
|
|
||||||
This implies that the C library should only provide lightweight wrappers around kernel
|
This implies that the C library should only provide lightweight wrappers
|
||||||
facilities and not try to be too smart to deal with edge cases.
|
around kernel facilities and not try to be too smart to deal with edge cases.
|
||||||
|
|
||||||
The name "Bionic" comes from the fact that it is part-BSD and part-Linux: its source
|
The name "Bionic" comes from the fact that it is part-BSD and part-Linux:
|
||||||
code consists in a mix of BSD C library pieces with custom Linux-specific bits used
|
its source code consists in a mix of BSD C library pieces with custom
|
||||||
to deal with threads, processes, signals and a few others things.
|
Linux-specific bits used to deal with threads, processes, signals and a few
|
||||||
|
others things.
|
||||||
|
|
||||||
All original BSD pieces carry the BSD copyright disclaimer. Bionic-specific bits
|
All original BSD pieces carry the BSD copyright disclaimer. Bionic-specific
|
||||||
carry the Android Open Source Project copyright disclaimer. And everything is released
|
bits carry the Android Open Source Project copyright disclaimer. And
|
||||||
under the BSD license.
|
everything is released under the BSD license.
|
||||||
|
|
||||||
Architectures:
|
Architectures:
|
||||||
|
|
||||||
Bionic currently supports the ARM and x86 instruction sets. In theory, it should be
|
Bionic currently supports the ARM and x86 instruction sets. In theory, it
|
||||||
possible to support more, but this may require a little work (e.g. adding system
|
should be possible to support more, but this may require a little work (e.g.
|
||||||
call IDs to SYSCALLS.TXT, described below, or modifying the dynamic linker).
|
adding system call IDs to SYSCALLS.TXT, described below, or modifying the
|
||||||
|
dynamic linker).
|
||||||
|
|
||||||
The ARM-specific code is under arch-arm/ and the x86-specific one is under arch-x86/
|
The ARM-specific code is under arch-arm/ and the x86-specific one is under
|
||||||
|
arch-x86/
|
||||||
|
|
||||||
Note that the x86 version is only meant to run on an x86 Android device. We make
|
Note that the x86 version is only meant to run on an x86 Android device. We
|
||||||
absolutely no claim that you could build and use Bionic on a stock x86 Linux
|
make absolutely no claim that you could build and use Bionic on a stock x86
|
||||||
distribution (though that would be cool, so patches are welcomed :-))
|
Linux distribution (though that would be cool, so patches are welcomed :-))
|
||||||
|
|
||||||
Syscall stubs:
|
Syscall stubs:
|
||||||
|
|
||||||
Each system call function is implemented by a tiny assembler source fragment
|
Each system call function is implemented by a tiny assembler source fragment
|
||||||
(called a "syscall stub"), which is generated automatically by tools/gensyscalls.py
|
(called a "syscall stub"), which is generated automatically by
|
||||||
which reads the SYSCALLS.TXT file for input.
|
tools/gensyscalls.py which reads the SYSCALLS.TXT file for input.
|
||||||
|
|
||||||
SYSCALLS.TXT contains the list of all syscall stubs to generate, along with
|
SYSCALLS.TXT contains the list of all syscall stubs to generate, along with
|
||||||
the corresponding syscall numeric identifier (which may differ between ARM and x86),
|
the corresponding syscall numeric identifier (which may differ between ARM
|
||||||
and its signature
|
and x86), and its signature
|
||||||
|
|
||||||
If you modify this file, you may want to use tools/checksyscalls.py which checks
|
If you modify this file, you may want to use tools/checksyscalls.py which
|
||||||
its content against official Linux kernel header files, and will report errors when
|
checks its content against official Linux kernel header files, and will
|
||||||
invalid syscall ids are used.
|
report errors when invalid syscall ids are used.
|
||||||
|
|
||||||
Sometimes, the C library function is really a wrapper that calls the corresponding
|
Sometimes, the C library function is really a wrapper that calls the
|
||||||
syscall with another name. For example, the exit() function is provided by the C
|
corresponding syscall with another name. For example, the exit() function
|
||||||
library and calls the _exit() syscall stub.
|
is provided by the C library and calls the _exit() syscall stub.
|
||||||
|
|
||||||
See SYSCALLS.TXT for documentation and details.
|
See SYSCALLS.TXT for documentation and details.
|
||||||
|
|
||||||
|
|
||||||
time_t:
|
time_t:
|
||||||
|
|
||||||
time_t is 32-bit as defined by the kernel on 32-bit CPUs. A 64-bit version would
|
time_t is 32-bit as defined by the kernel on 32-bit CPUs. A 64-bit version
|
||||||
be preferrable to avoid the Y2038 bug, but the kernel maintainers consider that
|
would be preferrable to avoid the Y2038 bug, but the kernel maintainers
|
||||||
this is not needed at the moment.
|
consider that this is not needed at the moment.
|
||||||
|
|
||||||
Instead, Bionic provides a <time64.h> header that defines a time64_t type, and
|
Instead, Bionic provides a <time64.h> header that defines a time64_t type,
|
||||||
related functions like mktime64(), localtime64(), etc...
|
and related functions like mktime64(), localtime64(), etc...
|
||||||
|
|
||||||
|
|
||||||
Timezone management:
|
Timezone management:
|
||||||
|
|
||||||
The name of the current timezone is taken from the TZ environment variable, if defined.
|
The name of the current timezone is taken from the TZ environment variable,
|
||||||
Otherwise, the system property named 'persist.sys.timezone' is checked instead.
|
if defined. Otherwise, the system property named 'persist.sys.timezone' is
|
||||||
|
checked instead.
|
||||||
|
|
||||||
The zoneinfo timezone database and index files are located under directory
|
The zoneinfo timezone database and index files are located under directory
|
||||||
/system/usr/share/zoneinfo, instead of the more Posix path of /usr/share/zoneinfo
|
/system/usr/share/zoneinfo, instead of the more Posix-compliant path of
|
||||||
|
/usr/share/zoneinfo
|
||||||
|
|
||||||
|
|
||||||
off_t:
|
off_t:
|
||||||
|
|
||||||
For similar reasons, off_t is 32-bit. We define loff_t as the 64-bit variant due
|
For similar reasons, off_t is 32-bit. We define loff_t as the 64-bit variant
|
||||||
to BSD inheritance, but off64_t should be available as a typedef to ease porting of
|
due to BSD inheritance, but off64_t should be available as a typedef to ease
|
||||||
current Linux-specific code.
|
porting of current Linux-specific code.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Linux kernel headers:
|
Linux kernel headers:
|
||||||
|
|
||||||
Bionic comes with its own set of "clean" Linux kernel headers to allow user-space
|
Bionic comes with its own set of "clean" Linux kernel headers to allow
|
||||||
code to use kernel-specific declarations (e.g. IOCTLs, structure declarations,
|
user-space code to use kernel-specific declarations (e.g. IOCTLs, structure
|
||||||
constants, etc...). They are located in:
|
declarations, constants, etc...). They are located in:
|
||||||
|
|
||||||
./kernel/common,
|
./kernel/common,
|
||||||
./kernel/arch-arm
|
./kernel/arch-arm
|
||||||
./kernel/arch-x86
|
./kernel/arch-x86
|
||||||
|
|
||||||
These headers have been generated by a tool (kernel/tools/update-all.py) to only
|
These headers have been generated by a tool (kernel/tools/update-all.py) to
|
||||||
include the public definitions from the original Linux kernel headers.
|
only include the public definitions from the original Linux kernel headers.
|
||||||
|
|
||||||
If you want to know why and how this is done, read kernel/README.TXT to get
|
If you want to know why and how this is done, read kernel/README.TXT to get
|
||||||
all the (gory) details.
|
all the (gory) details.
|
||||||
@ -97,21 +101,23 @@ Linux kernel headers:
|
|||||||
|
|
||||||
PThread implementation:
|
PThread implementation:
|
||||||
|
|
||||||
Bionic's C library comes with its own pthread implementation bundled in. This is
|
Bionic's C library comes with its own pthread implementation bundled in.
|
||||||
different from other historical C libraries which:
|
This is different from other historical C libraries which:
|
||||||
|
|
||||||
- place it in an external library (-lpthread)
|
- place it in an external library (-lpthread)
|
||||||
- play linker tricks with weak symbols at dynamic link time
|
- play linker tricks with weak symbols at dynamic link time
|
||||||
|
|
||||||
The support for real-time features (a.k.a. -lrt) is also bundled in the C library.
|
The support for real-time features (a.k.a. -lrt) is also bundled in the
|
||||||
|
C library.
|
||||||
|
|
||||||
The implementation is based on futexes and strives to provide *very* short code paths
|
The implementation is based on futexes and strives to provide *very* short
|
||||||
for common operations. Notable features are the following:
|
code paths for common operations. Notable features are the following:
|
||||||
|
|
||||||
- pthread_mutex_t, pthread_cond_t are only 4 bytes each.
|
- pthread_mutex_t, pthread_cond_t are only 4 bytes each.
|
||||||
|
|
||||||
- Normal, recursive and error-check mutexes are supported, and the code path
|
- Normal, recursive and error-check mutexes are supported, and the code
|
||||||
is heavily optimized for the normal case, which is used most of the time.
|
path is heavily optimized for the normal case, which is used most of
|
||||||
|
the time.
|
||||||
|
|
||||||
- Process-shared mutexes and condition variables are not supported.
|
- Process-shared mutexes and condition variables are not supported.
|
||||||
Their implementation requires far more complexity and was absolutely
|
Their implementation requires far more complexity and was absolutely
|
||||||
@ -123,8 +129,9 @@ PThread implementation:
|
|||||||
paths slightly slower though).
|
paths slightly slower though).
|
||||||
|
|
||||||
- There is currently no support for read/write locks, priority-ceiling in
|
- There is currently no support for read/write locks, priority-ceiling in
|
||||||
mutexes and other more advanced features. Again, the main idea being that
|
mutexes and other more advanced features. Again, the main idea being
|
||||||
this was not needed for Android at all but could be added in the future.
|
that this was not needed for Android at all but could be added in the
|
||||||
|
future.
|
||||||
|
|
||||||
pthread_cancel():
|
pthread_cancel():
|
||||||
|
|
||||||
@ -134,13 +141,13 @@ pthread_cancel():
|
|||||||
Consider that:
|
Consider that:
|
||||||
|
|
||||||
- A proper implementation must insert pthread cancellation checks in a lot
|
- A proper implementation must insert pthread cancellation checks in a lot
|
||||||
of different places of the C library. And conformance is very difficult to
|
of different places of the C library. And conformance is very difficult
|
||||||
test properly.
|
to test properly.
|
||||||
|
|
||||||
- A proper implementation must also clean up resources, like releasing memory,
|
- A proper implementation must also clean up resources, like releasing
|
||||||
or unlocking mutexes, properly if the cancellation happens in a complex
|
memory, or unlocking mutexes, properly if the cancellation happens in a
|
||||||
function (e.g. inside gethostbyname() or fprintf() + complex formatting
|
complex function (e.g. inside gethostbyname() or fprintf() + complex
|
||||||
rules). This tends to slow down the path of many functions.
|
formatting rules). This tends to slow down the path of many functions.
|
||||||
|
|
||||||
- pthread cancellation cannot stop all threads: e.g. it can't do anything
|
- pthread cancellation cannot stop all threads: e.g. it can't do anything
|
||||||
against an infinite loop
|
against an infinite loop
|
||||||
@ -151,18 +158,20 @@ pthread_cancel():
|
|||||||
All of this is contrary to the Bionic design goals. If your code depends on
|
All of this is contrary to the Bionic design goals. If your code depends on
|
||||||
thread cancellation, please consider alternatives.
|
thread cancellation, please consider alternatives.
|
||||||
|
|
||||||
Note however that Bionic does implement pthread_cleanup_push() and pthread_cleanup_pop(),
|
Note however that Bionic does implement pthread_cleanup_push() and
|
||||||
which can be used to handle cleanups that happen when a thread voluntarily exits
|
pthread_cleanup_pop(), which can be used to handle cleanups that happen when
|
||||||
through pthread_exit() or returning from its main function.
|
a thread voluntarily exits through pthread_exit() or returning from its
|
||||||
|
main function.
|
||||||
|
|
||||||
|
|
||||||
pthread_once():
|
pthread_once():
|
||||||
|
|
||||||
Do not call fork() within a callback provided to pthread_once(). Doing this
|
Do not call fork() within a callback provided to pthread_once(). Doing this
|
||||||
may result in a deadlock in the child process the next time it calls pthread_once().
|
may result in a deadlock in the child process the next time it calls
|
||||||
|
pthread_once().
|
||||||
|
|
||||||
Also, you can't throw a C++ Exception from the callback (see C++ Exception Support
|
Also, you can't throw a C++ Exception from the callback (see C++ Exception
|
||||||
below).
|
Support below).
|
||||||
|
|
||||||
The current implementation of pthread_once() lacks the necessary support of
|
The current implementation of pthread_once() lacks the necessary support of
|
||||||
multi-core-safe double-checked-locking (read and write barriers).
|
multi-core-safe double-checked-locking (read and write barriers).
|
||||||
@ -170,27 +179,27 @@ pthread_once():
|
|||||||
|
|
||||||
Thread-specific data
|
Thread-specific data
|
||||||
|
|
||||||
The thread-specific storage only provides for a bit less than 64 pthread_key_t
|
The thread-specific storage only provides for a bit less than 64
|
||||||
objects to each process. The implementation provides 64 real slots but also
|
pthread_key_t objects to each process. The implementation provides 64 real
|
||||||
uses about 5 of them (exact number may depend on implementation) for its
|
slots but also uses about 5 of them (exact number may depend on
|
||||||
own use (e.g. two slots are pre-allocated by the C library to speed-up the
|
implementation) for its own use (e.g. two slots are pre-allocated by the C
|
||||||
Android OpenGL sub-system).
|
library to speed-up the Android OpenGL sub-system).
|
||||||
|
|
||||||
Note that Posix mandates a minimum of 128 slots, but we do not claim to be
|
Note that Posix mandates a minimum of 128 slots, but we do not claim to be
|
||||||
Posix-compliant.
|
Posix-compliant.
|
||||||
|
|
||||||
Except for the main thread, the TLS area is stored at the top of the stack. See
|
Except for the main thread, the TLS area is stored at the top of the stack.
|
||||||
comments in bionic/libc/bionic/pthread.c for details.
|
See comments in bionic/libc/bionic/pthread.c for details.
|
||||||
|
|
||||||
At the moment, thread-local storage defined through the __thread compiler keyword
|
At the moment, thread-local storage defined through the __thread compiler
|
||||||
is not supported by the Bionic C library and dynamic linker.
|
keyword is not supported by the Bionic C library and dynamic linker.
|
||||||
|
|
||||||
|
|
||||||
Multi-core support
|
Multi-core support
|
||||||
|
|
||||||
At the moment, Bionic does not provide or use read/write memory barriers.
|
At the moment, Bionic does not provide or use read/write memory barriers.
|
||||||
This means that using it on certain multi-core systems might not be supported,
|
This means that using it on certain multi-core systems might not be
|
||||||
depending on its exact CPU architecture.
|
supported, depending on its exact CPU architecture.
|
||||||
|
|
||||||
|
|
||||||
Android-specific features:
|
Android-specific features:
|
||||||
@ -201,67 +210,69 @@ Android-specific features:
|
|||||||
|
|
||||||
Android provides a simple shared value/key space to all processes on the
|
Android provides a simple shared value/key space to all processes on the
|
||||||
system. It stores a liberal number of 'properties', each of them being a
|
system. It stores a liberal number of 'properties', each of them being a
|
||||||
simple size-limited string that can be associated to a size-limited string
|
simple size-limited string that can be associated to a size-limited
|
||||||
value.
|
string value.
|
||||||
|
|
||||||
The header <sys/system_properties.h> can be used to read system properties
|
The header <sys/system_properties.h> can be used to read system
|
||||||
and also defines the maximum size of keys and values.
|
properties and also defines the maximum size of keys and values.
|
||||||
|
|
||||||
- Android-specific user/group management:
|
- Android-specific user/group management:
|
||||||
|
|
||||||
There is no /etc/passwd or /etc/groups in Android. By design, it is meant to
|
There is no /etc/passwd or /etc/groups in Android. By design, it is
|
||||||
be used by a single handset user. On the other hand, Android uses the Linux
|
meant to be used by a single handset user. On the other hand, Android
|
||||||
user/group management features extensively to secure process permissions,
|
uses the Linux user/group management features extensively to secure
|
||||||
like access to various filesystem directories.
|
process permissions, like access to various filesystem directories.
|
||||||
|
|
||||||
In the Android scheme, each installed application gets its own uid_t/gid_t
|
In the Android scheme, each installed application gets its own
|
||||||
starting from 10000; lower numerical ids are reserved for system daemons.
|
uid_t/gid_t starting from 10000; lower numerical ids are reserved for
|
||||||
|
system daemons.
|
||||||
|
|
||||||
getpwnam() recognizes some hard-coded subsystems names (e.g. "radio") and
|
getpwnam() recognizes some hard-coded subsystems names (e.g. "radio")
|
||||||
will translate them to their low-user-id values. It also recognizes "app_1234"
|
and will translate them to their low-user-id values. It also recognizes
|
||||||
as the synthetic name of the application that was installed with uid 10000 + 1234,
|
"app_1234" as the synthetic name of the application that was installed
|
||||||
which is 11234. getgrnam() works similarly
|
with uid 10000 + 1234, which is 11234. getgrnam() works similarly
|
||||||
|
|
||||||
getgrouplist() will always return a single group for any user name, which is
|
getgrouplist() will always return a single group for any user name,
|
||||||
the one passed as an input parameter.
|
which is the one passed as an input parameter.
|
||||||
|
|
||||||
getgrgid() will similarly only return a structure that contains a single-element
|
getgrgid() will similarly only return a structure that contains a
|
||||||
members list, corresponding to the user with the same numerical value than the
|
single-element members list, corresponding to the user with the same
|
||||||
group.
|
numerical value than the group.
|
||||||
|
|
||||||
See bionic/libc/bionic/stubs.c for more details.
|
See bionic/libc/bionic/stubs.c for more details.
|
||||||
|
|
||||||
- getservent()
|
- getservent()
|
||||||
|
|
||||||
There is no /etc/services on Android. Instead the C library embeds a constant
|
There is no /etc/services on Android. Instead the C library embeds a
|
||||||
list of services in its executable, which is parsed on demand by the various
|
constant list of services in its executable, which is parsed on demand
|
||||||
functions that depend on it. See bionic/libc/netbsd/net/getservent.c and
|
by the various functions that depend on it. See
|
||||||
|
bionic/libc/netbsd/net/getservent.c and
|
||||||
bionic/libc/netbsd/net/services.h
|
bionic/libc/netbsd/net/services.h
|
||||||
|
|
||||||
The list of services defined internally might change liberally in the future.
|
The list of services defined internally might change liberally in the
|
||||||
This feature is mostly historically and is very rarely used.
|
future. This feature is mostly historically and is very rarely used.
|
||||||
|
|
||||||
The getservent() returns thread-local data. getservbyport() and getservbyname()
|
The getservent() returns thread-local data. getservbyport() and
|
||||||
are also implemented in a similar fashion.
|
getservbyname() are also implemented in a similar fashion.
|
||||||
|
|
||||||
- getprotoent()
|
- getprotoent()
|
||||||
|
|
||||||
There is no /etc/protocol on Android. Bionic does not currently implement
|
There is no /etc/protocol on Android. Bionic does not currently
|
||||||
getprotoent() and related functions. If we add it, it will likely be done
|
implement getprotoent() and related functions. If added, it will
|
||||||
in a way similar to getservent()
|
likely be done in a way similar to getservent()
|
||||||
|
|
||||||
DNS resolver:
|
DNS resolver:
|
||||||
|
|
||||||
Bionic uses a NetBSD-derived resolver library which has been modified in the following
|
Bionic uses a NetBSD-derived resolver library which has been modified in
|
||||||
ways:
|
the following ways:
|
||||||
|
|
||||||
- don't implement the name-server-switch feature (a.k.a. <nsswitch.h>)
|
- don't implement the name-server-switch feature (a.k.a. <nsswitch.h>)
|
||||||
|
|
||||||
- read /system/etc/resolv.conf instead of /etc/resolv.conf
|
- read /system/etc/resolv.conf instead of /etc/resolv.conf
|
||||||
|
|
||||||
- read the list of servers from system properties. the code looks for
|
- read the list of servers from system properties. the code looks for
|
||||||
'net.dns1', 'net.dns2', etc.. Each property should contain the IP address
|
'net.dns1', 'net.dns2', etc.. Each property should contain the IP
|
||||||
of a DNS server.
|
address of a DNS server.
|
||||||
|
|
||||||
these properties are set/modified by other parts of the Android system
|
these properties are set/modified by other parts of the Android system
|
||||||
(e.g. the dhcpd daemon).
|
(e.g. the dhcpd daemon).
|
||||||
@ -278,9 +289,9 @@ DNS resolver:
|
|||||||
|
|
||||||
- get rid of *many* unfortunate thread-safety issues in the original code
|
- get rid of *many* unfortunate thread-safety issues in the original code
|
||||||
|
|
||||||
Bionic does *not* expose implementation details of its DNS resolver; the content
|
Bionic does *not* expose implementation details of its DNS resolver; the
|
||||||
of <arpa/nameser.h> is intentionally blank. The resolver implementation might
|
content of <arpa/nameser.h> is intentionally blank. The resolver
|
||||||
change completely in the future.
|
implementation might change completely in the future.
|
||||||
|
|
||||||
|
|
||||||
PThread Real-Time Timers:
|
PThread Real-Time Timers:
|
||||||
@ -294,8 +305,8 @@ PThread Real-Time Timers:
|
|||||||
timers with compatible properties are used.
|
timers with compatible properties are used.
|
||||||
|
|
||||||
This means that if your code uses a lot of SIGEV_THREAD timers, your program
|
This means that if your code uses a lot of SIGEV_THREAD timers, your program
|
||||||
may consume a lot of memory. However, if your program needs many of these timers,
|
may consume a lot of memory. However, if your program needs many of these
|
||||||
it'd better handle timeout events directly instead.
|
timers, it'd better handle timeout events directly instead.
|
||||||
|
|
||||||
Other timers (e.g. SIGEV_SIGNAL) are handled by the kernel and use much less
|
Other timers (e.g. SIGEV_SIGNAL) are handled by the kernel and use much less
|
||||||
system resources.
|
system resources.
|
||||||
@ -303,58 +314,71 @@ PThread Real-Time Timers:
|
|||||||
|
|
||||||
Binary Compatibility:
|
Binary Compatibility:
|
||||||
|
|
||||||
Bionic is *not* in any way binary-compatible with the GNU C Library, ucLibc or any
|
Bionic is *not* in any way binary-compatible with the GNU C Library, ucLibc
|
||||||
known Linux C library. This means several things:
|
or any known Linux C library. This means several things:
|
||||||
|
|
||||||
- You cannot expect to build something against the GNU C Library headers and have
|
- You cannot expect to build something against the GNU C Library headers and
|
||||||
it dynamically link properly to Bionic later.
|
have it dynamically link properly to Bionic later.
|
||||||
|
|
||||||
- You should *really* use the Android toolchain to build your program against Bionic.
|
- You should *really* use the Android toolchain to build your program against
|
||||||
The toolchain deals with many important details that are crucial to get something
|
Bionic. The toolchain deals with many important details that are crucial
|
||||||
working properly.
|
to get something working properly.
|
||||||
|
|
||||||
Failure to do so will usually result in the inability to run or link your program,
|
Failure to do so will usually result in the inability to run or link your
|
||||||
or even runtime crashes. Several random web pages on the Internet describe how you
|
program, or even runtime crashes. Several random web pages on the Internet
|
||||||
can succesfully write a "hello-world" program with the ARM GNU toolchain. These
|
describe how you can succesfully write a "hello-world" program with the
|
||||||
examples usually work by chance, if anything else, and you should not follow these
|
ARM GNU toolchain. These examples usually work by chance, if anything else,
|
||||||
instructions unless you want to waste a lot of your time in the process.
|
and you should not follow these instructions unless you want to waste a lot
|
||||||
|
of your time in the process.
|
||||||
|
|
||||||
|
Note however that you *can* generate a binary that is built against the
|
||||||
|
GNU C Library headers and then statically linked to it. The corresponding
|
||||||
|
executable should be able to run (if it doesn't use dlopen()/dlsym())
|
||||||
|
|
||||||
Note however that you *can* generate a binary that is built against the GNU C Library
|
|
||||||
headers and then statically linked to it. The corresponding executable should be able
|
|
||||||
to run (if it doesn't use dlopen()/dlsym())
|
|
||||||
|
|
||||||
Dynamic Linker:
|
Dynamic Linker:
|
||||||
|
|
||||||
Bionic comes with its own dynamic linker (just like ld.so on Linux really comes from
|
Bionic comes with its own dynamic linker (just like ld.so on Linux really
|
||||||
GLibc). This linker does not support all the relocations generated by other GCC ARM
|
comes from GLibc). This linker does not support all the relocations
|
||||||
toolchains.
|
generated by other GCC ARM toolchains.
|
||||||
|
|
||||||
|
|
||||||
C++ Exceptions Support:
|
C++ Exceptions Support:
|
||||||
|
|
||||||
At the moment, Bionic doesn't support C++ exceptions, what this really means is the
|
At the moment, Bionic doesn't support C++ exceptions, what this really means
|
||||||
following:
|
is the following:
|
||||||
|
|
||||||
- If pthread_once() is called with a C++ callback that throws an exception,
|
- If pthread_once() is called with a C++ callback that throws an exception,
|
||||||
then the C library will keep the corresponding pthread_once_t mutex locked.
|
then the C library will keep the corresponding pthread_once_t mutex
|
||||||
Any further call to pthread_once() will result in a deadlock.
|
locked. Any further call to pthread_once() will result in a deadlock.
|
||||||
|
|
||||||
A proper implementation should be able to register a C++ exception cleanup
|
A proper implementation should be able to register a C++ exception
|
||||||
handler before the callback to properly unlock the pthread_once_t. Unfortunately
|
cleanup handler before the callback to properly unlock the
|
||||||
this requires tricky assembly code that is highly dependent on the compiler.
|
pthread_once_t. Unfortunately this requires tricky assembly code that
|
||||||
|
is highly dependent on the compiler.
|
||||||
|
|
||||||
This feature is not planned to be supported anytime soon.
|
This feature is not planned to be supported anytime soon.
|
||||||
|
|
||||||
- The same problem may arise if you throw an exception within a callback called
|
- The same problem may arise if you throw an exception within a callback
|
||||||
from the C library. Fortunately, these cases are very rare in the real-world,
|
called from the C library. Fortunately, these cases are very rare in the
|
||||||
but any callback you provide to the C library should *not* throw an exception.
|
real-world, but any callback you provide to the C library should *not*
|
||||||
|
throw an exception.
|
||||||
|
|
||||||
- Bionic lacks a few support functions to have exception support work properly.
|
- Bionic lacks a few support functions to have exception support work
|
||||||
|
properly.
|
||||||
|
|
||||||
|
System V IPCs:
|
||||||
|
|
||||||
|
Bionic intentionally does not provide support for System-V IPCs mechanisms,
|
||||||
|
like the ones provided by semget(), shmget(), msgget(). The reason for this
|
||||||
|
is to avoid denial-of-service. For a detailed rationale about this, please
|
||||||
|
read the file docs/SYSV-IPCS.TXT.
|
||||||
|
|
||||||
Include Paths:
|
Include Paths:
|
||||||
|
|
||||||
The Android build system should automatically provide the necessary include paths
|
The Android build system should automatically provide the necessary include
|
||||||
required to build against the C library headers. However, if you want to do that
|
paths required to build against the C library headers. However, if you want
|
||||||
yourself, you will need to add:
|
to do that yourself, you will need to add:
|
||||||
|
|
||||||
libc/arch-$ARCH/include
|
libc/arch-$ARCH/include
|
||||||
libc/include
|
libc/include
|
||||||
|
103
libc/docs/SYSV-IPC.TXT
Normal file
103
libc/docs/SYSV-IPC.TXT
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
Android does not support System V IPCs, i.e. the facilities provided by the
|
||||||
|
following standard Posix headers:
|
||||||
|
|
||||||
|
<sys/sem.h> /* SysV semaphores */
|
||||||
|
<sys/shm.h> /* SysV shared memory segments */
|
||||||
|
<sys/msg.h> /* SysV message queues */
|
||||||
|
<sys/ipc.h> /* General IPC definitions */
|
||||||
|
|
||||||
|
The reason for this is due to the fact that, by design, they lead to global
|
||||||
|
kernel resource leakage.
|
||||||
|
|
||||||
|
For example, there is no way to automatically release a SysV semaphore
|
||||||
|
allocated in the kernel when:
|
||||||
|
|
||||||
|
- a buggy or malicious process exits
|
||||||
|
- a non-buggy and non-malicious process crashes or is explicitely killed.
|
||||||
|
|
||||||
|
Killing processes automatically to make room for new ones is an
|
||||||
|
important part of Android's application lifecycle implementation. This means
|
||||||
|
that, even assuming only non-buggy and non-malicious code, it is very likely
|
||||||
|
that over time, the kernel global tables used to implement SysV IPCs will fill
|
||||||
|
up.
|
||||||
|
|
||||||
|
At that point, strange failures are likely to occur and prevent programs that
|
||||||
|
use them to run properly until the next reboot of the system.
|
||||||
|
|
||||||
|
And we can't ignore potential malicious applications. As a proof of concept
|
||||||
|
here is a simple exploit that you can run on a standard Linux box today:
|
||||||
|
|
||||||
|
--------------- cut here ------------------------
|
||||||
|
#include <sys/sem.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#define NUM_SEMAPHORES 32
|
||||||
|
#define MAX_FAILS 10
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int counter = 0;
|
||||||
|
int fails = 0;
|
||||||
|
|
||||||
|
if (counter == IPC_PRIVATE)
|
||||||
|
counter++;
|
||||||
|
|
||||||
|
printf( "%d (NUM_SEMAPHORES=%d)\n", counter, NUM_SEMAPHORES);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
int ret = fork();
|
||||||
|
int status;
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("fork:");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret == 0) {
|
||||||
|
/* in the child */
|
||||||
|
ret = semget( (key_t)counter, NUM_SEMAPHORES, IPC_CREAT );
|
||||||
|
if (ret < 0) {
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* in the parent */
|
||||||
|
ret = wait(&status);
|
||||||
|
if (ret < 0) {
|
||||||
|
perror("waitpid:");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (status != 0) {
|
||||||
|
status = WEXITSTATUS(status);
|
||||||
|
fprintf(stderr, "child %d FAIL at counter=%d: %d\n", ret,
|
||||||
|
counter, status);
|
||||||
|
if (++fails >= MAX_FAILS)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
counter++;
|
||||||
|
if ((counter % 1000) == 0) {
|
||||||
|
printf("%d\n", counter);
|
||||||
|
}
|
||||||
|
if (counter == IPC_PRIVATE)
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
--------------- cut here ------------------------
|
||||||
|
|
||||||
|
If you run it on a typical Linux distribution today, you'll discover that it
|
||||||
|
will quickly fill up the kernel's table of unique key_t values, and that
|
||||||
|
strange things will happen in some parts of the system, but not all.
|
||||||
|
|
||||||
|
(You can use the "ipcs -u" command to get a summary describing the kernel
|
||||||
|
tables and their allocations)
|
||||||
|
|
||||||
|
For example, in our experience, anything program launched after that that
|
||||||
|
calls strerror() will simply crash. The USB sub-system starts spoutting weird
|
||||||
|
errors to the system console, etc...
|
@ -170,17 +170,6 @@
|
|||||||
#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
|
#define __NR_getsockopt (__NR_SYSCALL_BASE + 295)
|
||||||
#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
|
#define __NR_sendmsg (__NR_SYSCALL_BASE + 296)
|
||||||
#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
|
#define __NR_recvmsg (__NR_SYSCALL_BASE + 297)
|
||||||
#define __NR_semctl (__NR_SYSCALL_BASE + 300)
|
|
||||||
#define __NR_semget (__NR_SYSCALL_BASE + 299)
|
|
||||||
#define __NR_semop (__NR_SYSCALL_BASE + 298)
|
|
||||||
#define __NR_shmat (__NR_SYSCALL_BASE + 305)
|
|
||||||
#define __NR_shmctl (__NR_SYSCALL_BASE + 308)
|
|
||||||
#define __NR_shmdt (__NR_SYSCALL_BASE + 306)
|
|
||||||
#define __NR_shmget (__NR_SYSCALL_BASE + 307)
|
|
||||||
#define __NR_msgctl (__NR_SYSCALL_BASE + 304)
|
|
||||||
#define __NR_msgget (__NR_SYSCALL_BASE + 303)
|
|
||||||
#define __NR_msgrcv (__NR_SYSCALL_BASE + 302)
|
|
||||||
#define __NR_msgsnd (__NR_SYSCALL_BASE + 301)
|
|
||||||
#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
|
#define __NR_epoll_create (__NR_SYSCALL_BASE + 250)
|
||||||
#define __NR_epoll_ctl (__NR_SYSCALL_BASE + 251)
|
#define __NR_epoll_ctl (__NR_SYSCALL_BASE + 251)
|
||||||
#define __NR_epoll_wait (__NR_SYSCALL_BASE + 252)
|
#define __NR_epoll_wait (__NR_SYSCALL_BASE + 252)
|
||||||
|
@ -179,17 +179,6 @@ int sched_getparam (pid_t pid, struct sched_param *param);
|
|||||||
int sched_get_priority_max (int policy);
|
int sched_get_priority_max (int policy);
|
||||||
int sched_get_priority_min (int policy);
|
int sched_get_priority_min (int policy);
|
||||||
int sched_rr_get_interval (pid_t pid, struct timespec *interval);
|
int sched_rr_get_interval (pid_t pid, struct timespec *interval);
|
||||||
int semctl (int semid, int semnum, int cmd, ...);
|
|
||||||
int semget (key_t key, int nsems, int semflg);
|
|
||||||
int semop (int semid, struct sembuf* sops, size_t nsops);
|
|
||||||
void* shmat (int shmid, const void* shmaddr, int shmflg);
|
|
||||||
int shmctl (int shmid, int cmd, struct shmid_ds* buf);
|
|
||||||
int shmdt (const void* shmaddr);
|
|
||||||
int shmget (key_t key, size_t size, int shmflg);
|
|
||||||
int msgctl (int msqid, int cmd, struct msqid_ds *buf);
|
|
||||||
int msgget (key_t key, int msgflg);
|
|
||||||
int msgrcv (int msqid, void* msgp, size_t msgsz, long int msgtyp, int msgflg);
|
|
||||||
int msgsnd (int msqid, const void* msgp, size_t msgsz, int msgflg);
|
|
||||||
int uname (struct utsname *);
|
int uname (struct utsname *);
|
||||||
pid_t __wait4 (pid_t pid, int *status, int options, struct rusage *rusage);
|
pid_t __wait4 (pid_t pid, int *status, int options, struct rusage *rusage);
|
||||||
mode_t umask (mode_t);
|
mode_t umask (mode_t);
|
||||||
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 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 _SYS_MSG_H
|
|
||||||
#define _SYS_MSG_H
|
|
||||||
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <linux/msg.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
|
|
||||||
extern int msgctl(int msqid, int cmd, struct msqid_ds *buf);
|
|
||||||
extern int msgget(key_t key, int msgflg);
|
|
||||||
extern int msgrcv(int msqid, void* msgp, size_t msgsz, long int msgtyp, int msgflg);
|
|
||||||
extern int msgsnd(int msqid, const void* msgp, size_t msgsz, int msgflg);
|
|
||||||
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif /* _SYS_MSG_H */
|
|
@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright (C) 2008 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 _SYS_SHM_H
|
|
||||||
#define _SYS_SHM_H
|
|
||||||
|
|
||||||
#include <sys/ipc.h>
|
|
||||||
#include <linux/shm.h>
|
|
||||||
|
|
||||||
__BEGIN_DECLS
|
|
||||||
|
|
||||||
extern void* shmat(int shmid, const void* shmaddr, int shmflg);
|
|
||||||
extern int shmctl(int shmid, int cmd, struct shmid_ds* buf);
|
|
||||||
extern int shmdt(const void* shmaddr);
|
|
||||||
extern int shmget(key_t key, size_t size, int shmflg);
|
|
||||||
|
|
||||||
__END_DECLS
|
|
||||||
|
|
||||||
#endif /* _SYS_SHM_H */
|
|
@ -29,6 +29,10 @@
|
|||||||
#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
|
#define AUDIO_SET_EQ _IOW(AUDIO_IOCTL_MAGIC, 8, unsigned)
|
||||||
#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
|
#define AUDIO_SET_RX_IIR _IOW(AUDIO_IOCTL_MAGIC, 9, unsigned)
|
||||||
#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
|
#define AUDIO_SET_VOLUME _IOW(AUDIO_IOCTL_MAGIC, 10, unsigned)
|
||||||
|
#define AUDIO_ENABLE_AUDPRE _IOW(AUDIO_IOCTL_MAGIC, 11, unsigned)
|
||||||
|
#define AUDIO_SET_AGC _IOW(AUDIO_IOCTL_MAGIC, 12, unsigned)
|
||||||
|
#define AUDIO_SET_NS _IOW(AUDIO_IOCTL_MAGIC, 13, unsigned)
|
||||||
|
#define AUDIO_SET_TX_IIR _IOW(AUDIO_IOCTL_MAGIC, 14, unsigned)
|
||||||
|
|
||||||
struct msm_audio_config {
|
struct msm_audio_config {
|
||||||
uint32_t buffer_size;
|
uint32_t buffer_size;
|
||||||
|
@ -626,37 +626,12 @@ gethostbyname_internal(const char *name, int af, res_state res)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ANDROID_CHANGES
|
|
||||||
cache = __get_res_cache();
|
|
||||||
if (cache != NULL) {
|
|
||||||
hp = _resolv_cache_lookup( cache, name, af );
|
|
||||||
if (hp == _RESOLV_HOSTENT_NONE) {
|
|
||||||
h_errno = HOST_NOT_FOUND;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
if (hp != NULL) {
|
|
||||||
h_errno = NETDB_SUCCESS;
|
|
||||||
return hp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hp = NULL;
|
hp = NULL;
|
||||||
h_errno = NETDB_INTERNAL;
|
h_errno = NETDB_INTERNAL;
|
||||||
if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyname",
|
if (nsdispatch(&hp, dtab, NSDB_HOSTS, "gethostbyname",
|
||||||
default_dns_files, name, strlen(name), af) != NS_SUCCESS) {
|
default_dns_files, name, strlen(name), af) != NS_SUCCESS) {
|
||||||
#ifdef ANDROID_CHANGES
|
|
||||||
/* cache negative DNS entry */
|
|
||||||
if (h_errno == HOST_NOT_FOUND && cache != NULL)
|
|
||||||
_resolv_cache_add( cache, name, af, _RESOLV_HOSTENT_NONE );
|
|
||||||
#endif
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
#ifdef ANDROID_CHANGES
|
|
||||||
if (cache != NULL) {
|
|
||||||
_resolv_cache_add( cache, name, af, hp );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
h_errno = NETDB_SUCCESS;
|
h_errno = NETDB_SUCCESS;
|
||||||
return hp;
|
return hp;
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -81,6 +81,9 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
|
|||||||
#endif
|
#endif
|
||||||
#endif /* LIBC_SCCS and not lint */
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
/* set to 1 to use our small/simple/limited DNS cache */
|
||||||
|
#define USE_RESOLV_CACHE 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send query to name server and wait for reply.
|
* Send query to name server and wait for reply.
|
||||||
*/
|
*/
|
||||||
@ -111,6 +114,10 @@ __RCSID("$NetBSD: res_send.c,v 1.9 2006/01/24 17:41:25 christos Exp $");
|
|||||||
|
|
||||||
#include <isc/eventlib.h>
|
#include <isc/eventlib.h>
|
||||||
|
|
||||||
|
#if USE_RESOLV_CACHE
|
||||||
|
# include <resolv_cache.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef DE_CONST
|
#ifndef DE_CONST
|
||||||
#define DE_CONST(c,v) v = ((c) ? \
|
#define DE_CONST(c,v) v = ((c) ? \
|
||||||
strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL)
|
strchr((const void *)(c), *(const char *)(const void *)(c)) : NULL)
|
||||||
@ -344,12 +351,17 @@ res_queriesmatch(const u_char *buf1, const u_char *eom1,
|
|||||||
return (1);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
res_nsend(res_state statp,
|
res_nsend(res_state statp,
|
||||||
const u_char *buf, int buflen, u_char *ans, int anssiz)
|
const u_char *buf, int buflen, u_char *ans, int anssiz)
|
||||||
{
|
{
|
||||||
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
|
int gotsomewhere, terrno, try, v_circuit, resplen, ns, n;
|
||||||
char abuf[NI_MAXHOST];
|
char abuf[NI_MAXHOST];
|
||||||
|
#if USE_RESOLV_CACHE
|
||||||
|
struct resolv_cache* cache;
|
||||||
|
ResolvCacheStatus cache_status = RESOLV_CACHE_UNSUPPORTED;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (statp->nscount == 0) {
|
if (statp->nscount == 0) {
|
||||||
errno = ESRCH;
|
errno = ESRCH;
|
||||||
@ -365,6 +377,20 @@ res_nsend(res_state statp,
|
|||||||
gotsomewhere = 0;
|
gotsomewhere = 0;
|
||||||
terrno = ETIMEDOUT;
|
terrno = ETIMEDOUT;
|
||||||
|
|
||||||
|
#if USE_RESOLV_CACHE
|
||||||
|
cache = __get_res_cache();
|
||||||
|
if (cache != NULL) {
|
||||||
|
int anslen = 0;
|
||||||
|
cache_status = _resolv_cache_lookup(
|
||||||
|
cache, buf, buflen,
|
||||||
|
ans, anssiz, &anslen);
|
||||||
|
|
||||||
|
if (cache_status == RESOLV_CACHE_FOUND) {
|
||||||
|
return anslen;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the ns_addr_list in the resolver context has changed, then
|
* If the ns_addr_list in the resolver context has changed, then
|
||||||
* invalidate our cached copy and the associated timing data.
|
* invalidate our cached copy and the associated timing data.
|
||||||
@ -534,6 +560,12 @@ res_nsend(res_state statp,
|
|||||||
(stdout, "%s", ""),
|
(stdout, "%s", ""),
|
||||||
ans, (resplen > anssiz) ? anssiz : resplen);
|
ans, (resplen > anssiz) ? anssiz : resplen);
|
||||||
|
|
||||||
|
#if USE_RESOLV_CACHE
|
||||||
|
if (cache_status == RESOLV_CACHE_NOTFOUND) {
|
||||||
|
_resolv_cache_add(cache, buf, buflen,
|
||||||
|
ans, resplen);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/*
|
/*
|
||||||
* If we have temporarily opened a virtual circuit,
|
* If we have temporarily opened a virtual circuit,
|
||||||
* or if we haven't been asked to keep a socket open,
|
* or if we haven't been asked to keep a socket open,
|
||||||
|
@ -46,7 +46,6 @@ typedef struct {
|
|||||||
struct __res_state _nres[1];
|
struct __res_state _nres[1];
|
||||||
unsigned _serial;
|
unsigned _serial;
|
||||||
struct prop_info* _pi;
|
struct prop_info* _pi;
|
||||||
struct hostent* _hostent;
|
|
||||||
struct res_static _rstatic[1];
|
struct res_static _rstatic[1];
|
||||||
} _res_thread;
|
} _res_thread;
|
||||||
|
|
||||||
@ -66,10 +65,10 @@ _res_thread_alloc(void)
|
|||||||
if ( res_ninit( rt->_nres ) < 0 ) {
|
if ( res_ninit( rt->_nres ) < 0 ) {
|
||||||
free(rt);
|
free(rt);
|
||||||
rt = NULL;
|
rt = NULL;
|
||||||
}
|
} else {
|
||||||
rt->_hostent = NULL;
|
|
||||||
memset(rt->_rstatic, 0, sizeof rt->_rstatic);
|
memset(rt->_rstatic, 0, sizeof rt->_rstatic);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +92,6 @@ _res_thread_free( void* _rt )
|
|||||||
_res_thread* rt = _rt;
|
_res_thread* rt = _rt;
|
||||||
|
|
||||||
_res_static_done(rt->_rstatic);
|
_res_static_done(rt->_rstatic);
|
||||||
_resolv_hostent_free(rt->_hostent);
|
|
||||||
res_ndestroy(rt->_nres);
|
res_ndestroy(rt->_nres);
|
||||||
free(rt);
|
free(rt);
|
||||||
}
|
}
|
||||||
@ -132,6 +130,7 @@ _res_thread_get(void)
|
|||||||
rt = NULL;
|
rt = NULL;
|
||||||
pthread_setspecific( _res_key, rt );
|
pthread_setspecific( _res_key, rt );
|
||||||
}
|
}
|
||||||
|
_resolv_cache_reset(rt->_serial);
|
||||||
return rt;
|
return rt;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,14 +176,6 @@ __res_put_state(res_state res)
|
|||||||
res=res;
|
res=res;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct hostent**
|
|
||||||
__get_res_cache_hostent_p(void)
|
|
||||||
{
|
|
||||||
_res_thread* rt = _res_thread_get();
|
|
||||||
|
|
||||||
return rt ? &rt->_hostent : NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
res_static
|
res_static
|
||||||
__res_get_static(void)
|
__res_get_static(void)
|
||||||
{
|
{
|
||||||
|
@ -28,31 +28,39 @@
|
|||||||
#ifndef _RESOLV_CACHE_H_
|
#ifndef _RESOLV_CACHE_H_
|
||||||
#define _RESOLV_CACHE_H_
|
#define _RESOLV_CACHE_H_
|
||||||
|
|
||||||
#include <netdb.h>
|
|
||||||
|
|
||||||
const struct hostent _resolv_hostent_none;
|
|
||||||
#define _RESOLV_HOSTENT_NONE ((struct hostent*)&_resolv_hostent_none)
|
|
||||||
|
|
||||||
struct resolv_cache; /* forward */
|
struct resolv_cache; /* forward */
|
||||||
|
|
||||||
|
/* get cache instance, can be NULL if cache is disabled
|
||||||
|
* (e.g. through an environment variable) */
|
||||||
extern struct resolv_cache* __get_res_cache(void);
|
extern struct resolv_cache* __get_res_cache(void);
|
||||||
extern struct hostent** __get_res_cache_hostent_p(void);
|
|
||||||
|
|
||||||
extern struct resolv_cache* _resolv_cache_get( void );
|
/* this gets called everytime we detect some changes in the DNS configuration
|
||||||
|
* and will flush the cache */
|
||||||
|
extern void _resolv_cache_reset( unsigned generation );
|
||||||
|
|
||||||
extern struct resolv_cache* _resolv_cache_create( void );
|
typedef enum {
|
||||||
|
RESOLV_CACHE_UNSUPPORTED, /* the cache can't handle that kind of queries */
|
||||||
|
/* or the answer buffer is too small */
|
||||||
|
RESOLV_CACHE_NOTFOUND, /* the cache doesn't know about this query */
|
||||||
|
RESOLV_CACHE_FOUND /* the cache found the answer */
|
||||||
|
} ResolvCacheStatus;
|
||||||
|
|
||||||
extern void _resolv_cache_destroy( struct resolv_cache* cache );
|
extern ResolvCacheStatus
|
||||||
|
_resolv_cache_lookup( struct resolv_cache* cache,
|
||||||
|
const void* query,
|
||||||
|
int querylen,
|
||||||
|
void* answer,
|
||||||
|
int answersize,
|
||||||
|
int *answerlen );
|
||||||
|
|
||||||
extern struct hostent* _resolv_cache_lookup( struct resolv_cache* cache,
|
/* add a (query,answer) to the cache, only call if _resolv_cache_lookup
|
||||||
const char* name,
|
* did return RESOLV_CACHE_NOTFOUND
|
||||||
int af );
|
*/
|
||||||
|
extern void
|
||||||
extern void _resolv_cache_add( struct resolv_cache* cache,
|
_resolv_cache_add( struct resolv_cache* cache,
|
||||||
const char* name,
|
const void* query,
|
||||||
int af,
|
int querylen,
|
||||||
struct hostent* hp );
|
const void* answer,
|
||||||
|
int answerlen );
|
||||||
extern struct hostent* _resolv_hostent_copy( struct hostent* hp );
|
|
||||||
extern void _resolv_hostent_free( struct hostent* hp );
|
|
||||||
|
|
||||||
#endif /* _RESOLV_CACHE_H_ */
|
#endif /* _RESOLV_CACHE_H_ */
|
||||||
|
@ -1133,13 +1133,25 @@ static int reloc_library(soinfo *si, Elf32_Rel *rel, unsigned count)
|
|||||||
switch(type){
|
switch(type){
|
||||||
#if defined(ANDROID_ARM_LINKER)
|
#if defined(ANDROID_ARM_LINKER)
|
||||||
case R_ARM_JUMP_SLOT:
|
case R_ARM_JUMP_SLOT:
|
||||||
|
COUNT_RELOC(RELOC_ABSOLUTE);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "%5d RELO JMP_SLOT %08x <- %08x %s\n", pid,
|
||||||
|
reloc, sym_addr, sym_name);
|
||||||
|
*((unsigned*)reloc) = sym_addr;
|
||||||
|
break;
|
||||||
case R_ARM_GLOB_DAT:
|
case R_ARM_GLOB_DAT:
|
||||||
|
COUNT_RELOC(RELOC_ABSOLUTE);
|
||||||
|
MARK(rel->r_offset);
|
||||||
|
TRACE_TYPE(RELO, "%5d RELO GLOB_DAT %08x <- %08x %s\n", pid,
|
||||||
|
reloc, sym_addr, sym_name);
|
||||||
|
*((unsigned*)reloc) = sym_addr;
|
||||||
|
break;
|
||||||
case R_ARM_ABS32:
|
case R_ARM_ABS32:
|
||||||
COUNT_RELOC(RELOC_ABSOLUTE);
|
COUNT_RELOC(RELOC_ABSOLUTE);
|
||||||
MARK(rel->r_offset);
|
MARK(rel->r_offset);
|
||||||
TRACE_TYPE(RELO, "%5d RELO ABS %08x <- %08x %s\n", pid,
|
TRACE_TYPE(RELO, "%5d RELO ABS %08x <- %08x %s\n", pid,
|
||||||
reloc, sym_addr, sym_name);
|
reloc, sym_addr, sym_name);
|
||||||
*((unsigned*)reloc) = sym_addr;
|
*((unsigned*)reloc) += sym_addr;
|
||||||
break;
|
break;
|
||||||
#elif defined(ANDROID_X86_LINKER)
|
#elif defined(ANDROID_X86_LINKER)
|
||||||
case R_386_JUMP_SLOT:
|
case R_386_JUMP_SLOT:
|
||||||
@ -1591,13 +1603,13 @@ static int link_image(soinfo *si, unsigned wr_offset)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* If this is a SETUID programme, dup /dev/null to openned stdin,
|
/* If this is a SET?ID program, dup /dev/null to opened stdin,
|
||||||
stdout and stderr to close a security hole described in:
|
stdout and stderr to close a security hole described in:
|
||||||
|
|
||||||
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
|
ftp://ftp.freebsd.org/pub/FreeBSD/CERT/advisories/FreeBSD-SA-02:23.stdio.asc
|
||||||
|
|
||||||
*/
|
*/
|
||||||
if (getuid() != geteuid())
|
if (getuid() != geteuid() || getgid() != getegid())
|
||||||
nullify_closed_stdio ();
|
nullify_closed_stdio ();
|
||||||
call_constructors(si);
|
call_constructors(si);
|
||||||
notify_gdb_of_load(si);
|
notify_gdb_of_load(si);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user