1fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney/* 2fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * Copyright 2012, The Android Open Source Project 3fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 4fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * Licensed under the Apache License, Version 2.0 (the "License"); 5fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * you may not use this file except in compliance with the License. 6fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * You may obtain a copy of the License at 7fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 8fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * http://www.apache.org/licenses/LICENSE-2.0 9fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 10fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * Unless required by applicable law or agreed to in writing, software 11fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * distributed under the License is distributed on an "AS IS" BASIS, 12fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * See the License for the specific language governing permissions and 14fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * limitations under the License. 15fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney */ 162928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney 17fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#define _GNU_SOURCE 186433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsieh#include <portability.h> 19fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <sched.h> 20fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <stdarg.h> 21fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <stdlib.h> 22fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <signal.h> 23fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <signal_portable.h> 24fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <portability.h> 25fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <stdio.h> 26fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <errno.h> 27c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney#include <filefd_portable.h> 28fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 29fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#define PORTABLE_TAG "clone_portable" 30fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney#include <log_portable.h> 31fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 32fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 33fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney/* 34fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * This function maps the clone function call defined in: 35fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * $TOP/bionic/libc/bionic/bionic_clone.c 36fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 37fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * which calls the __bionic_clone() system call which is defined in: 38fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * $TOP/bionic/libc/unistd/arch-mips/bionic/clone.S 39fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 40fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * We have to map the low byte of the 'flags' parameter which 41fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * contains the number of the termination signal sent to the 42fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * parent when the child dies. 43fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 44fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * Note that if this signal is specified as anything other than 45fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * SIGCHLD, then the parent process must specify the __WALL or 46fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * __WCLONE options when waiting for the child with wait(2). 47fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * 48fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * If no signal is specified, then the parent process is not 49fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * signaled when the child terminates. 50fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney */ 516433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsiehint WRAP(clone)(int (*fn)(void *), void *child_stack, int port_flags, void *arg, ...) 52fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney{ 53fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney va_list args; 54fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int ret; 55fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int mips_flags; 56fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney void *new_tls = NULL; 57fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int *child_tidptr = NULL; 58fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int *parent_tidptr = NULL; 59fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int mips_term_signum; 60fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney char *mips_term_signame; 61fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney int portable_term_signum; 62fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney char *portable_term_signame; 63c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney int cloning_vm = ((port_flags & CLONE_VM) == CLONE_VM); 64c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney int cloning_files = ((port_flags & CLONE_FILES) == CLONE_FILES); 65c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney int cloning_sighand = ((port_flags & CLONE_SIGHAND) == CLONE_SIGHAND); 66fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 67fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney ALOGV(" "); 68fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney ALOGV("%s(fn:%p, child_stack:%p, port_flags:0x%x, arg:%p, ...) {", __func__, 69fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney fn, child_stack, port_flags, arg); 70fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 71c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney /* Shared file descriptor table requires shared memory. */ 72c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney if (cloning_files != cloning_vm) { 73c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGE("%s: cloning_files:%d != cloning_vm:%d) ...", __func__, 74c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney cloning_files, cloning_vm); 75c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney 76c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGE("%s: ... port_flags:0x%x Not Supported by Lib-Portable!", __func__, 77c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney port_flags); 78c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney } 79c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney 80c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney /* Shared signal handler table requires shared memory. */ 81c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney if (cloning_sighand != cloning_vm) { 82c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGE("%s: cloning_sighand:%d != cloning_vm:%d) ...", __func__, 83c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney cloning_sighand, cloning_vm); 84c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney 85c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGE("%s: ... port_flags:0x%x Not Supported by Lib-Portable!", __func__, 86c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney port_flags); 87c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney } 88c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney 89dbbf0045b6dba0df28761e37be03f3127d2d2dd9Pete Delaney /* Extract optional parameters - they are cumulative. */ 90fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney va_start(args, arg); 91fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney if (port_flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID)) { 92fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney parent_tidptr = va_arg(args, int*); 93fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney } 94fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney if (port_flags & (CLONE_SETTLS|CLONE_CHILD_SETTID)) { 95fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney new_tls = va_arg(args, void*); 96fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney } 97fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney if (port_flags & CLONE_CHILD_SETTID) { 98fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney child_tidptr = va_arg(args, int*); 99fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney } 100fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney va_end(args); 101fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 102fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney /* 103fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney * Map the LSB of the flags as explained above. 104fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney */ 105fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney portable_term_signum = port_flags & 0xFF; 106fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney if (portable_term_signum == 0) { 107fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney mips_flags = port_flags; 108fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney } else { 109fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney portable_term_signame = map_portable_signum_to_name(portable_term_signum); 110c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGV("%s: portable_term_signum:0x%x:'%s'", __func__, 111c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney portable_term_signum, portable_term_signame); 1122928edfab922ff749cc8b90610cc4c228a4a2948Pete Delaney mips_term_signum = signum_pton(portable_term_signum); 113fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney mips_term_signame = map_mips_signum_to_name(mips_term_signum); 114c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGV("%s: mips_term_signum:0x%x:'%s'", __func__, 115c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney mips_term_signum, mips_term_signame); 116fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney mips_flags = (port_flags & ~0xFF) | (mips_term_signum & 0xFF); 117fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney } 118c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney ALOGV("%s: clone(%p, %p, 0x%x, %p, %p, %p, %p);", __func__, 119c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney fn, child_stack, mips_flags, arg, parent_tidptr, new_tls, child_tidptr); 120fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 1216433ec22b1e20af20b31671b2fd4d5d235a7de52Andrew Hsieh ret = REAL(clone)(fn, child_stack, mips_flags, arg, parent_tidptr, 122fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney new_tls, child_tidptr); 123fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney 124c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney if (ret > 0) { 125c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney /* 126c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney * Disable mapping in the parent if the child could interfere 127c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney * and make things even worse than skipping the signal and 128c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney * file read mapping. 129c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney */ 130c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney if (cloning_files != cloning_vm) { 131c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney filefd_disable_mapping(); 132c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney } 133c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney if (cloning_sighand != cloning_vm) { 134c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney signal_disable_mapping(); 135c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney } 136c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney } 137c684613e19bce87e5ee3cdee5fb1e7ed5be14229Pete Delaney 138fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney ALOGV("%s: return(ret:%d); }", __func__, ret); 1398930ac553438f5265d36ba048493d1bc4a89dde3Pete Delaney return ret; 140fbedea894cef9b6d196596a1da3e6ecbf028dd2cPete Delaney} 141