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:
Lubos Dolezel 2015-12-21 00:56:09 +01:00
parent 33ddc75a38
commit 5983370373
35 changed files with 861 additions and 44 deletions

4
.gitmodules vendored
View File

@ -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
View 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)

View File

@ -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__ */

View File

@ -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>

View File

@ -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
View 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
View 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
View 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

View File

@ -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
View 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;
}

View File

@ -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

@ -0,0 +1 @@
Subproject commit 90e8afbf0c7afce065accc130aeb5b521b5738db

View File

@ -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

View 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;
}
}

View File

@ -0,0 +1,7 @@
#ifndef LINUX_GETLOGIN_H
#define LINUX_GETLOGIN_H
long sys_getlogin(char* buf, unsigned int len);
#endif

View File

@ -5,6 +5,7 @@ struct rlimit
{
unsigned long long rlim_cur;
unsigned long long rlim_max;
long _dummy[20];
};
enum {

View File

@ -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();

View File

@ -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,

View File

@ -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 ;\

View File

@ -152,6 +152,7 @@ L2:
#error Unsupported architecture
#endif
#if defined(__x86_64__)
.type vfork, @function
.globl vfork
vfork = __vfork
#endif

View File

@ -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})

View File

@ -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>

View File

@ -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

View File

@ -44,6 +44,8 @@
#ifdef DARLING
# define _memcmp memcmp
# define _bcmp bcmp
.type memcmp, @function
.type bcmp, @function
#endif
.text

View File

@ -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

View File

@ -37,6 +37,7 @@
#ifdef DARLING
# define _strcmp strcmp
.type strcmp, @function
#endif
.text

View File

@ -39,6 +39,7 @@
#ifdef DARLING
# define _strcpy strcpy
.type strcpy, @function
#endif
.text

View File

@ -49,6 +49,7 @@
#ifdef DARLING
# define _strlcat strlcat
.type strlcat, @function
#endif
.text

View File

@ -46,6 +46,7 @@
#ifdef DARLING
# define _strlcpy strlcpy
.type strlcpy,@function
#endif
.text

View File

@ -34,6 +34,7 @@
#ifdef DARLING
# define _strlen strlen
.type strlen, @function
#endif
.text

View File

@ -37,6 +37,7 @@
#ifdef DARLING
# define _strncmp strncmp
.type strncmp, @function
#endif
#define kShort 20 // too short for vectors (must be >16)

View File

@ -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

View File

@ -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];
}

View File

@ -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"

View File

@ -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.