mirror of
https://github.com/darlinghq/darling.git
synced 2024-11-23 04:09:43 +00:00
Added shell_cmds submodule, building some executables from it.
Added initial 'darling' tool. Added sys_getlogin. sysconf(_SC_ARG_MAX) now works.
This commit is contained in:
parent
33ddc75a38
commit
5983370373
4
.gitmodules
vendored
4
.gitmodules
vendored
@ -45,3 +45,7 @@
|
||||
path = src/external/curl
|
||||
url = ../darling-curl.git
|
||||
branch = darling
|
||||
[submodule "src/external/shell_cmds"]
|
||||
path = src/external/shell_cmds
|
||||
url = ../darling-shell_cmds.git
|
||||
branch = darling
|
||||
|
20
cmake/darling_exe.cmake
Normal file
20
cmake/darling_exe.cmake
Normal file
@ -0,0 +1,20 @@
|
||||
if(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
cmake_policy(SET CMP0011 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
|
||||
|
||||
FUNCTION(add_darling_executable exe)
|
||||
foreach(f IN LISTS ARGN)
|
||||
set(files ${files} ${f})
|
||||
endforeach(f)
|
||||
|
||||
SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib${SUFFIX}/darling")
|
||||
SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE)
|
||||
SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
add_executable(${exe} ${files})
|
||||
target_link_libraries(${exe} system -lpthread csu dyld)
|
||||
set_target_properties(${exe} PROPERTIES COMPILE_FLAGS "-Denviron=__darwin_environ -Ddlopen=__darwin_dlopen -Ddlclose=__darwin_dlclose -Ddlsym=__darwin_dlsym -Ddladdr=__darwin_dladdr")
|
||||
ENDFUNCTION(add_darling_executable)
|
||||
|
@ -30,6 +30,7 @@
|
||||
#include <stdint.h>
|
||||
#include <mach/message.h>
|
||||
#include <Availability.h>
|
||||
#include <stdbool.h>
|
||||
#ifdef __BLOCKS__
|
||||
#include <dispatch/dispatch.h>
|
||||
#endif /* __BLOCKS__ */
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004-2013 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_START@
|
||||
*
|
||||
* This file contains Original Code and/or Modifications of Original Code
|
||||
* as defined in and that are subject to the Apple Public Source License
|
||||
* Version 2.0 (the 'License'). You may not use this file except in
|
||||
* compliance with the License. The rights granted to you under the License
|
||||
* may not be used to create, or enable the creation or redistribution of,
|
||||
* unlawful or unlicensed copies of an Apple operating system, or to
|
||||
* circumvent, violate, or enable the circumvention or violation of, any
|
||||
* terms of an Apple operating system software license agreement.
|
||||
*
|
||||
* Please obtain a copy of the License at
|
||||
* http://www.opensource.apple.com/apsl/ and read it before using this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||||
* Please see the License for the specific language governing rights and
|
||||
* limitations under the License.
|
||||
*
|
||||
* @APPLE_OSREFERENCE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
#include <sys/_types.h>
|
@ -107,6 +107,8 @@ add_subdirectory(libedit)
|
||||
#add_subdirectory(launchd/src)
|
||||
add_subdirectory(external/compiler-rt/lib/builtins)
|
||||
add_subdirectory(CommonCrypto)
|
||||
add_subdirectory(csu)
|
||||
add_subdirectory(external/shell_cmds)
|
||||
|
||||
######################
|
||||
# libc++ & libc++abi #
|
||||
|
24
src/csu/CMakeLists.txt
Normal file
24
src/csu/CMakeLists.txt
Normal file
@ -0,0 +1,24 @@
|
||||
project(csu)
|
||||
|
||||
cmake_minimum_required(VERSION 2.4.0)
|
||||
|
||||
enable_language(C ASM)
|
||||
|
||||
if(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
endif(COMMAND cmake_policy)
|
||||
|
||||
add_definitions(-DTARGET_OS_MAC=1)
|
||||
add_definitions(-D__APPLE__ -D__DYNAMIC__)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w")
|
||||
|
||||
include_directories(${DARLING_TOP_DIRECTORY}/src/libc/include/FreeBSD)
|
||||
|
||||
set(csu_SRCS
|
||||
crt.c
|
||||
start.S
|
||||
)
|
||||
|
||||
add_library(csu STATIC ${csu_SRCS})
|
||||
|
356
src/csu/crt.c
Normal file
356
src/csu/crt.c
Normal file
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 1999-2008 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
|
||||
* Reserved. This file contains Original Code and/or Modifications of
|
||||
* Original Code as defined in and that are subject to the Apple Public
|
||||
* Source License Version 1.1 (the "License"). You may not use this file
|
||||
* except in compliance with the License. Please obtain a copy of the
|
||||
* License at http://www.apple.com/publicsource and read it before using
|
||||
* this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
/*
|
||||
* The common startup code. This code is if'ed with the 'C' preprocessor
|
||||
* macros __DYNAMIC__ and GCRT. It is used to create
|
||||
* the following files when compiled with the following macros defined:
|
||||
*
|
||||
* File Dedined Macros Purpose
|
||||
* crt1.o __DYNAMIC__ startup for programs compiled -dynamic
|
||||
* gcrt1.o __DYNAMIC__, GCRT profiling startup, programs compiled -dynamic
|
||||
*
|
||||
* crt0.o startup for programs compiled -static
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
/*
|
||||
* Global data definitions (initialized data).
|
||||
*/
|
||||
int NXArgc = 0;
|
||||
const char** NXArgv = NULL;
|
||||
const char** environ = NULL;
|
||||
const char* __progname = NULL;
|
||||
|
||||
#if ADD_PROGRAM_VARS
|
||||
extern void* __dso_handle;
|
||||
struct ProgramVars
|
||||
{
|
||||
void* mh;
|
||||
int* NXArgcPtr;
|
||||
const char*** NXArgvPtr;
|
||||
const char*** environPtr;
|
||||
const char** __prognamePtr;
|
||||
};
|
||||
__attribute__((used)) static struct ProgramVars pvars
|
||||
__attribute__ ((section ("__DATA,__program_vars"))) = { &__dso_handle, &NXArgc, &NXArgv, &environ, &__progname };
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* This file is not needed for executables targeting 10.5 or later
|
||||
* start calls main() directly.
|
||||
*/
|
||||
#if __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT
|
||||
/*
|
||||
* The following symbols are reference by System Framework symbolicly (instead
|
||||
* of through undefined references (to allow prebinding). To get strip(1) to
|
||||
* know these symbols are not to be stripped they need to have the
|
||||
* REFERENCED_DYNAMICALLY bit (0x10) set. This would have been done automaticly
|
||||
* by ld(1) if these symbols were referenced through undefined symbols.
|
||||
* The catch_exception_raise symbol is special in that the Mach API specifically
|
||||
* requires that the library call into the user program for its implementation.
|
||||
* Therefore, we need to create a common definition and make sure the symbol
|
||||
* doesn't get stripped.
|
||||
*/
|
||||
asm(".desc _NXArgc, 0x10");
|
||||
asm(".desc _NXArgv, 0x10");
|
||||
asm(".desc _environ, 0x10");
|
||||
asm(".desc __mh_execute_header, 0x10");
|
||||
#if defined(__ppc__) || defined(__i386__)
|
||||
asm(".comm _catch_exception_raise, 4");
|
||||
asm(".desc _catch_exception_raise, 0x10");
|
||||
asm(".comm _catch_exception_raise_state, 4");
|
||||
asm(".desc _catch_exception_raise_state, 0x10");
|
||||
asm(".comm _catch_exception_raise_state_identity, 4");
|
||||
asm(".desc _catch_exception_raise_state_identity, 0x10");
|
||||
asm(".comm _do_mach_notify_dead_name, 4");
|
||||
asm(".desc _do_mach_notify_dead_name, 0x10");
|
||||
asm(".comm _do_seqnos_mach_notify_dead_name, 4");
|
||||
asm(".desc _do_seqnos_mach_notify_dead_name, 0x10");
|
||||
asm(".comm _do_mach_notify_no_senders, 4");
|
||||
asm(".desc _do_mach_notify_no_senders, 0x10");
|
||||
asm(".comm _do_seqnos_mach_notify_no_senders, 4");
|
||||
asm(".desc _do_seqnos_mach_notify_no_senders, 0x10");
|
||||
asm(".comm _do_mach_notify_port_deleted, 4");
|
||||
asm(".desc _do_mach_notify_port_deleted, 0x10");
|
||||
asm(".comm _do_seqnos_mach_notify_port_deleted, 4");
|
||||
asm(".desc _do_seqnos_mach_notify_port_deleted, 0x10");
|
||||
asm(".comm _do_mach_notify_send_once, 4");
|
||||
asm(".desc _do_mach_notify_send_once, 0x10");
|
||||
asm(".comm _do_seqnos_mach_notify_send_once, 4");
|
||||
asm(".desc _do_seqnos_mach_notify_send_once, 0x10");
|
||||
asm(".comm _clock_alarm_reply, 4");
|
||||
asm(".desc _clock_alarm_reply, 0x10");
|
||||
asm(".comm _receive_samples, 4");
|
||||
asm(".desc _receive_samples, 0x10");
|
||||
#endif /* __ppc__ || __i386__ */
|
||||
asm(".desc ___progname, 0x10");
|
||||
|
||||
/*
|
||||
* Common data definitions. If the routines in System Framework are not pulled
|
||||
* into the executable then the static linker will allocate these as common
|
||||
* symbols. The code in here tests the value of these are non-zero to know if
|
||||
* the routines in System Framework got pulled in and should be called. The
|
||||
* first two are pointers to functions. The second two use just the symbol
|
||||
* itself. In the later case we are using the symbol with two different 'C'
|
||||
* types. To make it as clean as possible the 'C' type declared is that of the
|
||||
* external function. The common symbol is declared with an asm() and the code
|
||||
* casts the function name to a pointer to an int and then indirects through
|
||||
* the pointer to see if the value is not zero to know the function got linked
|
||||
* in. Then the code uses a pointer in the data area to the function to call
|
||||
* the function. The pointer in the data area is needed on various RISC
|
||||
* architectutes like the PowerPC to avoid a relocation overflow error when
|
||||
* linking programs with large data area.
|
||||
*/
|
||||
extern int (*mach_init_routine)(void);
|
||||
extern int (*_cthread_init_routine)(void);
|
||||
#if !__DYNAMIC__
|
||||
asm(".comm __cplus_init, 4");
|
||||
extern void _cplus_init(void);
|
||||
#endif
|
||||
#if __DYNAMIC__ && __ppc__
|
||||
asm(".comm ___darwin_gcc3_preregister_frame_info, 4");
|
||||
extern void __darwin_gcc3_preregister_frame_info (void);
|
||||
static void (*pointer_to__darwin_gcc3_preregister_frame_info)(void) =
|
||||
__darwin_gcc3_preregister_frame_info;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Prototypes for routines that are called.
|
||||
*/
|
||||
extern int main(int argc, const char* argv[], const char* envp[], const char* apple[]);
|
||||
extern void exit(int status) __attribute__ ((noreturn));
|
||||
extern int atexit(void (*fcn)(void));
|
||||
static const char* crt_basename(const char* path);
|
||||
|
||||
#if GCRT
|
||||
extern void moninit(void);
|
||||
static void _mcleanup(void);
|
||||
extern void monitor(char *lowpc,char *highpc,char *buf,int bufsiz,int nfunc);
|
||||
#endif /* GCRT */
|
||||
|
||||
#if __DYNAMIC__
|
||||
extern int _dyld_func_lookup(const char *dyld_func_name,unsigned long *address);
|
||||
extern void __keymgr_dwarf2_register_sections (void);
|
||||
#endif /* __DYNAMIC__ */
|
||||
|
||||
#if __DYNAMIC__ && __ppc__
|
||||
static void _call_objcInit(void);
|
||||
#endif
|
||||
|
||||
extern int errno;
|
||||
|
||||
/*
|
||||
* _start() is called from the machine dependent assembly entry point "start:" .
|
||||
* It takes care of setting up the stack so 'C' routines can be called and
|
||||
* passes argc, argv and envp to here.
|
||||
*/
|
||||
__private_extern__
|
||||
void
|
||||
_start(int argc, const char* argv[], const char* envp[])
|
||||
{
|
||||
const char** apple;
|
||||
#if __DYNAMIC__
|
||||
void (*term)(void);
|
||||
void (*init)(void);
|
||||
#endif
|
||||
|
||||
// initialize global variables
|
||||
NXArgc = argc;
|
||||
NXArgv = argv;
|
||||
environ = envp;
|
||||
__progname = ((argv[0] != NULL) ? crt_basename(argv[0]) : "");
|
||||
// see start.s for how "apple" parameter follow envp
|
||||
for(apple = envp; *apple != NULL; ++apple) { /* loop */ }
|
||||
++apple;
|
||||
|
||||
// initialize libSystem
|
||||
if ( mach_init_routine != 0 )
|
||||
(void) mach_init_routine();
|
||||
if ( _cthread_init_routine != 0 )
|
||||
(*_cthread_init_routine)();
|
||||
|
||||
#ifdef __DYNAMIC__
|
||||
__keymgr_dwarf2_register_sections ();
|
||||
#endif
|
||||
|
||||
#if __ppc__ && __DYNAMIC__
|
||||
/* Call a ppc GCC 3.3-specific function (in libgcc.a) to
|
||||
"preregister" exception frame info, meaning to set up the
|
||||
dyld hooks that do the actual registration. */
|
||||
if ( *((int *)pointer_to__darwin_gcc3_preregister_frame_info) != 0 )
|
||||
pointer_to__darwin_gcc3_preregister_frame_info ();
|
||||
#endif
|
||||
|
||||
#if !__DYNAMIC__
|
||||
if(*((int *)_cplus_init) != 0)
|
||||
_cplus_init();
|
||||
#endif
|
||||
|
||||
#ifdef __DYNAMIC__
|
||||
/*
|
||||
* Call into dyld to run all initializers. This must be done
|
||||
* after mach_init()
|
||||
*/
|
||||
_dyld_func_lookup("__dyld_make_delayed_module_initializer_calls",
|
||||
(unsigned long *)&init);
|
||||
init();
|
||||
#endif
|
||||
|
||||
#if __DYNAMIC__ && __ppc__
|
||||
_call_objcInit();
|
||||
#endif
|
||||
|
||||
#ifdef GCRT
|
||||
atexit(_mcleanup);
|
||||
moninit();
|
||||
#endif
|
||||
|
||||
#ifdef __DYNAMIC__
|
||||
/*
|
||||
* If the dyld we are running with supports module termination routines
|
||||
* for all types of images then register the function to call them with
|
||||
* atexit().
|
||||
*/
|
||||
_dyld_func_lookup("__dyld_mod_term_funcs", (unsigned long *)&term);
|
||||
if ( term != 0 )
|
||||
atexit(term);
|
||||
#endif
|
||||
|
||||
// clear errno, so main() starts fresh
|
||||
errno = 0;
|
||||
|
||||
// call main() and return to exit()
|
||||
exit(main(argc, argv, envp, apple));
|
||||
}
|
||||
|
||||
#if GCRT
|
||||
/*
|
||||
* For profiling the routine _mcleanup gets registered with atexit so monitor(0)
|
||||
* gets called.
|
||||
*/
|
||||
static
|
||||
void
|
||||
_mcleanup(
|
||||
void)
|
||||
{
|
||||
monitor(0,0,0,0,0);
|
||||
}
|
||||
#endif /* GCRT */
|
||||
|
||||
static
|
||||
const char *
|
||||
crt_basename(const char *path)
|
||||
{
|
||||
const char *s;
|
||||
const char *last = path;
|
||||
|
||||
for (s = path; *s != '\0'; s++) {
|
||||
if (*s == '/') last = s+1;
|
||||
}
|
||||
|
||||
return last;
|
||||
}
|
||||
|
||||
#if __DYNAMIC__ && __ppc__
|
||||
static
|
||||
int
|
||||
crt_strbeginswith(const char *s1, const char *s2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; ; i++) {
|
||||
if (s2[i] == '\0') return 1;
|
||||
else if (s1[i] != s2[i]) return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Look for a function called _objcInit() in any library whose name
|
||||
* starts with "libobjc", and call it if one exists. This is used to
|
||||
* initialize the Objective-C runtime on Mac OS X 10.3 and earlier.
|
||||
* This is completely unnecessary on Mac OS X 10.4 and later.
|
||||
*/
|
||||
static
|
||||
void
|
||||
_call_objcInit(void)
|
||||
{
|
||||
unsigned int i, count;
|
||||
|
||||
unsigned int (*_dyld_image_count_fn)(void);
|
||||
const char *(*_dyld_get_image_name_fn)(unsigned int image_index);
|
||||
const void *(*_dyld_get_image_header_fn)(unsigned int image_index);
|
||||
const void *(*NSLookupSymbolInImage_fn)(const void *image, const char *symbolName, unsigned int options);
|
||||
void *(*NSAddressOfSymbol_fn)(const void *symbol);
|
||||
|
||||
// Find some dyld functions.
|
||||
_dyld_func_lookup("__dyld_image_count",
|
||||
(unsigned long *)&_dyld_image_count_fn);
|
||||
_dyld_func_lookup("__dyld_get_image_name",
|
||||
(unsigned long *)&_dyld_get_image_name_fn);
|
||||
_dyld_func_lookup("__dyld_get_image_header",
|
||||
(unsigned long *)&_dyld_get_image_header_fn);
|
||||
_dyld_func_lookup("__dyld_NSLookupSymbolInImage",
|
||||
(unsigned long *)&NSLookupSymbolInImage_fn);
|
||||
_dyld_func_lookup("__dyld_NSAddressOfSymbol",
|
||||
(unsigned long *)&NSAddressOfSymbol_fn);
|
||||
|
||||
// If any of the dyld functions don't exist, assume we're
|
||||
// on a post-Panther dyld and silently do nothing.
|
||||
if (!_dyld_image_count_fn) return;
|
||||
if (!_dyld_get_image_name_fn) return;
|
||||
if (!_dyld_get_image_header_fn) return;
|
||||
if (!NSLookupSymbolInImage_fn) return;
|
||||
if (!NSAddressOfSymbol_fn) return;
|
||||
|
||||
// Search for an image whose library name starts with "libobjc".
|
||||
count = (*_dyld_image_count_fn)();
|
||||
for (i = 0; i < count; i++) {
|
||||
const void *image;
|
||||
const char *path = (*_dyld_get_image_name_fn)(i);
|
||||
const char *base = crt_basename(path);
|
||||
if (!crt_strbeginswith(base, "libobjc")) continue;
|
||||
|
||||
// Call _objcInit() if library exports it.
|
||||
if ((image = (*_dyld_get_image_header_fn)(i))) {
|
||||
const void *symbol;
|
||||
// 4 == NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR
|
||||
if ((symbol = (*NSLookupSymbolInImage_fn)(image,"__objcInit",4))) {
|
||||
void (*_objcInit_fn)(void) =
|
||||
(void(*)(void))(*NSAddressOfSymbol_fn)(symbol);
|
||||
if (_objcInit_fn) {
|
||||
(*_objcInit_fn)();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __DYNAMIC__ && __ppc__ */
|
||||
|
||||
#endif /* __DYNAMIC__ && OLD_LIBSYSTEM_SUPPORT */
|
269
src/csu/start.S
Normal file
269
src/csu/start.S
Normal file
@ -0,0 +1,269 @@
|
||||
// Modified by Lubos Dolezel for Darling
|
||||
/*
|
||||
* Copyright (c) 1999-2009 Apple Inc. All rights reserved.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_START@
|
||||
*
|
||||
* Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
|
||||
* Reserved. This file contains Original Code and/or Modifications of
|
||||
* Original Code as defined in and that are subject to the Apple Public
|
||||
* Source License Version 1.1 (the "License"). You may not use this file
|
||||
* except in compliance with the License. Please obtain a copy of the
|
||||
* License at http://www.apple.com/publicsource and read it before using
|
||||
* this file.
|
||||
*
|
||||
* The Original Code and all software distributed under the License are
|
||||
* distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||||
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||||
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT. Please see the
|
||||
* License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* @APPLE_LICENSE_HEADER_END@
|
||||
*/
|
||||
|
||||
#include <Availability.h>
|
||||
|
||||
#ifdef DARLING
|
||||
# define start _start
|
||||
# define _main main
|
||||
#endif
|
||||
|
||||
#if __ppc__ && __DYNAMIC__
|
||||
//
|
||||
// Force stub section next to __text section to minimize chance that
|
||||
// a bl to a stub will be out of range.
|
||||
//
|
||||
.text
|
||||
.symbol_stub
|
||||
.picsymbol_stub
|
||||
#endif
|
||||
|
||||
/*
|
||||
* C runtime startup for ppc, ppc64, i386, x86_64
|
||||
*
|
||||
* Kernel sets up stack frame to look like:
|
||||
*
|
||||
* :
|
||||
* | STRING AREA |
|
||||
* +-------------+
|
||||
* | 0 |
|
||||
* +-------------+
|
||||
* | exec_path | extra "apple" parameters start after NULL terminating env array
|
||||
* +-------------+
|
||||
* | 0 |
|
||||
* +-------------+
|
||||
* | env[n] |
|
||||
* +-------------+
|
||||
* :
|
||||
* :
|
||||
* +-------------+
|
||||
* | env[0] |
|
||||
* +-------------+
|
||||
* | 0 |
|
||||
* +-------------+
|
||||
* | arg[argc-1] |
|
||||
* +-------------+
|
||||
* :
|
||||
* :
|
||||
* +-------------+
|
||||
* | arg[0] |
|
||||
* +-------------+
|
||||
* | argc | argc is always 4 bytes long, even in 64-bit architectures
|
||||
* +-------------+ <- sp
|
||||
*
|
||||
* Where arg[i] and env[i] point into the STRING AREA
|
||||
*/
|
||||
|
||||
.text
|
||||
.globl start
|
||||
.align 2
|
||||
|
||||
#if __ppc__
|
||||
start: mr r26,r1 ; save original stack pointer into r26
|
||||
subi r1,r1,4 ; make space for linkage
|
||||
clrrwi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
|
||||
li r0,0 ; load 0 into r0
|
||||
stw r0,0(r1) ; terminate initial stack frame
|
||||
stwu r1,-64(r1) ; allocate minimal stack frame
|
||||
lwz r3,0(r26) ; get argc into r3
|
||||
addi r4,r26,4 ; get argv into r4
|
||||
addi r27,r3,1 ; calculate argc + 1 into r27
|
||||
slwi r27,r27,2 ; calculate (argc + 1) * sizeof(char *) into r27
|
||||
add r5,r4,r27 ; get address of env[0] into r5
|
||||
#if OLD_LIBSYSTEM_SUPPORT
|
||||
bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
|
||||
trap ; should never return
|
||||
#else
|
||||
mr r6,r5
|
||||
Lapple: lwz r0,0(r6) ; look for NULL ending env[] array
|
||||
addi r6,r6,4
|
||||
cmpwi r0,0
|
||||
bne Lapple ; once found, next pointer is "apple" parameter now in r6
|
||||
bl _main
|
||||
b _exit ; pass result from main() to exit()
|
||||
#endif
|
||||
#endif // __ppc__
|
||||
|
||||
|
||||
#if __ppc64__
|
||||
start: mr r26,r1 ; save original stack pointer into r26
|
||||
subi r1,r1,8 ; make space for linkage
|
||||
clrrdi r1,r1,5 ; align to 32 bytes (good enough for 32- and 64-bit APIs)
|
||||
li r0,0 ; load 0 into r0
|
||||
std r0,0(r1) ; terminate initial stack frame
|
||||
stdu r1,-128(r1) ; allocate minimal stack frame
|
||||
lwz r3,0(r26) ; get argc into r3
|
||||
addi r4,r26,8 ; get argv into r4
|
||||
addi r27,r3,1 ; calculate argc + 1 into r27
|
||||
sldi r27,r27,3 ; calculate (argc + 1) * sizeof(char *) into r27
|
||||
add r5,r4,r27 ; get address of env[0] into r5
|
||||
#if OLD_LIBSYSTEM_SUPPORT
|
||||
bl __start ; 24-bt branch to __start. ld64 will make a branch island if needed
|
||||
trap ; should never return
|
||||
#else
|
||||
mr r6,r5
|
||||
Lapple: ld r0,0(r6) ; look for NULL ending env[] array
|
||||
addi r6,r6,8
|
||||
cmpdi r0,0
|
||||
bne Lapple ; once found, next pointer is "apple" parameter now in r6
|
||||
bl _main
|
||||
b _exit ; pass result from main() to exit()
|
||||
#endif
|
||||
#endif // __ppc64__
|
||||
|
||||
|
||||
#if __i386__
|
||||
start: pushl $0 # push a zero for debugger end of frames marker
|
||||
movl %esp,%ebp # pointer to base of kernel frame
|
||||
andl $-16,%esp # force SSE alignment
|
||||
subl $16,%esp # room for new argc, argv, & envp, SSE aligned
|
||||
movl 4(%ebp),%ebx # pickup argc in %ebx
|
||||
movl %ebx,0(%esp) # argc to reserved stack word
|
||||
lea 8(%ebp),%ecx # addr of arg[0], argv, into %ecx
|
||||
movl %ecx,4(%esp) # argv to reserved stack word
|
||||
addl $1,%ebx # argc + 1 for zero word
|
||||
sall $2,%ebx # * sizeof(char *)
|
||||
addl %ecx,%ebx # addr of env[0], envp, into %ebx
|
||||
movl %ebx,8(%esp) # envp to reserved stack word
|
||||
#if OLD_LIBSYSTEM_SUPPORT
|
||||
call __start # call _start(argc, argv, envp)
|
||||
hlt # should never return
|
||||
#else
|
||||
Lapple: movl (%ebx),%eax # look for NULL ending env[] array
|
||||
add $4,%ebx
|
||||
testl %eax,%eax
|
||||
jne Lapple # once found, next pointer is "apple" parameter now in %ebx
|
||||
movl %ebx,12(%esp) # apple to reserved stack word
|
||||
call _main
|
||||
movl %eax, 0(%esp) # pass result from main() to exit()
|
||||
call _exit # need to use call to keep stack aligned
|
||||
hlt
|
||||
#endif
|
||||
#endif // __i386__
|
||||
|
||||
|
||||
|
||||
#if __x86_64__
|
||||
start: pushq $0 # push a zero for debugger end of frames marker
|
||||
movq %rsp,%rbp # pointer to base of kernel frame
|
||||
andq $-16,%rsp # force SSE alignment
|
||||
movq 8(%rbp),%rdi # put argc in %rdi
|
||||
leaq 16(%rbp),%rsi # addr of arg[0], argv, into %rsi
|
||||
movl %edi,%edx # copy argc into %rdx
|
||||
addl $1,%edx # argc + 1 for zero word
|
||||
sall $3,%edx # * sizeof(char *)
|
||||
addq %rsi,%rdx # addr of env[0], envp, into %rdx
|
||||
#if OLD_LIBSYSTEM_SUPPORT
|
||||
call __start # call _start(argc, argv, envp)
|
||||
hlt # should never return
|
||||
#else
|
||||
movq %rdx,%rcx
|
||||
jmp Lapple2
|
||||
Lapple: add $8,%rcx
|
||||
Lapple2:cmpq $0,(%rcx) # look for NULL ending env[] array
|
||||
jne Lapple
|
||||
add $8,%rcx # once found, next pointer is "apple" parameter now in %rcx
|
||||
call _main
|
||||
movl %eax,%edi # pass result from main() to exit()
|
||||
call _exit@PLT # need to use call to keep stack aligned
|
||||
hlt
|
||||
#endif
|
||||
#endif // __x86_64__
|
||||
|
||||
#ifdef __arm__
|
||||
start:
|
||||
ldr r0, [sp] // get argc into r0
|
||||
add r1, sp, #4 // get argv into r1
|
||||
add r4, r0, #1 // calculate argc + 1 into r4
|
||||
add r2, r1, r4, lsl #2 // get address of env[0] into r2
|
||||
bic sp, sp, #7 // force eight-byte alignment
|
||||
#if OLD_LIBSYSTEM_SUPPORT
|
||||
bl __start
|
||||
.long 0xe1200070 // should never return
|
||||
#else
|
||||
mov r3, r2
|
||||
Lapple:
|
||||
ldr r4, [r3], #4 // look for NULL ending env[] array
|
||||
cmp r4, #0
|
||||
bne Lapple
|
||||
// "apple" param now in r3
|
||||
#if __STATIC__ || ((__IPHONE_OS_VERSION_MIN_REQUIRED >= 30100) && !__ARM_ARCH_4T__)
|
||||
bl _main
|
||||
b _exit
|
||||
#else
|
||||
// use -mlong-branch style call sites so that main executable can be >32MB
|
||||
ldr ip, L4
|
||||
L2: add ip, pc, ip
|
||||
ldr ip, [ip, #0]
|
||||
#if __ARM_ARCH_4T__
|
||||
mov lr, pc // blx not supported, so simulate it in two steps
|
||||
bx ip
|
||||
#else
|
||||
blx ip // call main()
|
||||
#endif
|
||||
|
||||
ldr ip, L5
|
||||
L3: add ip, pc, ip
|
||||
ldr ip, [ip, #0]
|
||||
bx ip // jmp exit()
|
||||
|
||||
L4: .long L_main$non_lazy_ptr-(L2+8)
|
||||
L5: .long L_exit$non_lazy_ptr-(L3+8)
|
||||
|
||||
.non_lazy_symbol_pointer
|
||||
L_main$non_lazy_ptr:
|
||||
.indirect_symbol _main
|
||||
.long 0
|
||||
L_exit$non_lazy_ptr:
|
||||
.indirect_symbol _exit
|
||||
.long 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
#endif /* __arm__ */
|
||||
|
||||
|
||||
#if __arm64__
|
||||
|
||||
start:
|
||||
mov x5, sp
|
||||
ldr x0, [x5] ; get argc into x0 (kernel passes 32-bit int argc as 64-bits on stack to keep alignment)
|
||||
add x1, x5, #8 ; get argv into x1
|
||||
add x4, x0, #1 ; argc + 1
|
||||
add x2, x1, x4, lsl #3 ; &env[0] = (argc+1)*8
|
||||
and sp, x5, #~15 ; force 16-byte alignment of stack
|
||||
mov x3, x2
|
||||
L1: ldr x4, [x3], #8
|
||||
cmp x4, #0 ; look for NULL ending env[] array
|
||||
b.ne L1
|
||||
bl _main ; main(x0=argc, x1=argv, x2=envp, x3=apple)
|
||||
b _exit
|
||||
|
||||
#endif /* __arm64__ */
|
||||
|
||||
|
||||
// This code has be written to allow dead code stripping
|
||||
// .subsections_via_symbols
|
@ -24,6 +24,6 @@ SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
|
||||
add_library(system_duct SHARED commpage.c libnotify.c numcpus.c
|
||||
CRGetCrashLogMessage.c acl.c bootstrap.c dyld.c dns_sd.c
|
||||
sa_dst_compare.c)
|
||||
sa_dst_compare.c asl.c)
|
||||
|
||||
install(TARGETS system_duct DESTINATION lib${SUFFIX}/darling)
|
||||
|
65
src/duct/src/asl.c
Normal file
65
src/duct/src/asl.c
Normal file
@ -0,0 +1,65 @@
|
||||
int asl_close()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_get()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_open()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_set_query()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_store_match_timeout()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_new()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_free()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aslresponse_free()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_set()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int aslresponse_next()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_store_open_read()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_send()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int asl_store_close()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -84,6 +84,22 @@ case "$1" in
|
||||
>2& echo "Not implemented yet"
|
||||
exit 1
|
||||
;;
|
||||
"load")
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
2>&1 "You need to be root for this command."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
darling_load
|
||||
;;
|
||||
"unload")
|
||||
if [ "$(id -u)" != 0 ]; then
|
||||
2>&1 "You need to be root for this command."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
darling_unload
|
||||
;;
|
||||
*)
|
||||
exec "${dyld_path}" "$1" "${@:2}"
|
||||
;;
|
||||
|
1
src/external/shell_cmds
vendored
Submodule
1
src/external/shell_cmds
vendored
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 90e8afbf0c7afce065accc130aeb5b521b5738db
|
@ -89,6 +89,7 @@ set(emulation_sources
|
||||
misc/getrlimit.c
|
||||
misc/gethostuuid.c
|
||||
misc/getrusage.c
|
||||
misc/getlogin.c
|
||||
fcntl/open.c
|
||||
fcntl/fcntl.c
|
||||
network/socket.c
|
||||
|
26
src/kernel/emulation/linux/misc/getlogin.c
Normal file
26
src/kernel/emulation/linux/misc/getlogin.c
Normal file
@ -0,0 +1,26 @@
|
||||
#include "getlogin.h"
|
||||
#include "../base.h"
|
||||
#include "../errno.h"
|
||||
#include <asm/unistd.h>
|
||||
#include <stddef.h>
|
||||
|
||||
extern char *getenv(const char *name);
|
||||
extern unsigned long strlcpy(char* dst, const char* src, unsigned long size);
|
||||
|
||||
long sys_getlogin(char* buf, unsigned int len)
|
||||
{
|
||||
int ret;
|
||||
char* e;
|
||||
|
||||
e = getenv("USER");
|
||||
if (e != NULL)
|
||||
{
|
||||
return strlcpy(buf, e, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
*buf = '\0';
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
7
src/kernel/emulation/linux/misc/getlogin.h
Normal file
7
src/kernel/emulation/linux/misc/getlogin.h
Normal file
@ -0,0 +1,7 @@
|
||||
#ifndef LINUX_GETLOGIN_H
|
||||
#define LINUX_GETLOGIN_H
|
||||
|
||||
long sys_getlogin(char* buf, unsigned int len);
|
||||
|
||||
#endif
|
||||
|
@ -5,6 +5,7 @@ struct rlimit
|
||||
{
|
||||
unsigned long long rlim_cur;
|
||||
unsigned long long rlim_max;
|
||||
long _dummy[20];
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -12,6 +12,7 @@
|
||||
#include <limits.h>
|
||||
#include "../ext/sys/utsname.h"
|
||||
#include "../ext/syslog.h"
|
||||
#include "getrlimit.h"
|
||||
#include "darling-config.h"
|
||||
#include <util/IniConfig.h>
|
||||
|
||||
@ -184,6 +185,19 @@ long sys_sysctl(int* name, unsigned int nlen, void* old,
|
||||
return -ENOTDIR;
|
||||
}
|
||||
}
|
||||
case KERN_ARGMAX:
|
||||
{
|
||||
struct rlimit lim;
|
||||
int r;
|
||||
int* ovalue = (int*) old;
|
||||
|
||||
r = sys_getrlimit(BSD_RLIMIT_STACK, &lim);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ovalue = lim.rlim_cur / 4;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
need_uname();
|
||||
|
@ -60,6 +60,7 @@
|
||||
#include "process/wait4.h"
|
||||
#include "process/waitid.h"
|
||||
#include "process/execve.h"
|
||||
#include "misc/getlogin.h"
|
||||
#include "misc/ioctl.h"
|
||||
#include "misc/getrlimit.h"
|
||||
#include "misc/thread_selfid.h"
|
||||
@ -158,6 +159,7 @@ void* __bsd_syscall_table[512] = {
|
||||
[46] = sys_sigaction,
|
||||
[47] = sys_getgid,
|
||||
[48] = sys_sigprocmask,
|
||||
[49] = sys_getlogin,
|
||||
[53] = sys_sigaltstack,
|
||||
[54] = sys_ioctl,
|
||||
[57] = sys_symlink,
|
||||
|
@ -146,6 +146,7 @@ LEAF(pseudo, 0) ;\
|
||||
|
||||
#define UNIX_SYSCALL(name, nargs) \
|
||||
.globl cerror ;\
|
||||
.type name, @function ;\
|
||||
LEAF(name, 0) ;\
|
||||
movl $ SYS_##name, %eax ;\
|
||||
call __darling_bsd_syscall@PLT ;\
|
||||
@ -158,6 +159,7 @@ LEAF(name, 0) ;\
|
||||
|
||||
#define UNIX_SYSCALL_NONAME(name, nargs, cerror) \
|
||||
.globl cerror ;\
|
||||
.type name, @function ;\
|
||||
movl $ SYS_##name, %eax ;\
|
||||
call __darling_bsd_syscall@PLT ;\
|
||||
cmpq $-4095, %rax ;\
|
||||
|
@ -152,6 +152,7 @@ L2:
|
||||
#error Unsupported architecture
|
||||
#endif
|
||||
#if defined(__x86_64__)
|
||||
.type vfork, @function
|
||||
.globl vfork
|
||||
vfork = __vfork
|
||||
#endif
|
||||
|
@ -53,7 +53,7 @@ set(gen_sources #asl.c
|
||||
#syslog.c
|
||||
thread_stack_pcs.c
|
||||
uname.c
|
||||
#utmpx-darwin.c
|
||||
utmpx-darwin.c
|
||||
wordexp.c)
|
||||
|
||||
set(gen_sources ${gen_sources}
|
||||
@ -169,7 +169,7 @@ SET_SOURCE_FILES_PROPERTIES(FreeBSD/wait.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_F
|
||||
SET_SOURCE_FILES_PROPERTIES(FreeBSD/waitpid.c PROPERTIES COMPILE_FLAGS "${CMAKE_C_FLAGS} -DLIBC_ALIAS_WAITPID")
|
||||
|
||||
set(gen_sources ${gen_sources}
|
||||
#NetBSD/utmpx.c
|
||||
NetBSD/utmpx.c
|
||||
)
|
||||
|
||||
add_library(libc-gen OBJECT ${gen_sources})
|
||||
|
@ -52,7 +52,7 @@
|
||||
#include <mach/mach_types.h>
|
||||
#include <servers/bootstrap.h>
|
||||
#include <pthread.h>
|
||||
#include <asl_ipc.h>
|
||||
//#include <asl_ipc.h>
|
||||
|
||||
#ifdef UTMP_COMPAT
|
||||
#include <ttyent.h>
|
||||
|
@ -3,6 +3,7 @@ project(libc-sys)
|
||||
cmake_minimum_required(VERSION 2.4.0)
|
||||
|
||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99")
|
||||
include_directories(${DARLING_TOP_DIRECTORY}/src/libnotify)
|
||||
|
||||
set(sys_sources chmodx_np.c
|
||||
crt_externs.c
|
||||
@ -19,7 +20,7 @@ set(sys_sources chmodx_np.c
|
||||
#OSThermalNotification.c
|
||||
posix_spawn.c
|
||||
semctl.c
|
||||
#settimeofday.c
|
||||
settimeofday.c
|
||||
shmctl.c
|
||||
sigaction.c
|
||||
sigcatch.c
|
||||
|
@ -44,6 +44,8 @@
|
||||
#ifdef DARLING
|
||||
# define _memcmp memcmp
|
||||
# define _bcmp bcmp
|
||||
.type memcmp, @function
|
||||
.type bcmp, @function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -49,6 +49,7 @@
|
||||
# define _memset_pattern8 memset_pattern8
|
||||
# define _memset_pattern16 memset_pattern16
|
||||
# define _bzero bzero@PLT
|
||||
.type memset, @function
|
||||
#endif
|
||||
|
||||
#define kShort 255 // for nonzero memset(), too short for commpage
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strcmp strcmp
|
||||
.type strcmp, @function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -39,6 +39,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strcpy strcpy
|
||||
.type strcpy, @function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -49,6 +49,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strlcat strlcat
|
||||
.type strlcat, @function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -46,6 +46,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strlcpy strlcpy
|
||||
.type strlcpy,@function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strlen strlen
|
||||
.type strlen, @function
|
||||
#endif
|
||||
|
||||
.text
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#ifdef DARLING
|
||||
# define _strncmp strncmp
|
||||
.type strncmp, @function
|
||||
#endif
|
||||
|
||||
#define kShort 20 // too short for vectors (must be >16)
|
||||
|
@ -46,6 +46,7 @@
|
||||
#ifdef DARLING
|
||||
# define _strncpy strncpy
|
||||
# define _bzero bzero@PLT
|
||||
.type strncpy, @function
|
||||
#endif
|
||||
|
||||
#define kShort 31 // too short to bother with vector loop
|
||||
|
@ -314,14 +314,15 @@ struct ProgramVars
|
||||
const char*** environPtr;
|
||||
const char** __prognamePtr;
|
||||
};
|
||||
extern "C" char** __darwin_environ;
|
||||
void __darling_get_args(int** argc, char**** argv, char**** env, struct ::ProgramVars* vars)
|
||||
{
|
||||
*argc = &g_argc;
|
||||
*argv = &g_argv;
|
||||
*env = &environ;
|
||||
*env = &__darwin_environ;
|
||||
vars->NXArgcPtr = &g_argc;
|
||||
vars->NXArgvPtr = (const char***) &g_argv;
|
||||
vars->environPtr = (const char***) &environ;
|
||||
vars->environPtr = (const char***) &__darwin_environ;
|
||||
vars->__prognamePtr = (const char**) &g_argv[0];
|
||||
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
#ifdef __x86_64__
|
||||
__asm__(".section .bss\n"
|
||||
".type __darwin_environ,@common\n"
|
||||
".size __darwin_environ, 8\n"
|
||||
".global __darwin_environ\n"
|
||||
".symver __darwin_environ, environ@DARWIN\n"
|
||||
"//.comm __darwin_environ, 8\n"
|
||||
|
@ -94,8 +94,8 @@ struct ProgramVars
|
||||
/*
|
||||
* libsyscall_initializer() initializes all of libSystem.dylib <rdar://problem/4892197>
|
||||
*/
|
||||
static __attribute__((constructor))
|
||||
void libSystem_initializer(/*int argc, const char* argv[], const char* envp[], const char* apple[], const struct ProgramVars* vars*/)
|
||||
//static
|
||||
void libSystem_initializer(int argc, const char* argv[], const char* envp[] /*, const char* apple[], const struct ProgramVars* vars*/)
|
||||
{
|
||||
static const struct _libkernel_functions libkernel_funcs = {
|
||||
.version = 1,
|
||||
@ -106,15 +106,30 @@ void libSystem_initializer(/*int argc, const char* argv[], const char* envp[], c
|
||||
._pthread_exit_if_canceled = _pthread_exit_if_canceled,
|
||||
};
|
||||
|
||||
int* argc;
|
||||
char*** argv;
|
||||
char*** envp;
|
||||
int* x_argc;
|
||||
char*** x_argv;
|
||||
char*** x_envp;
|
||||
char** apple = { NULL };
|
||||
struct ProgramVars vars;
|
||||
|
||||
/* Early initialization - original Apple code assumes pthread_init() doesn't print errors */
|
||||
__darling_get_args(&argc, &argv, &envp, &vars);
|
||||
__darling_set_libc_vars(argc, argv, envp);
|
||||
__darling_get_args(&x_argc, &x_argv, &x_envp, &vars);
|
||||
|
||||
if (!*x_argc)
|
||||
{
|
||||
// Darling libdyld is not being used
|
||||
// to execute a Mach-O binary.
|
||||
// Use what the ELF loader gave us.
|
||||
*x_argc = argc;
|
||||
*x_argv = argv;
|
||||
*x_envp = envp;
|
||||
vars.NXArgcPtr = x_argc;
|
||||
vars.NXArgvPtr = x_argv;
|
||||
vars.environPtr = x_envp;
|
||||
vars.__prognamePtr = &(*x_argv)[0];
|
||||
vars.mh = NULL;
|
||||
}
|
||||
__darling_set_libc_vars(x_argc, x_argv, x_envp);
|
||||
|
||||
/* cerror() calls require working pthread_self() */
|
||||
char dummy_self[4096];
|
||||
@ -144,6 +159,12 @@ void libSystem_initializer(/*int argc, const char* argv[], const char* envp[], c
|
||||
__objc_initialize();
|
||||
}
|
||||
|
||||
void (*const init_array []) (void)
|
||||
__attribute__ ((section (".init_array"), aligned (sizeof (void *)))) =
|
||||
{
|
||||
&libSystem_initializer
|
||||
};
|
||||
|
||||
/*
|
||||
* libSystem_atfork_{prepare,parent,child}() are called by libc when we fork, then we deal with running fork handlers
|
||||
* for everyone else.
|
||||
|
Loading…
Reference in New Issue
Block a user