]> git.saurik.com Git - apple/dyld.git/blob - src/glue.c
dyld-132.13.tar.gz
[apple/dyld.git] / src / glue.c
1 /* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*-
2 *
3 * Copyright (c) 2004-2009 Apple Inc. All rights reserved.
4 *
5 * @APPLE_LICENSE_HEADER_START@
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25 #include <stddef.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <time.h>
29 #include <unistd.h>
30 #include <stdarg.h>
31 #include <stdio.h>
32
33 // from _simple.h in libc
34 typedef struct _SIMPLE* _SIMPLE_STRING;
35 extern void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap);
36 extern void _simple_dprintf(int __fd, const char *__fmt, ...);
37 extern _SIMPLE_STRING _simple_salloc(void);
38 extern int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap);
39 extern void _simple_sfree(_SIMPLE_STRING __b);
40 extern char * _simple_string(_SIMPLE_STRING __b);
41
42 // dyld::log(const char* format, ...)
43 extern void _ZN4dyld3logEPKcz(const char*, ...);
44
45 // dyld::halt(const char* msg);
46 extern void _ZN4dyld4haltEPKc(const char* msg) __attribute__((noreturn));
47
48
49 // abort called by C++ unwinding code
50 void abort()
51 {
52 _ZN4dyld4haltEPKc("dyld calling abort()\n");
53 }
54
55 // std::terminate called by C++ unwinding code
56 void _ZSt9terminatev()
57 {
58 _ZN4dyld4haltEPKc("dyld std::terminate()\n");
59 }
60
61 // std::unexpected called by C++ unwinding code
62 void _ZSt10unexpectedv()
63 {
64 _ZN4dyld4haltEPKc("dyld std::unexpected()\n");
65 }
66
67 // __cxxabiv1::__terminate(void (*)()) called to terminate process
68 void _ZN10__cxxabiv111__terminateEPFvvE()
69 {
70 _ZN4dyld4haltEPKc("dyld std::__terminate()\n");
71 }
72
73 // __cxxabiv1::__unexpected(void (*)()) called to terminate process
74 void _ZN10__cxxabiv112__unexpectedEPFvvE()
75 {
76 _ZN4dyld4haltEPKc("dyld std::__unexpected()\n");
77 }
78
79 // __cxxabiv1::__terminate_handler
80 void* _ZN10__cxxabiv119__terminate_handlerE = &_ZSt9terminatev;
81
82 // __cxxabiv1::__unexpected_handler
83 void* _ZN10__cxxabiv120__unexpected_handlerE = &_ZSt10unexpectedv;
84
85 // libc uses assert()
86 void __assert_rtn(const char* func, const char* file, int line, const char* failedexpr)
87 {
88 if (func == NULL)
89 _ZN4dyld3logEPKcz("Assertion failed: (%s), file %s, line %d.\n", failedexpr, file, line);
90 else
91 _ZN4dyld3logEPKcz("Assertion failed: (%s), function %s, file %s, line %d.\n", failedexpr, func, file, line);
92 abort();
93 }
94
95
96 // called by libuwind code before aborting
97 size_t fwrite(const void* ptr, size_t size, size_t nitme, FILE* stream)
98 {
99 return fprintf(stream, "%s", (char*)ptr);
100 }
101
102 // called by libuwind code before aborting
103 int fprintf(FILE* file, const char* format, ...)
104 {
105 va_list list;
106 va_start(list, format);
107 _simple_vdprintf(STDERR_FILENO, format, list);
108 va_end(list);
109 return 0;
110 }
111
112 // called by LIBC_ABORT
113 void abort_report_np(const char* format, ...)
114 {
115 va_list list;
116 const char *str;
117 _SIMPLE_STRING s = _simple_salloc();
118 if ( s != NULL ) {
119 va_start(list, format);
120 _simple_vsprintf(s, format, list);
121 va_end(list);
122 str = _simple_string(s);
123 }
124 else {
125 // _simple_salloc failed, but at least format may have useful info by itself
126 str = format;
127 }
128 _ZN4dyld4haltEPKc(str);
129 // _ZN4dyld4haltEPKc doesn't return, so we can't call _simple_sfree
130 }
131
132
133 // real cthread_set_errno_self() has error handling that pulls in
134 // pthread_exit() which pulls in fprintf()
135 extern int* __error(void);
136 void cthread_set_errno_self(int err)
137 {
138 int* ep = __error();
139 *ep = err;
140 }
141
142 /*
143 * We have our own localtime() to avoid needing the notify API which is used
144 * by the code in libc.a for localtime() which is used by arc4random().
145 */
146 struct tm* localtime(const time_t* t)
147 {
148 return (struct tm*)NULL;
149 }
150
151
152 //
153 // The stack protector routines in lib.c bring in too much stuff, so
154 // make our own custom ones.
155 //
156 long __stack_chk_guard = 0;
157 static __attribute__((constructor)) void __guard_setup(void)
158 {
159 #if __LP64__
160 __stack_chk_guard = ((long)arc4random() << 32) | arc4random();
161 #else
162 __stack_chk_guard = arc4random();
163 #endif
164 }
165 extern void _ZN4dyld4haltEPKc(const char*);
166 void __stack_chk_fail()
167 {
168 _ZN4dyld4haltEPKc("stack buffer overrun");
169 }
170
171