this repo has no description
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Lots of work

+1467 -688
+19 -6
CMakeLists.txt
··· 9 9 enable_language(ASM_NASM) 10 10 ADD_DEFINITIONS(-ggdb -DDEBUG) 11 11 12 + if (SUFFIX STREQUAL "32") 13 + set(CMAKE_CPP_FLAGS "${CMAKE_CPP_FLAGS} -m32") 14 + endif(SUFFIX STREQUAL "32") 15 + 12 16 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) 13 17 include_directories(${CMAKE_CURRENT_SOURCE_DIR}) 14 18 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include/xnu) ··· 58 62 src/dyld/binfmt_misc.cpp 59 63 ) 60 64 61 - add_executable(dyld ${dyld_SRCS}) 62 - target_link_libraries(dyld -ldl -lpthread mach-o util) 65 + add_executable(dyld${SUFFIX} ${dyld_SRCS}) 66 + target_link_libraries(dyld${SUFFIX} -ldl -lpthread mach-o util) 63 67 64 68 set(fatmacho-extract_SRCS 65 69 src/dyld/extract.cpp 66 70 ) 67 71 68 72 add_executable(fatmacho-extract ${fatmacho-extract_SRCS}) 69 - target_link_libraries(fatmacho-extract -ldl -lpthread mach-o -Wl,-export-dynamic) 73 + target_link_libraries(fatmacho-extract -ldl -lpthread -l:./libmach-o.so -Wl,-export-dynamic) 70 74 71 75 set(motool_SRCS 72 76 src/motool/motool.cpp ··· 75 79 add_executable(motool ${motool_SRCS}) 76 80 target_link_libraries(motool mach-o) 77 81 78 - install(TARGETS dyld fatmacho-extract motool DESTINATION bin) 79 - install(TARGETS mach-o DESTINATION lib) 80 - install(FILES etc/dylib.conf DESTINATION /etc/darling) 82 + install(TARGETS dyld${SUFFIX} DESTINATION bin) 83 + 84 + # If building on a 64bit system, only install these for 64bits 85 + if (NOT DEFINED SUFFIX OR SUFFIX STREQUAL "64") 86 + install(TARGETS fatmacho-extract motool DESTINATION bin) 87 + install(FILES etc/dylib.conf DESTINATION /etc/darling) 88 + endif(NOT DEFINED SUFFIX OR SUFFIX STREQUAL "64") 89 + 90 + install(TARGETS mach-o DESTINATION lib${SUFFIX}) 81 91 82 92 add_subdirectory(src/libSystem) 83 93 add_subdirectory(src/libcxxdarwin) 94 + add_subdirectory(src/libncurses) 84 95 #add_subdirectory(src/CoreServices) 85 96 97 + add_dependencies(dyld${SUFFIX} mach-o) 98 +
+1 -1
etc/dylib.conf
··· 1 1 [aliases] 2 2 libintl.8.dylib=libSystem.B.dylib.so 3 3 libiconv.2.dylib=libSystem.B.dylib.so 4 - libncurses.5.4.dylib=libncurses.so.5 4 + #libncurses.5.4.dylib=libncurses.so.5 5 5 /usr/local/lib/darling/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation=libCoreFoundation.so 6 6 /usr/local/lib/darling/System/Library/Frameworks/CoreServices.framework/Versions/A/CoreServices=libgnustep-base.so 7 7
+6 -1
src/dyld/MachOLoader.cpp
··· 447 447 void MachOLoader::run(MachO& mach, int argc, char** argv, char** envp) 448 448 { 449 449 char* apple[2] = { g_darwin_executable_path, 0 }; 450 + std::vector<char*> envCopy; 451 + 452 + //for (int i = 0; envp[i]; i++) 453 + // envCopy.push_back(envp[i]); 454 + envCopy.push_back(0); 450 455 451 456 load(mach, g_darwin_executable_path); 452 457 setupDyldData(mach); ··· 457 462 458 463 mach.close(); 459 464 460 - runPendingInitFuncs(argc, argv, envp, apple); 465 + runPendingInitFuncs(argc, argv, &envCopy[0], apple); 461 466 462 467 fflush(stdout); 463 468 assert(argc > 0);
+217 -56
src/dyld/Trampoline.cpp
··· 7 7 #include <iostream> 8 8 #include <fstream> 9 9 #include <sstream> 10 + #include <stack> 10 11 11 12 TrampolineMgr* TrampolineMgr::m_pInstance = 0; 12 - int TrampolineMgr::m_nDepth = 0; 13 13 std::map<std::string, TrampolineMgr::FunctionInfo> TrampolineMgr::m_functionInfo; 14 + struct timeval TrampolineMgr::m_startup; 15 + 16 + static __thread std::stack<TrampolineMgr::ReturnInfo>* g_returnInfo; 17 + static std::ofstream* g_logger = 0; 18 + static pid_t g_loggerForPid = 0; 14 19 15 20 extern "C" void reg_saveall(); 16 21 extern "C" void reg_restoreall(); ··· 40 45 m_wd = p; 41 46 free(p); 42 47 } 48 + 49 + ::gettimeofday(&m_startup, nullptr); 43 50 44 51 std::cout << logPath() << std::endl; 45 52 } ··· 127 134 } 128 135 } 129 136 137 + std::string TrampolineMgr::formatTime(double ms) 138 + { 139 + const double HRS = 1000.0*60*60; 140 + const double MINS = 1000.0*60; 141 + const double SECS = 1000.0; 142 + std::stringstream ss; 143 + 144 + if (ms >= HRS) 145 + { 146 + int hrs = int(ms / HRS); 147 + ss << hrs << 'h'; 148 + ms -= double(hrs) * HRS; 149 + } 150 + if (ms >= MINS) 151 + { 152 + int mins = int(ms / MINS); 153 + ss << mins << 'm'; 154 + ms -= double(mins) * MINS; 155 + } 156 + if (ms >= SECS) 157 + { 158 + int secs = int(ms / SECS); 159 + ss << secs << 's'; 160 + ms -= double(secs) * SECS; 161 + } 162 + ss << ms << "ms"; 163 + return ss.str(); 164 + } 165 + 166 + std::string TrampolineMgr::callTime() 167 + { 168 + double ms; 169 + struct timeval now; 170 + 171 + ::gettimeofday(&now, nullptr); 172 + ms = (now.tv_sec - g_returnInfo->top().callTime.tv_sec) * 1000; 173 + ms += (now.tv_usec - g_returnInfo->top().callTime.tv_usec) / 1000.0; 174 + 175 + return formatTime(ms); 176 + } 177 + 130 178 std::string TrampolineMgr::timeStamp() 131 179 { 132 - char buf[50]; 133 - time_t t = time(0); 134 - struct tm tm; 180 + double ms; 181 + struct timeval now; 135 182 136 - localtime_r(&t, &tm); 137 - strftime(buf, sizeof(buf), "%H:%M:%S", &tm); 183 + ::gettimeofday(&now, nullptr); 184 + ms = (now.tv_sec - m_pInstance->m_startup.tv_sec) * 1000; 185 + ms += (now.tv_usec - m_pInstance->m_startup.tv_usec) / 1000.0; 138 186 139 - return buf; 187 + return formatTime(ms); 140 188 } 141 189 142 190 std::string TrampolineMgr::logPath() ··· 154 202 return ss.str(); 155 203 } 156 204 157 - bool TrampolineMgr::openLog(std::ofstream& stream) 205 + std::ostream* TrampolineMgr::getLogger() 158 206 { 159 - stream.open(logPath(), std::ios_base::out | std::ios_base::app); 160 - return stream.is_open(); 207 + if (g_loggerForPid == getpid()) 208 + return g_logger ? g_logger : &std::cerr; 209 + else 210 + { 211 + delete g_logger; 212 + g_logger = new std::ofstream(logPath(), std::ios_base::out | std::ios_base::app); 213 + 214 + if (!g_logger->is_open()) 215 + { 216 + delete g_logger; 217 + g_logger = 0; 218 + } 219 + g_loggerForPid = getpid(); 220 + return g_logger; 221 + } 161 222 } 162 223 163 224 void* TrampolineMgr::printInfo(uint32_t index, CallStack* stack) ··· 165 226 FunctionInfo* info = 0; 166 227 const std::string& name = m_pInstance->m_entries[index].name; 167 228 auto it = m_functionInfo.find(name); 168 - std::ofstream logFile; 169 - std::ostream* out = &logFile; 229 + std::ostream* out; 230 + ReturnInfo retInfo; 170 231 171 - if (!m_pInstance->openLog(logFile)) 172 - out = &(*out); 232 + out = m_pInstance->getLogger(); 173 233 174 - (*out) << std::string(m_nDepth, ' '); 175 - (*out) << '[' << timeStamp() << "] "; 234 + std::string stamp = timeStamp(); 235 + (*out) << '[' << stamp << "]"; 236 + (*out) << std::string((20 - stamp.size()) + g_returnInfo ? g_returnInfo->size() : 0, ' '); 176 237 177 238 if (it != m_functionInfo.end()) 178 239 { ··· 194 255 } 195 256 else 196 257 (*out) << m_pInstance->m_entries[index].name << "(?)\n" << std::flush; 197 - m_pInstance->m_entries[index].retAddr = stack->retAddr; 198 - 199 - m_nDepth++; 258 + 259 + if (!g_returnInfo) 260 + g_returnInfo = new std::stack<TrampolineMgr::ReturnInfo>; 261 + 262 + retInfo.retAddr = stack->retAddr; 263 + gettimeofday(&retInfo.callTime, 0); 264 + 265 + g_returnInfo->push(retInfo); 200 266 201 267 return m_pInstance->m_entries[index].addr; 202 268 } 203 269 204 270 void* TrampolineMgr::printInfoR(uint32_t index, CallStack* stack) 205 271 { 206 - void* rv = m_pInstance->m_entries[index].retAddr; 207 - std::ofstream logFile; 208 - std::ostream* out = &logFile; 272 + void* rv = g_returnInfo->top().retAddr; 273 + std::ostream* out; 209 274 210 - if (!m_pInstance->openLog(logFile)) 211 - out = &(*out); 212 - 213 - m_pInstance->m_entries[index].retAddr = 0; 214 - m_nDepth--; 215 - 275 + out = m_pInstance->getLogger(); 276 + 216 277 const std::string& name = m_pInstance->m_entries[index].name; 217 278 auto it = m_functionInfo.find(name); 218 279 219 - (*out) << std::string(m_nDepth, ' '); 220 - (*out) << '[' << timeStamp() << "] "; 221 - 280 + std::string stamp = timeStamp(); 281 + (*out) << '[' << stamp << "]"; 282 + (*out) << std::string((20 - stamp.size()) + g_returnInfo ? g_returnInfo->size() : 0, ' '); 283 + 222 284 if (it != m_functionInfo.end()) 223 285 { 224 286 ArgumentWalker w(stack); 225 - (*out) << "-> " << w.ret(it->second.retType) << '\n' << std::flush; 287 + (*out) << "-> " << w.ret(it->second.retType); 226 288 } 227 289 else 228 - (*out) << "-> ?\n" << std::flush; 290 + (*out) << "-> ?"; 291 + 292 + (*out) << " {" << callTime() << "}\n" << std::flush; 229 293 294 + g_returnInfo->pop(); 295 + 230 296 // standard retval in rax, double in xmm0 231 297 return rv; 232 298 } ··· 234 300 void Trampoline::init(uint32_t i, void* (*pDebug)(uint32_t,TrampolineMgr::CallStack*), void* (*pDebugR)(uint32_t,TrampolineMgr::CallStack*)) 235 301 { 236 302 // See trampoline in trampoline_helper.asm for source 303 + #ifdef __x86_64__ 237 304 memcpy(this, "\x49\xba\xb6\xb5\xb4\xb3\xb2\xb1\xb0\x00\x41\xff\xd2\xbf" 238 305 "\x56\x34\x12\x00\x48\x89\xe6\x48\xb9\xff\xee\xdd\xcc\xbb\xaa\x00\x00" 239 306 "\xff\xd1\x49\x89\xc3\x49\xba\xc6\xc5\xc4\xc3\xc2\xc1\xc0\x00\x41\xff" ··· 243 310 "\xc3\x49\xba\xc6\xc5\xc4\xc3\xc2\xc1\xc0\x00\x41\xff\xd2\x41\xff\xe3", 244 311 sizeof(*this) 245 312 ); 313 + #else 314 + memcpy(this, "\x68\xa3\xa2\xa1\xa0\xc3\x54\x68\x78\x56\x34\x12\x68\xb3" 315 + "\xb2\xb1\xb0\xc3\x89\x44\x24\xf8\x68\xc3\xc2\xc1\xc0\xc3\xe8\x00" 316 + "\x00\x00\x00\x8b\x04\x24\x83\xc0\x10\x89\x04\x24\x8b\x44\x24\xe0" 317 + "\xff\xe0\x90\x68\xa3\xa2\xa1\xa0\xc3\x54\x68\x78\x56\x34\x12\x68" 318 + "\xb9\xb9\xb9\xb9\xc3\x89\x44\x24\xf8\x68\xc3\xc2\xc1\xc0\xc3\x8b" 319 + "\x4c\x24\xe0\xff\xe1", 320 + sizeof(*this) 321 + ); 322 + 323 + #endif 246 324 247 325 this->reg_saveall = reinterpret_cast<uint64_t>(::reg_saveall); 248 326 this->reg_saveall2 = reinterpret_cast<uint64_t>(::reg_saveall); ··· 255 333 } 256 334 257 335 TrampolineMgr::ArgumentWalker::ArgumentWalker(CallStack* stack) 258 - : m_stack(stack), m_indexInt(0), m_indexXmm(0) 336 + : m_stack(stack) 259 337 { 338 + #ifdef __x86_64__ 339 + m_indexInt = m_indexXmm = 0; 340 + #else 341 + m_indexArg = 0; 342 + #endif 260 343 } 261 344 262 345 TrampolineMgr::ArgumentWalker::ArgumentWalker(CallStack* stack, OutputArguments args) 263 - : m_stack(stack), m_indexInt(0), m_indexXmm(0), m_pointers(args) 346 + : m_stack(stack), m_pointers(args) 264 347 { 348 + #ifdef __x86_64__ 349 + m_indexInt = m_indexXmm = 0; 350 + #else 351 + m_indexArg = 0; 352 + #endif 265 353 } 266 354 267 - 355 + #ifdef __x86_64__ 268 356 uint64_t TrampolineMgr::ArgumentWalker::next64bit() 269 357 { 270 358 uint64_t rv; ··· 287 375 return rv; 288 376 } 289 377 290 - long double TrampolineMgr::ArgumentWalker::nextDouble() 378 + long long TrampolineMgr::ArgumentWalker::nextLL() 379 + { 380 + uint64_t v = next64bit(); 381 + return *((long*) &v); 382 + } 383 + 384 + int TrampolineMgr::ArgumentWalker::nextInt() 385 + { 386 + uint64_t v = next64bit(); 387 + return *((int*) &v); 388 + } 389 + 390 + long double TrampolineMgr::ArgumentWalker::nextLongDouble() 291 391 { 292 392 long double rv; 293 393 if (m_indexXmm >= 0 && m_indexXmm <= 7) ··· 299 399 return rv; 300 400 } 301 401 402 + double TrampolineMgr::ArgumentWalker::nextDouble() 403 + { 404 + long double v = nextLongDouble(); 405 + return *((double*)&v); 406 + } 407 + 408 + float TrampolineMgr::ArgumentWalker::nextFloat() 409 + { 410 + long double v = nextLongDouble(); 411 + return *((float*)&v); 412 + } 413 + 414 + void* TrampolineMgr::ArgumentWalker::nextPointer() 415 + { 416 + uint64_t v = next64bit(); 417 + return (void*) v; 418 + } 419 + 420 + #else 421 + 422 + void* TrampolineMgr::ArgumentWalker::nextPointer() 423 + { 424 + uint32_t v = m_stack->arguments[m_indexArg++]; 425 + return (void*) v; 426 + } 427 + 428 + int TrampolineMgr::ArgumentWalker::nextInt() 429 + { 430 + uint32_t v = m_stack->arguments[m_indexArg++]; 431 + return *((int*) &v); 432 + } 433 + 434 + long long TrampolineMgr::ArgumentWalker::nextLL() 435 + { 436 + union 437 + { 438 + uint32_t b32[2]; 439 + long long b64; 440 + } ll; 441 + 442 + ll.b32[0] = m_stack->arguments[m_indexArg+1]; 443 + ll.b32[1] = m_stack->arguments[m_indexArg]; 444 + m_indexArg += 2; 445 + 446 + return ll.b64; 447 + } 448 + 449 + float TrampolineMgr::ArgumentWalker::nextFloat() 450 + { 451 + uint32_t v = m_stack->arguments[m_indexArg++]; 452 + return *((float*) &v); 453 + } 454 + 455 + double TrampolineMgr::ArgumentWalker::nextDouble() 456 + { 457 + double* d = (double*) &m_stack->arguments[m_indexArg]; 458 + m_indexArg += 2; 459 + return *d; 460 + } 461 + 462 + #endif 463 + 302 464 std::string TrampolineMgr::ArgumentWalker::next(char type) 303 465 { 304 466 std::stringstream ss; 305 467 void* ptr; 306 468 307 469 if (type == 'u') 308 - ss << next64bit(); 470 + ss << unsigned(nextInt()); 309 471 else if (type == 'i') 310 - { 311 - uint64_t u = next64bit(); 312 - ss << *((int64_t*) &u); 313 - } 472 + ss << nextInt(); 473 + else if (type == 'q') 474 + ss << nextLL(); 314 475 else if (type == 'f') 315 - { 316 - long double d = nextDouble(); 317 - ss << *((float*)&d); 318 - } 476 + ss << nextFloat(); 319 477 else if (type == 'd') 320 - { 321 - long double d = nextDouble(); 322 - ss << *((double*)&d); 323 - } 478 + ss << nextDouble(); 324 479 else if (type == 'p' || isupper(type)) 325 - { 326 - ptr = (void*) next64bit(); 327 - ss << ptr; 328 - } 480 + ss << nextPointer(); 329 481 else if (type == 'c') 330 - ss << char(next64bit()); 482 + ss << char(nextInt()); 331 483 else if (type == 's') 332 484 { 333 - const char* s = (const char*) next64bit(); 485 + const char* s = (const char*) nextPointer(); 334 486 ss << (void*)s; 335 487 if (s) 336 488 ss << " \"" << safeString(s) << '"'; ··· 346 498 return ss.str(); 347 499 } 348 500 501 + #ifdef __x86_64__ 349 502 std::string TrampolineMgr::ArgumentWalker::ret(char type) 350 503 { 351 504 std::stringstream ss; ··· 381 534 382 535 return ss.str(); 383 536 } 537 + #else 538 + std::string TrampolineMgr::ArgumentWalker::ret(char type) 539 + { 540 + std::stringstream ss; 541 + // TODO 542 + return ss.str(); 543 + } 544 + #endif 384 545 385 546 std::string TrampolineMgr::ArgumentWalker::safeString(const char* in) 386 547 {
+62 -9
src/dyld/Trampoline.h
··· 6 6 #include <list> 7 7 #include <map> 8 8 #include <fstream> 9 + #include <sys/time.h> 9 10 10 11 struct Trampoline; 11 12 ··· 21 22 22 23 static void loadFunctionInfo(const char* path); 23 24 24 - #pragma pack(1) 25 + #pragma pack(1) 26 + #ifdef __x86_64__ 25 27 struct CallStack 26 28 { 27 29 long double xmm[8]; // xmm7-xmm0 28 30 uint64_t r15, r14, r13, r12, r9, r8, rcx, rdx, rsi, rdi, rbx, rax; 29 31 void* retAddr; 30 32 }; 31 - #pragma pack() 33 + #else 34 + struct CallStack 35 + { 36 + uint32_t edi, esi, edx, ecx, ebx, eax; 37 + void* retAddr; 38 + uint32_t arguments[]; 39 + }; 40 + #endif 41 + #pragma pack() 32 42 private: 33 43 void loadMemoryMap(); 34 44 35 45 std::string logPath(); 36 - bool openLog(std::ofstream& stream); 46 + std::ostream* getLogger(); 37 47 static std::string timeStamp(); 48 + static std::string callTime(); 49 + static std::string formatTime(double ms); 38 50 static void* printInfo(uint32_t index, CallStack* stack); 39 51 static void* printInfoR(uint32_t index, CallStack* stack); 52 + public: 53 + typedef std::vector<std::pair<char,void*> > OutputArguments; 54 + struct ReturnInfo 55 + { 56 + void* retAddr; 57 + OutputArguments pointers; 58 + struct timeval callTime; 59 + }; 40 60 private: 41 - typedef std::vector<std::pair<char,void*> > OutputArguments; 42 61 struct AddrEntry 43 62 { 44 63 std::string name; 45 64 void* addr; 46 - void* retAddr; // not reentrant 47 - OutputArguments pointers; // not reentrant 48 65 }; 49 66 struct MemoryPages 50 67 { ··· 65 82 public: 66 83 ArgumentWalker(CallStack* stack); 67 84 ArgumentWalker(CallStack* stack, OutputArguments args /* for printInfoR only */); 85 + #ifdef __x86_64__ 68 86 uint64_t next64bit(); 69 - long double nextDouble(); 87 + long double nextLongDouble(); 88 + #endif 89 + int nextInt(); 90 + long long nextLL(); 91 + float nextFloat(); 92 + double nextDouble(); 93 + void* nextPointer(); 70 94 std::string next(char type); 71 95 std::string ret(char type); 72 96 OutputArguments getOutputArguments() { return m_pointers; } ··· 74 98 static std::string safeString(const char* in); 75 99 private: 76 100 CallStack* m_stack; 101 + #ifdef __x86_64__ 77 102 int m_indexInt, m_indexXmm; 103 + #else 104 + int m_indexArg; 105 + #endif 78 106 OutputArguments m_pointers; 79 107 }; 80 108 ··· 86 114 std::vector<AddrEntry> m_entries; 87 115 std::list<MemoryPages> m_memoryMap; 88 116 std::string m_wd; 89 - static int m_nDepth; 117 + static struct timeval m_startup; 90 118 static std::map<std::string, FunctionInfo> m_functionInfo; 91 119 }; 92 120 93 121 #pragma pack(1) 94 - struct Trampoline // 119 bytes // 63 code // 56 pointers 122 + struct Trampoline 95 123 { 96 124 void init(uint32_t index, void* (*pDebug)(uint32_t,TrampolineMgr::CallStack*), void* (*pDebugR)(uint32_t,TrampolineMgr::CallStack*)); 97 125 126 + #ifdef __x86_64__ 127 + 128 + // 119 bytes // 63 code // 56 pointers 98 129 char code1[2]; 99 130 uint64_t reg_saveall; 100 131 char code2[4]; ··· 113 144 uint64_t reg_restoreall2; 114 145 char code9[9]; 115 146 char padding[1]; 147 + #else 148 + // 83 bytes 149 + char code1; 150 + uint32_t reg_saveall; 151 + char code2[3]; 152 + uint32_t index; 153 + char code3; 154 + uint32_t debugFcn; 155 + char code4[6]; 156 + uint32_t reg_restoreall; 157 + char code5[23]; 158 + uint32_t reg_saveall2; 159 + char code6[3]; 160 + uint32_t index2; 161 + char code7; 162 + uint32_t debugFcnR; 163 + char code8[6]; 164 + uint32_t reg_restoreall2; 165 + char code9[7]; 166 + char padding[1]; 167 + 168 + #endif 116 169 }; 117 170 #pragma pack() 118 171
+1 -3
src/dyld/dyld.cpp
··· 64 64 if (!::realpath(argv[1], g_darwin_executable_path)) 65 65 ::strcpy(g_darwin_executable_path, argv[1]); 66 66 67 - setlocale(LC_CTYPE, ""); 67 + // setlocale(LC_CTYPE, ""); 68 68 if (getenv("DYLD_MTRACE") && atoi(getenv("DYLD_MTRACE"))) 69 69 mtrace(); 70 - #ifdef __x86_64__ 71 70 if (getenv("DYLD_TRAMPOLINE") && atoi(getenv("DYLD_TRAMPOLINE"))) 72 71 g_trampoline = true; 73 - #endif 74 72 75 73 g_mainBinary = MachO::readFile(argv[1], ARCH_NAME); 76 74
+38 -4
src/dyld/keymgr.cpp
··· 1 1 #include "keymgr.h" 2 + #include <pthread.h> 3 + #include <map> 2 4 3 - // Stubs should be sufficient 5 + struct Entry 6 + { 7 + void* value; 8 + pthread_mutex_t mutex; 9 + }; 10 + static std::map<unsigned,Entry> m_keymgr; 11 + static pthread_mutex_t m_mutexNew = PTHREAD_MUTEX_INITIALIZER; 4 12 5 13 void* _keymgr_get_and_lock_processwide_ptr(unsigned key) 6 14 { 7 - return 0; 15 + pthread_mutex_lock(&m_mutexNew); 16 + 17 + auto iter = m_keymgr.find(key); 18 + void* rv; 19 + 20 + if (iter == m_keymgr.end()) 21 + { 22 + Entry e = { 0, PTHREAD_MUTEX_INITIALIZER }; 23 + m_keymgr[key] = e; 24 + rv = 0; 25 + 26 + pthread_mutex_lock(&m_keymgr[key].mutex); 27 + } 28 + else 29 + { 30 + pthread_mutex_lock(&m_keymgr[key].mutex); 31 + rv = iter->second.value; 32 + } 33 + 34 + pthread_mutex_unlock(&m_mutexNew); 35 + return rv; 8 36 } 9 37 10 - int _keymgr_set_and_unlock_processwide_ptr(unsigned key, void* ptr) 38 + void _keymgr_set_and_unlock_processwide_ptr(unsigned key, void* ptr) 11 39 { 12 - return 0; 40 + m_keymgr[key].value = ptr; 41 + pthread_mutex_lock(&m_keymgr[key].mutex); 42 + } 43 + 44 + void _keymgr_unlock_processwide_ptr(unsigned key) 45 + { 46 + pthread_mutex_lock(&m_keymgr[key].mutex); 13 47 } 14 48
+2 -1
src/dyld/keymgr.h
··· 5 5 6 6 // Only these are needed for Unwind 7 7 void* _keymgr_get_and_lock_processwide_ptr(unsigned key); 8 - int _keymgr_set_and_unlock_processwide_ptr(unsigned key, void* ptr); 8 + void _keymgr_set_and_unlock_processwide_ptr(unsigned key, void* ptr); 9 + void _keymgr_unlock_processwide_ptr(unsigned key); 9 10 10 11 } 11 12
+3
src/dyld/ld.cpp
··· 564 564 565 565 extern "C" void* dyld_stub_binder() 566 566 { 567 + /* 567 568 long arg1, arg2; 568 569 asm ("movq (%%rsp), %%rbx;" 569 570 "movq %%rbx, %0;" ··· 571 572 "movq %%rbx, %1;" 572 573 : "=r" (arg1), "=r" (arg2) 573 574 ); 575 + */ 576 + // TODO 574 577 return 0; 575 578 } 576 579
+153 -21
src/dyld/public.cpp
··· 5 5 #include "trace.h" 6 6 #include <cstring> 7 7 #include <cstdlib> 8 + #include <link.h> 9 + #include <stddef.h> 10 + #include "../libmach-o/leb.h" 8 11 9 12 extern FileMap g_file_map; 10 13 extern "C" char* dyld_getDarwinExecutablePath(); ··· 68 71 return g_file_map.fileNameForAddr(addr); 69 72 } 70 73 71 - bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info) 74 + struct CBData 75 + { 76 + void* addr; 77 + struct dyld_unwind_sections* info; 78 + }; 79 + 80 + #pragma pack(1) 81 + struct eh_frame_hdr 82 + { 83 + uint8_t version, eh_frame_ptr_enc, fde_count_enc, table_enc; 84 + uint8_t eh_frame_ptr[]; 85 + }; 86 + #pragma pack() 87 + 88 + static uintptr_t readEncodedPointer(const eh_frame_hdr* hdr) 72 89 { 73 - TRACE1(addr); 74 - const FileMap::ImageMap* map = g_file_map.imageMapForAddr(addr); 75 - if (!map) 90 + uint8_t format = hdr->eh_frame_ptr_enc & 0xf; 91 + uint8_t rel = hdr->eh_frame_ptr_enc & 0xf0; 92 + uintptr_t val; 93 + bool isSigned = false; 94 + 95 + if (hdr->eh_frame_ptr_enc == 0xff) 96 + return 0; 97 + 98 + switch (format) 76 99 { 77 - Dl_info dinfo; 78 - if (dladdr(addr, &dinfo)) 100 + case 1: // unsigned LEB 101 + { 102 + const uint8_t* ptr = (uint8_t*) hdr->eh_frame_ptr; 103 + val = uleb128(ptr); 104 + break; 105 + } 106 + case 2: // 2 bytes 107 + val = *((uint16_t*) hdr->eh_frame_ptr); 108 + break; 109 + case 3: 110 + val = *((uint32_t*) hdr->eh_frame_ptr); 111 + break; 112 + case 4: 113 + val = *((uint64_t*) hdr->eh_frame_ptr); 114 + break; 115 + case 9: // signed LEB 79 116 { 80 - LOG << "The address given belongs to " << dinfo.dli_fname << ", sym " << dinfo.dli_sname << std::endl; 81 - if (strstr(dinfo.dli_fname, "/libcxxdarwin.so")) 82 - { 83 - return _dyld_find_unwind_sections((void*) 0x100000b60, info); 84 - LOG << "Returning fake data\n"; 85 - memset(info, 0, sizeof(*info)); 86 - return true; 87 - } 117 + const uint8_t* ptr = (uint8_t*) hdr->eh_frame_ptr; 118 + val = sleb128(ptr); 119 + break; 88 120 } 89 - return false; 121 + case 0xa: 122 + val = *((int16_t*) hdr->eh_frame_ptr); 123 + break; 124 + case 0xb: 125 + val = *((int32_t*) hdr->eh_frame_ptr); 126 + break; 127 + case 0xc: 128 + val = *((int64_t*) hdr->eh_frame_ptr); 129 + break; 130 + default: 131 + return 0; 90 132 } 91 133 92 - info->mh = &map->header; 93 - info->dwarf_section = reinterpret_cast<const void*>(map->eh_frame.first + map->slide); 94 - info->dwarf_section_length = map->eh_frame.second; 95 - info->compact_unwind_section = reinterpret_cast<const void*>(map->unwind_info.first + map->slide); 96 - info->compact_unwind_section_length = map->unwind_info.second; 134 + switch (rel) 135 + { 136 + case 0: // no change 137 + break; 138 + case 0x10: // pcrel 139 + val += uintptr_t(hdr) + 4; 140 + break; 141 + case 0x30: // eh_frame_hdr rel 142 + val += uintptr_t(hdr); 143 + break; 144 + default: 145 + return 0; 146 + } 97 147 98 - return true; 148 + return val; 149 + } 150 + 151 + static int dlCallback(struct dl_phdr_info *info, size_t size, void *data) 152 + { 153 + CBData* cbdata = static_cast<CBData*>(data); 154 + bool addrMatch = false; 155 + void* maxAddr = 0; 156 + const eh_frame_hdr* ehdr = 0; 157 + 158 + if (cbdata->info->dwarf_section) // we already have a match 159 + return 0; 160 + 161 + std::cout << "Looking into " << info->dlpi_name << std::endl; 162 + 163 + if (size < offsetof(struct dl_phdr_info, dlpi_phnum)) 164 + return 0; 165 + 166 + for (int i = 0; i < info->dlpi_phnum; i++) 167 + { 168 + const ElfW(Phdr)* phdr = &info->dlpi_phdr[i]; 169 + 170 + if (strstr(info->dlpi_name, "cxxdarwin")) 171 + { 172 + std::cout << "type: " << phdr->p_type << "; vaddr: " << phdr->p_vaddr << std::endl; 173 + } 174 + 175 + if (phdr->p_type == PT_LOAD) 176 + { 177 + void* from = (void*) (uintptr_t(info->dlpi_addr) + uintptr_t(phdr->p_vaddr)); 178 + void* to = ((char*)from) + phdr->p_memsz; 179 + 180 + if (cbdata->addr >= from && cbdata->addr < to) 181 + addrMatch = true; 182 + if (to > maxAddr) 183 + maxAddr = to; // TODO: this could be improved 184 + } 185 + else if (phdr->p_type == PT_GNU_EH_FRAME) 186 + { 187 + std::cout << "Found .eh_frame_hdr in " << info->dlpi_name << std::endl; 188 + ehdr = (eh_frame_hdr*) (uintptr_t(info->dlpi_addr) + phdr->p_vaddr); 189 + // cbdata->info->dwarf_section_length = phdr->p_memsz; 190 + } 191 + } 192 + 193 + if (addrMatch && ehdr) 194 + { 195 + std::cout << "*** Match found! " << info->dlpi_name << std::endl; 196 + 197 + // Now we find .eh_frame from .eh_frame_hdr 198 + if (ehdr->version != 1) 199 + return 0; 200 + cbdata->info->dwarf_section = (void*) readEncodedPointer(ehdr); 201 + cbdata->info->dwarf_section_length = uintptr_t(maxAddr) - uintptr_t(cbdata->info->dwarf_section); 202 + } 203 + 204 + return 0; 205 + } 206 + 207 + bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info) 208 + { 209 + TRACE1(addr); 210 + const FileMap::ImageMap* map = g_file_map.imageMapForAddr(addr); 211 + 212 + if (!map) // in ELF 213 + { 214 + memset(info, 0, sizeof(*info)); 215 + 216 + CBData data = { addr, info }; 217 + 218 + dl_iterate_phdr(dlCallback, &data); 219 + return info->dwarf_section != 0; 220 + } 221 + else // in Mach-O 222 + { 223 + info->mh = &map->header; 224 + info->dwarf_section = reinterpret_cast<const void*>(map->eh_frame.first + map->slide); 225 + info->dwarf_section_length = map->eh_frame.second; 226 + info->compact_unwind_section = 0; //reinterpret_cast<const void*>(map->unwind_info.first + map->slide); 227 + info->compact_unwind_section_length = 0; //map->unwind_info.second; 228 + 229 + return true; 230 + } 99 231 } 100 232
+78
src/dyld/trampoline_helper.nasm
··· 1 + %ifidn __OUTPUT_FORMAT__, elf64 2 + 1 3 BITS 64 2 4 section text 3 5 ··· 92 94 call r10 93 95 jmp r11 ; now we "return" to the original function 94 96 97 + %elifidn __OUTPUT_FORMAT__, elf 98 + 99 + BITS 32 100 + section text 101 + 102 + ;global trampoline 103 + global reg_saveall 104 + global reg_restoreall 105 + 106 + reg_saveall: ; 24 bytes on stack 107 + xchg eax, [esp] 108 + 109 + push ebx 110 + push ecx 111 + push edx 112 + push esi 113 + push edi 114 + 115 + jmp eax 116 + 117 + reg_restoreall: 118 + pop ebx 119 + mov eax, [esp+24] 120 + mov [esp+24], ebx 121 + 122 + pop edi 123 + pop esi 124 + pop edx 125 + pop ecx 126 + pop ebx 127 + 128 + ret 129 + 130 + trampoline: 131 + push 0xa0a1a2a3 ; call reg_saveall 132 + ret 133 + push esp 134 + push 0x12345678 ; index in entry table 135 + push 0xb0b1b2b3 136 + ret ; call print function 137 + 138 + mov [esp-8], eax 139 + push 0xc0c1c2c3 ; call reg_restoreall 140 + ret 141 + 142 + ; we cannot use IP-relative lea on 32bit x86 143 + call get_eip 144 + get_eip: 145 + mov eax, [esp] 146 + add eax, 0x10 ; this gives us the address of after_jump 147 + mov [esp], eax 148 + mov eax, [esp-32] 149 + 150 + jmp eax ; call the real function 151 + 152 + ALIGN 2 153 + after_jump: 154 + push 0xa0a1a2a3 155 + ret ; call reg_saveall 156 + push esp 157 + push 0x12345678 ; index in entry table 158 + push 0xb9b9b9b9 ; print function 2 159 + ret 160 + 161 + mov [esp-8], eax ; real return address 162 + push 0xc0c1c2c3 163 + ret ; call reg_restoreall 164 + 165 + mov ecx, [esp-32] 166 + jmp ecx ; return to the original caller 167 + 168 + %else 169 + 170 + %error "Unsupported platform" 171 + 172 + %endif
+4 -2
src/libSystem/CMakeLists.txt
··· 61 61 libc/net.cpp 62 62 libc/getpwent.cpp 63 63 libc/signals.cpp 64 + libc/termios.cpp 64 65 common/auto.cpp 65 66 common/path.cpp 66 67 ) ··· 86 87 87 88 add_library(System.B.dylib SHARED ${libc_SRCS} ${bsdkern_SRCS} ${machkern_SRCS}) 88 89 # -luuid to make uuid_ functions available for Darwin apps 89 - target_link_libraries(System.B.dylib -ldl -lpthread -luuid -lmach-o -l:libobjc.so.4 -lrt -lssl -lbsd) 90 + target_link_libraries(System.B.dylib -ldl -lpthread -luuid -l:../../libmach-o.so -lrt -lssl -lbsd -l:libobjc.so.4) 91 + add_dependencies(System.B.dylib mach-o) 90 92 91 - install(TARGETS System.B.dylib DESTINATION lib) 93 + install(TARGETS System.B.dylib DESTINATION lib${SUFFIX}) 92 94
+2 -2
src/libSystem/common/auto.cpp
··· 1 1 #include "auto.h" 2 2 3 - int Darling::flagsDarwinToNative(MappedFlag* flags, size_t count, int darwin) 3 + int Darling::flagsDarwinToNative(const MappedFlag* flags, size_t count, int darwin) 4 4 { 5 5 int out = 0; 6 6 for (size_t i = 0; i < count; i++) ··· 11 11 return out; 12 12 } 13 13 14 - int Darling::flagsNativeToDarwin(MappedFlag* flags, size_t count, int native) 14 + int Darling::flagsNativeToDarwin(const MappedFlag* flags, size_t count, int native) 15 15 { 16 16 int out = 0; 17 17 for (size_t i = 0; i < count; i++)
+2 -2
src/libSystem/common/auto.h
··· 43 43 int darwin; 44 44 int native; 45 45 }; 46 - int flagsDarwinToNative(MappedFlag* flags, size_t count, int darwin); 47 - int flagsNativeToDarwin(MappedFlag* flags, size_t count, int native); 46 + int flagsDarwinToNative(const MappedFlag* flags, size_t count, int darwin); 47 + int flagsNativeToDarwin(const MappedFlag* flags, size_t count, int native); 48 48 } 49 49 50 50 #endif
+20 -1
src/libSystem/kernel-bsd/wait.cpp
··· 2 2 #include "wait.h" 3 3 #include "libc/errno.h" 4 4 #include "libc/darwin_errno_codes.h" 5 + #include "libc/signals.h" 5 6 #include "log.h" 6 7 #include <sys/time.h> 7 8 #include <sys/resource.h> 9 + 10 + int __darwin_kill(pid_t pid, int sig) 11 + { 12 + int rv = kill(pid, Darling::signalDarwinToLinux(sig)); 13 + if (rv == -1) 14 + errnoOut(); 15 + return rv; 16 + } 8 17 9 18 pid_t __darwin_wait(int *stat_loc) 10 19 { ··· 31 40 pid_t __darwin_waitpid(pid_t pid, int *stat_loc, int options) 32 41 { 33 42 pid_t rv = waitpid(pid, stat_loc, options); 34 - return rv; // TODO 43 + if (WIFSIGNALED(*stat_loc)) 44 + { 45 + // rewrite the signal number 46 + // 0x7f on Linux 47 + int signum = (*stat_loc) & (0x7f); 48 + signum = Darling::signalLinuxToDarwin(signum); 49 + *stat_loc &= ~(0x7f); 50 + *stat_loc |= signum; 51 + } 52 + return rv; // TODO: check if compatible 35 53 } 54 +
+1
src/libSystem/kernel-bsd/wait.h
··· 5 5 extern "C" 6 6 { 7 7 8 + int __darwin_kill(pid_t pid, int sig); 8 9 pid_t __darwin_wait(int *stat_loc); 9 10 pid_t __darwin_wait3(int *stat_loc, int options, struct rusage *rusage); 10 11 pid_t __darwin_wait4(pid_t pid, int *stat_loc, int options, struct rusage *rusage);
+3 -1
src/libSystem/libc/nextstep.cpp
··· 3 3 #include <cstring> 4 4 #include <unistd.h> 5 5 6 + static char** my_environ = environ; 7 + 6 8 char*** _NSGetEnviron() 7 9 { 8 - return &environ; 10 + return &my_environ; 9 11 }
+96 -8
src/libSystem/libc/signals.cpp
··· 2 2 #include "signals.h" 3 3 #include "errno.h" 4 4 #include "common/auto.h" 5 + #include "Bidimap.h" 5 6 #include <signal.h> 7 + #include <iostream> 6 8 #include <memory> 7 9 #include "darwin_errno_codes.h" 8 10 ··· 16 18 { DARWIN_SA_SIGINFO, SA_SIGINFO } 17 19 }; 18 20 21 + typedef void(*HandlerType)(int,siginfo_t*,void*); 22 + static int g_sigLinuxToDarwin[33], g_sigDarwinToLinux[33]; 23 + static const int SIGNAL_MAX = 31; 24 + static HandlerType g_darwinHandlers[32]; 25 + 26 + __attribute__((constructor)) 27 + static void initializeSignalMaps() 28 + { 29 + Darling::Bidimap<int,33> map(g_sigLinuxToDarwin, g_sigDarwinToLinux); 30 + map.put(SIGHUP, DARWIN_SIGHUP); 31 + map.put(SIGINT, DARWIN_SIGINT); 32 + map.put(SIGQUIT, DARWIN_SIGQUIT); 33 + map.put(SIGILL, DARWIN_SIGILL); 34 + map.put(SIGTRAP, DARWIN_SIGTRAP); 35 + map.put(SIGABRT, DARWIN_SIGABRT); 36 + map.put(SIGPOLL, DARWIN_SIGPOLL); 37 + map.put(SIGFPE, DARWIN_SIGFPE); 38 + map.put(SIGKILL, DARWIN_SIGKILL); 39 + map.put(SIGBUS, DARWIN_SIGBUS); 40 + map.put(SIGSEGV, DARWIN_SIGSEGV); 41 + map.put(SIGSYS, DARWIN_SIGSYS); 42 + map.put(SIGPIPE, DARWIN_SIGPIPE); 43 + map.put(SIGALRM, DARWIN_SIGALRM); 44 + map.put(SIGTERM, DARWIN_SIGTERM); 45 + map.put(SIGURG, DARWIN_SIGURG); 46 + map.put(SIGSTOP, DARWIN_SIGSTOP); 47 + map.put(SIGTSTP, DARWIN_SIGTSTP); 48 + map.put(SIGCONT, DARWIN_SIGCONT); 49 + map.put(SIGCHLD, DARWIN_SIGCHLD); 50 + map.put(SIGTTIN, DARWIN_SIGTTIN); 51 + map.put(SIGTTOU, DARWIN_SIGTTOU); 52 + map.put(SIGIO, DARWIN_SIGIO); 53 + map.put(SIGXCPU, DARWIN_SIGXCPU); 54 + map.put(SIGXFSZ, DARWIN_SIGXFSZ); 55 + map.put(SIGVTALRM, DARWIN_SIGVTALRM); 56 + map.put(SIGPROF, DARWIN_SIGPROF); 57 + map.put(SIGWINCH, DARWIN_SIGWINCH); 58 + //map.put(SIGINFO, DARWIN_SIGINFO); // N/A on Linux 59 + map.put(SIGUSR1, DARWIN_SIGUSR1); 60 + map.put(SIGUSR2, DARWIN_SIGUSR2); 61 + 62 + std::fill(g_darwinHandlers, g_darwinHandlers+32, reinterpret_cast<HandlerType>(SIG_DFL)); 63 + } 64 + 65 + int Darling::signalLinuxToDarwin(int sig) 66 + { 67 + return g_sigLinuxToDarwin[sig]; 68 + } 69 + 70 + int Darling::signalDarwinToLinux(int sig) 71 + { 72 + return g_sigDarwinToLinux[sig]; 73 + } 74 + 75 + static void GenericHandler(int sig, siginfo_t* p, void* p2) 76 + { 77 + int dsig = g_sigLinuxToDarwin[sig]; 78 + g_darwinHandlers[sig](dsig, p, p2); 79 + } 80 + 81 + sighandler_t __darwin_signal(int signum, sighandler_t handler) 82 + { 83 + signum = g_sigDarwinToLinux[signum]; 84 + g_darwinHandlers[signum] = reinterpret_cast<HandlerType>(handler); 85 + 86 + if (handler != SIG_DFL && handler != SIG_IGN && handler) 87 + handler = reinterpret_cast<sighandler_t>(GenericHandler); 88 + 89 + return signal(signum, handler); 90 + } 91 + 19 92 static sigset_t sigsetDarwinToLinux(const __darwin_sigset_t* set) 20 93 { 21 94 sigset_t rv; 22 95 23 96 sigemptyset(&rv); 24 97 25 - for (int i = 0; i < 19; i++) 98 + for (int i = 0; i <= SIGNAL_MAX; i++) 26 99 { 27 100 if (*set & (1 << i)) 28 - sigaddset(&rv, i+1); 101 + sigaddset(&rv, g_sigDarwinToLinux[i+1]); 29 102 } 30 103 31 104 return rv; ··· 35 108 { 36 109 __darwin_sigset_t rv = 0; 37 110 38 - for (int i = 0; i < 19; i++) 111 + for (int i = 0; i <= SIGNAL_MAX; i++) 39 112 { 40 113 if (sigismember(set, i+1) > 0) 41 - rv |= (1 << (i+1)); 114 + rv |= (1 << g_sigLinuxToDarwin[i+1]); 42 115 } 43 116 44 117 return rv; 45 118 } 46 119 47 120 // TODO: check siginfo compatibility 121 + // TODO: map signal numbers for 48 122 int __darwin_sigaction(int signum, const struct __darwin_sigaction* act, struct __darwin_sigaction* oldact) 49 123 { 50 124 std::unique_ptr<struct sigaction> nact; 51 125 std::unique_ptr<struct sigaction> noldact; 126 + HandlerType oldhdl = 0; 127 + 128 + signum = g_sigDarwinToLinux[signum]; 52 129 53 130 if (oldact) 54 131 noldact.reset(new struct sigaction); ··· 60 137 nact->sa_handler = act->xsa_handler; 61 138 nact->sa_sigaction = act->xsa_sigaction; 62 139 nact->sa_mask = sigsetDarwinToLinux(&act->sa_mask); 140 + oldhdl = g_darwinHandlers[signum]; 141 + 142 + // defer a user-supplied function to a wrapper that will translate the signal number 143 + if (act->xsa_handler != 0 && act->xsa_handler != SIG_IGN && act->xsa_handler != SIG_DFL) 144 + { 145 + //std::cout << "Setting GenericHandler for " << signum << std::endl; 146 + nact->sa_sigaction = GenericHandler; 147 + } 148 + g_darwinHandlers[signum] = act->xsa_sigaction; 63 149 } 64 150 65 151 int rv = sigaction(signum, nact.get(), noldact.get()); ··· 72 158 oldact->xsa_sigaction = noldact->sa_sigaction; 73 159 else 74 160 oldact->xsa_handler = noldact->sa_handler; 161 + oldact->xsa_sigaction = oldhdl; 75 162 oldact->sa_mask = sigsetLinuxToDarwin(&noldact->sa_mask); 76 163 } 77 164 if (rv == -1) ··· 88 175 89 176 int __darwin_sigfillset(__darwin_sigset_t *set) 90 177 { 91 - *set = 0x7ffff; // 19 signals on Linux 178 + *set = 0xffffffff; 92 179 return 0; 93 180 } 94 181 95 182 int __darwin_sigaddset(__darwin_sigset_t *set, int signum) 96 183 { 97 - if (signum > 19) 184 + if (signum >= SIGNAL_MAX) 98 185 { 99 186 errno = DARWIN_EINVAL; 100 187 return -1; ··· 108 195 109 196 int __darwin_sigdelset(__darwin_sigset_t *set, int signum) 110 197 { 111 - if (signum > 19) 198 + if (signum >= SIGNAL_MAX) 112 199 { 113 200 errno = DARWIN_EINVAL; 114 201 return -1; ··· 122 209 123 210 int __darwin_sigismember(__darwin_sigset_t *set, int signum) 124 211 { 125 - if (signum > 19) 212 + if (signum >= SIGNAL_MAX) 126 213 { 127 214 errno = DARWIN_EINVAL; 128 215 return -1; ··· 172 259 int rv = sigwait(&nset, sig); 173 260 if (rv == -1) 174 261 errnoOut(); 262 + *sig = g_sigLinuxToDarwin[*sig]; 175 263 return rv; 176 264 } 177 265
+39
src/libSystem/libc/signals.h
··· 10 10 #define DARWIN_SA_NOCLDWAIT 0x0020 11 11 #define DARWIN_SA_SIGINFO 0x0040 12 12 13 + #define DARWIN_SIGHUP 1 14 + #define DARWIN_SIGINT 2 15 + #define DARWIN_SIGQUIT 3 16 + #define DARWIN_SIGILL 4 17 + #define DARWIN_SIGTRAP 5 18 + #define DARWIN_SIGABRT 6 19 + #define DARWIN_SIGPOLL 7 20 + #define DARWIN_SIGFPE 8 21 + #define DARWIN_SIGKILL 9 22 + #define DARWIN_SIGBUS 10 23 + #define DARWIN_SIGSEGV 11 24 + #define DARWIN_SIGSYS 12 25 + #define DARWIN_SIGPIPE 13 26 + #define DARWIN_SIGALRM 14 27 + #define DARWIN_SIGTERM 15 28 + #define DARWIN_SIGURG 16 29 + #define DARWIN_SIGSTOP 17 30 + #define DARWIN_SIGTSTP 18 31 + #define DARWIN_SIGCONT 19 32 + #define DARWIN_SIGCHLD 20 33 + #define DARWIN_SIGTTIN 21 34 + #define DARWIN_SIGTTOU 22 35 + #define DARWIN_SIGIO 23 36 + #define DARWIN_SIGXCPU 24 37 + #define DARWIN_SIGXFSZ 25 38 + #define DARWIN_SIGVTALRM 26 39 + #define DARWIN_SIGPROF 27 40 + #define DARWIN_SIGWINCH 28 41 + #define DARWIN_SIGINFO 29 42 + #define DARWIN_SIGUSR1 30 43 + #define DARWIN_SIGUSR2 31 44 + 13 45 typedef int __darwin_sigset_t; 14 46 struct __darwin_sigaction 15 47 { ··· 25 57 extern "C" 26 58 { 27 59 60 + sighandler_t __darwin_signal(int signum, sighandler_t handler); 28 61 int __darwin_sigaction(int signum, const struct __darwin_sigaction* act, struct __darwin_sigaction* oldact); 29 62 int __darwin_sigprocmask(int how, const __darwin_sigset_t *set, __darwin_sigset_t *oldset); 30 63 ··· 38 71 int __darwin_sigwait(const __darwin_sigset_t *set, int *sig); 39 72 int __darwin_sigpending(__darwin_sigset_t *set); 40 73 74 + } 75 + 76 + namespace Darling 77 + { 78 + int signalLinuxToDarwin(int sig); 79 + int signalDarwinToLinux(int sig); 41 80 } 42 81 43 82 #endif
+154
src/libSystem/libc/termios.cpp
··· 1 + #include "termios.h" 2 + #include "errno.h" 3 + #include "common/auto.h" 4 + #include <stdint.h> 5 + #include <cstring> 6 + 7 + const static uint8_t g_ccIndices[][2] = { 8 + {DARWIN_VEOF, VEOF}, {DARWIN_VEOL, VEOL}, {DARWIN_VEOL2, VEOL2}, {DARWIN_VERASE, VERASE}, {DARWIN_VWERASE, VWERASE}, 9 + {DARWIN_VKILL, VKILL}, {DARWIN_VREPRINT, VREPRINT}, {DARWIN_VINTR,VINTR}, {DARWIN_VQUIT, VQUIT}, {DARWIN_VSUSP, VSUSP}, 10 + {DARWIN_VSTART, VSTART}, {DARWIN_VSTOP, VSTOP}, {DARWIN_VLNEXT, VLNEXT}, {DARWIN_VDISCARD, VDISCARD}, {DARWIN_VMIN, VMIN}, 11 + {DARWIN_VTIME, VTIME} 12 + }; 13 + 14 + const static Darling::MappedFlag g_inputFlags[] = { 15 + {DARWIN_IGNBRK, IGNBRK}, {DARWIN_BRKINT, BRKINT}, {DARWIN_IGNPAR, IGNPAR}, {DARWIN_PARMRK, PARMRK}, 16 + /*{DARWIN_INPCL, INPCL},*/ {DARWIN_ISTRIP, ISTRIP}, {DARWIN_INLCR, INLCR}, {DARWIN_ICRNL, ICRNL}, {DARWIN_IXON, IXON}, 17 + {DARWIN_IXOFF, IXOFF}, /*{DARWIN_IXANZ, IXANZ},*/ {DARWIN_IMAXBEL, IMAXBEL}, {DARWIN_IUTF8, IUTF8} 18 + }; 19 + 20 + const static Darling::MappedFlag g_outputFlags[] = { 21 + {DARWIN_OPOST, OPOST}, {DARWIN_ONLCR, ONLCR}, /*{DARWIN_OXTABS, OXTABS},*/ /*{DARWIN_ONOEOT, ONOEOT} */ 22 + }; 23 + 24 + const static Darling::MappedFlag g_controlFlags[] = { 25 + /*{DARWIN_XIGNORE, XIGNORE}, */ {DARWIN_CSIZE, CSIZE}, {DARWIN_CS5, CS5}, {DARWIN_CS6, CS6}, {DARWIN_CS7, CS7}, 26 + {DARWIN_CS8, CS8}, {DARWIN_CSTOPB, CSTOPB}, {DARWIN_CREAD, CREAD}, {DARWIN_PARENB, PARENB}, {DARWIN_PARODD, PARODD}, 27 + {DARWIN_HUPCL, HUPCL}, {DARWIN_CLOCAL, CLOCAL}, /*{DARWIN_CCTS_OFLOW, CCTS_OFLOW}, {DARWIN_CRTS_IFLOW, CRTS_IFLOW}, 28 + {DARWIN_CDTR_IFLOW, CDTR_IFLOW}, {DARWIN_CDSR_OFLOW, CDSR_OFLOW}, {DARWIN_CCAR_OFLOW, CCAR_OFLOW}*/ 29 + }; 30 + 31 + const static Darling::MappedFlag g_localFlags[] = { 32 + {DARWIN_ECHOKE, ECHOKE}, {DARWIN_ECHOE, ECHOE}, {DARWIN_ECHOK, ECHOK}, {DARWIN_ECHO, ECHO}, {DARWIN_ECHONL, ECHONL}, 33 + /* {DARWIN_ECHOPTR, ECHOPTR}, */ {DARWIN_ECHOCTL, ECHOCTL}, {DARWIN_ISIG, ISIG}, {DARWIN_ICANON, ICANON}, 34 + /* {DARWIN_ALTWERASE, ALTWERASE}, */ {DARWIN_IEXTEN, IEXTEN}, {DARWIN_EXTPROC, EXTPROC}, {DARWIN_TOSTOP, TOSTOP}, 35 + {DARWIN_FLUSHO, FLUSHO}, {DARWIN_PENDIN, PENDIN}, {int(DARWIN_NOFLSH), NOFLSH} 36 + }; 37 + 38 + static void termiosDarwinToLinux(const struct __darwin_termios* p, struct termios* n) 39 + { 40 + n->c_ispeed = p->c_ispeed; 41 + n->c_ospeed = p->c_ospeed; 42 + n->c_line = p->c_line; 43 + 44 + memset(n->c_cc, 0, sizeof(n->c_cc)); 45 + 46 + for (int i = 0; i < sizeof(g_ccIndices) / sizeof(g_ccIndices[0]); i++) 47 + { 48 + if (p->c_cc[g_ccIndices[i][0]]) 49 + n->c_cc[g_ccIndices[i][1]] = 1; 50 + } 51 + 52 + n->c_oflag = Darling::flagsDarwinToNative(g_outputFlags, sizeof(g_outputFlags)/sizeof(g_outputFlags[0]), p->c_oflag); 53 + n->c_iflag = Darling::flagsDarwinToNative(g_inputFlags, sizeof(g_inputFlags)/sizeof(g_inputFlags[0]), p->c_iflag); 54 + n->c_cflag = Darling::flagsDarwinToNative(g_controlFlags, sizeof(g_controlFlags)/sizeof(g_controlFlags[0]), p->c_cflag); 55 + n->c_lflag = Darling::flagsDarwinToNative(g_localFlags, sizeof(g_localFlags)/sizeof(g_localFlags[0]), p->c_lflag); 56 + } 57 + 58 + static void termiosLinuxToDarwin(const struct termios* p, struct __darwin_termios* d) 59 + { 60 + d->c_ispeed = p->c_ispeed; 61 + d->c_ospeed = p->c_ospeed; 62 + d->c_line = p->c_line; 63 + 64 + memset(d->c_cc, 0, sizeof(d->c_cc)); 65 + 66 + for (int i = 0; i < sizeof(g_ccIndices) / sizeof(g_ccIndices[0]); i++) 67 + { 68 + if (p->c_cc[g_ccIndices[i][1]]) 69 + d->c_cc[g_ccIndices[i][0]] = 1; 70 + } 71 + 72 + d->c_oflag = Darling::flagsNativeToDarwin(g_outputFlags, sizeof(g_outputFlags)/sizeof(g_outputFlags[0]), p->c_oflag); 73 + d->c_iflag = Darling::flagsNativeToDarwin(g_inputFlags, sizeof(g_inputFlags)/sizeof(g_inputFlags[0]), p->c_iflag); 74 + d->c_cflag = Darling::flagsNativeToDarwin(g_controlFlags, sizeof(g_controlFlags)/sizeof(g_controlFlags[0]), p->c_cflag); 75 + d->c_lflag = Darling::flagsNativeToDarwin(g_localFlags, sizeof(g_localFlags)/sizeof(g_localFlags[0]), p->c_lflag); 76 + } 77 + 78 + int __darwin_tcgetattr(int fd, struct __darwin_termios *termios_p) 79 + { 80 + struct termios n; 81 + int rv = tcgetattr(fd, &n); 82 + 83 + if (rv == -1) 84 + errnoOut(); 85 + else 86 + termiosLinuxToDarwin(&n, termios_p); 87 + return rv; 88 + } 89 + 90 + int __darwin_tcsetattr(int fd, int optional_actions, const struct __darwin_termios *termios_p) 91 + { 92 + struct termios n; 93 + termiosDarwinToLinux(termios_p, &n); 94 + 95 + int rv = tcsetattr(fd, optional_actions, &n); 96 + if (rv == -1) 97 + errnoOut(); 98 + return rv; 99 + } 100 + 101 + void __darwin_cfmakeraw(struct __darwin_termios *termios_p) 102 + { 103 + // from man termios(3) 104 + termios_p->c_iflag &= ~(DARWIN_IGNBRK | DARWIN_BRKINT | DARWIN_PARMRK | DARWIN_ISTRIP | DARWIN_INLCR | /*DARWIN_IGNCR |*/ DARWIN_ICRNL | DARWIN_IXON); 105 + termios_p->c_oflag &= ~DARWIN_OPOST; 106 + termios_p->c_lflag &= ~(DARWIN_ECHO | DARWIN_ECHONL | DARWIN_ICANON | DARWIN_ISIG | DARWIN_IEXTEN); 107 + termios_p->c_cflag &= ~(DARWIN_CSIZE | DARWIN_PARENB); 108 + termios_p->c_cflag |= DARWIN_CS8; 109 + } 110 + 111 + long __darwin_cfgetispeed(const struct __darwin_termios *termios_p) 112 + { 113 + return termios_p->c_ispeed; 114 + } 115 + 116 + long __darwin_cfgetospeed(const struct __darwin_termios *termios_p) 117 + { 118 + return termios_p->c_ospeed; 119 + } 120 + 121 + int __darwin_cfsetispeed(struct __darwin_termios *termios_p, long speed) 122 + { 123 + termios_p->c_ispeed = speed; 124 + return 0; 125 + } 126 + 127 + int __darwin_cfsetospeed(struct __darwin_termios *termios_p, long speed) 128 + { 129 + termios_p->c_ospeed = speed; 130 + return 0; 131 + } 132 + 133 + int __darwin_cfsetspeed(struct __darwin_termios *termios_p, long speed) 134 + { 135 + termios_p->c_ospeed = termios_p->c_ispeed = speed; 136 + return 0; 137 + } 138 + 139 + int __darwin_tcflush(int fd, int queue_selector) 140 + { 141 + int rv = tcflush(fd, queue_selector-1); 142 + if (rv == -1) 143 + errnoOut(); 144 + return rv; 145 + } 146 + 147 + int __darwin_tcflow(int fd, int action) 148 + { 149 + int rv = tcflow(fd, action-1); 150 + if (rv == -1) 151 + errnoOut(); 152 + return rv; 153 + } 154 +
+116
src/libSystem/libc/termios.h
··· 1 + #ifndef LIBC_TERMIOS_H 2 + #define LIBC_TERMIOS_H 3 + #include <termios.h> 4 + 5 + extern "C" 6 + { 7 + 8 + #define DARWIN_NCCS 20 9 + struct __darwin_termios 10 + { 11 + long c_iflag; // 4 on Linux, 4/8 on BSD 12 + long c_oflag; 13 + long c_cflag; 14 + long c_lflag; 15 + cc_t c_line; // 1 16 + cc_t c_cc[DARWIN_NCCS]; // 32 on Linux, 20 on BSD 17 + long c_ispeed; // 4 on Linux, 4/8 on BSD 18 + long c_ospeed; 19 + }; 20 + 21 + int __darwin_tcgetattr(int fd, struct __darwin_termios *termios_p); 22 + int __darwin_tcsetattr(int fd, int optional_actions, const struct __darwin_termios *termios_p); 23 + void __darwin_cfmakeraw(struct __darwin_termios *termios_p); 24 + long __darwin_cfgetispeed(const struct __darwin_termios *termios_p); 25 + long __darwin_cfgetospeed(const struct __darwin_termios *termios_p); 26 + int __darwin_cfsetispeed(struct __darwin_termios *termios_p, long speed); 27 + int __darwin_cfsetospeed(struct __darwin_termios *termios_p, long speed); 28 + int __darwin_cfsetspeed(struct __darwin_termios *termios_p, long speed); 29 + 30 + int __darwin_tcflush(int fd, int queue_selector); 31 + int __darwin_tcflow(int fd, int action); 32 + 33 + // cc_t 34 + #define DARWIN_VEOF 0 35 + #define DARWIN_VEOL 1 36 + #define DARWIN_VEOL2 2 37 + #define DARWIN_VERASE 3 38 + #define DARWIN_VWERASE 4 39 + #define DARWIN_VKILL 5 40 + #define DARWIN_VREPRINT 6 41 + #define DARWIN_VINTR 8 42 + #define DARWIN_VQUIT 9 43 + #define DARWIN_VSUSP 10 44 + // #define DARWIN_VDSUSP 11 45 + #define DARWIN_VSTART 12 46 + #define DARWIN_VSTOP 13 47 + #define DARWIN_VLNEXT 14 48 + #define DARWIN_VDISCARD 15 49 + #define DARWIN_VMIN 16 50 + #define DARWIN_VTIME 17 51 + // #define DARWIN_VSTATUS 19 52 + // #define DARWIN_NCCS 20 53 + 54 + // input flags 55 + #define DARWIN_IGNBRK 0x1 56 + #define DARWIN_BRKINT 0x2 57 + #define DARWIN_IGNPAR 0x4 58 + #define DARWIN_PARMRK 0x8 59 + #define DARWIN_INPCL 0x10 60 + #define DARWIN_ISTRIP 0x20 61 + #define DARWIN_INLCR 0x80 62 + #define DARWIN_ICRNL 0x100 63 + #define DARWIN_IXON 0x200 64 + #define DARWIN_IXOFF 0x400 65 + #define DARWIN_IXANZ 0x800 66 + #define DARWIN_IMAXBEL 0x2000 67 + #define DARWIN_IUTF8 0x4000 68 + 69 + // output flags 70 + #define DARWIN_OPOST 0x1 71 + #define DARWIN_ONLCR 0x2 72 + #define DARWIN_OXTABS 0x4 73 + #define DARWIN_ONOEOT 0x8 74 + 75 + // control flags 76 + #define DARWIN_XIGNORE 0x1 77 + #define DARWIN_CSIZE 0x300 78 + #define DARWIN_CS5 0 79 + #define DARWIN_CS6 0x100 80 + #define DARWIN_CS7 0x200 81 + #define DARWIN_CS8 0x300 82 + #define DARWIN_CSTOPB 0x400 83 + #define DARWIN_CREAD 0x800 84 + #define DARWIN_PARENB 0x1000 85 + #define DARWIN_PARODD 0x2000 86 + #define DARWIN_HUPCL 0x4000 87 + #define DARWIN_CLOCAL 0x8000 88 + #define DARWIN_CCTS_OFLOW 0x10000 89 + #define DARWIN_CRTS_IFLOW 0x20000 90 + #define DARWIN_CDTR_IFLOW 0x40000 91 + #define DARWIN_CDSR_OFLOW 0x80000 92 + #define DARWIN_CCAR_OFLOW 0x100000 93 + 94 + // local flags 95 + #define DARWIN_ECHOKE 0x1 96 + #define DARWIN_ECHOE 0x2 97 + #define DARWIN_ECHOK 0x4 98 + #define DARWIN_ECHO 0x8 99 + #define DARWIN_ECHONL 0x10 100 + #define DARWIN_ECHOPTR 0x20 101 + #define DARWIN_ECHOCTL 0x40 102 + #define DARWIN_ISIG 0x80 103 + #define DARWIN_ICANON 0x100 104 + #define DARWIN_ALTWERASE 0x200 105 + #define DARWIN_IEXTEN 0x400 106 + #define DARWIN_EXTPROC 0x800 107 + #define DARWIN_TOSTOP 0x400000 108 + #define DARWIN_FLUSHO 0x800000 109 + //#define DARWIN_NOKERNINFO 0x2000000 110 + #define DARWIN_PENDIN 0x20000000 111 + #define DARWIN_NOFLSH 0x80000000 112 + 113 + } 114 + 115 + #endif 116 +
+10 -5
src/libcxxdarwin/CMakeLists.txt
··· 6 6 endif(COMMAND cmake_policy) 7 7 8 8 enable_language(ASM-ATT) 9 - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -std=c99 -D__darwin_natural_t=long -I./include -I ../../include/darwin -fPIC -Ddladdr=__darwin_dladdr -ggdb") 10 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I./include -stdlib=libc++ -fPIC -Ddl_info=Dl_info -Ddladdr=__darwin_dladdr -Wno-format -ggdb") 9 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w -std=c99 -D__darwin_natural_t=long -I./include -I ../../include/darwin -fPIC -Ddladdr=__darwin_dladdr -gdwarf-2") 10 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I./include -stdlib=libc++ -fPIC -Ddl_info=Dl_info -Ddladdr=__darwin_dladdr -Wno-format -gdwarf-2") 11 11 set(CMAKE_SHARED_LINKER_FLAGS "-stdlib=libc++ -Wl,-Bsymbolic -Wl,-Bsymbolic-functions") 12 12 13 + if (SUFFIX STREQUAL "32") 14 + set(FLAGS "-m32") 15 + SET(CMAKE_ASM-ATT_FLAGS "--32") 16 + endif (SUFFIX STREQUAL "32") 17 + 13 18 message(STATUS "${CMAKE_CURRENT_SOURCE_DIR}") 14 19 ADD_CUSTOM_COMMAND(OUTPUT src-unwind/Registers.s 15 - COMMAND ${CMAKE_C_COMPILER} ARGS -E src-unwind/Registers.S -o src-unwind/Registers.s 20 + COMMAND ${CMAKE_C_COMPILER} ARGS -E src-unwind/Registers.S ${FLAGS} -o src-unwind/Registers.s 16 21 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") 17 22 ADD_CUSTOM_COMMAND(OUTPUT src-unwind/unw_getcontext.s 18 - COMMAND "${CMAKE_C_COMPILER}" ARGS -E src-unwind/unw_getcontext.S -o src-unwind/unw_getcontext.s 23 + COMMAND "${CMAKE_C_COMPILER}" ARGS -E src-unwind/unw_getcontext.S ${FLAGS} -o src-unwind/unw_getcontext.s 19 24 WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}") 20 25 21 26 set (cxxdarwin_SRCS ··· 31 36 ) 32 37 33 38 add_library(cxxdarwin SHARED ${cxxdarwin_SRCS} ${abi_SRCS}) 34 - install(TARGETS cxxdarwin DESTINATION lib) 39 + install(TARGETS cxxdarwin DESTINATION lib${SUFFIX}) 35 40
+9 -9
src/libcxxdarwin/src-unwind/DwarfParser.hpp
··· 212 212 template <typename A> 213 213 bool CFI_Parser<A>::findFDE(A& addressSpace, pint_t pc, pint_t ehSectionStart, uint32_t sectionLength, pint_t fdeHint, FDE_Info* fdeInfo, CIE_Info* cieInfo) 214 214 { 215 - //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc); 215 + fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc); 216 216 pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart; 217 217 const pint_t ehSectionEnd = p + sectionLength; 218 218 while ( p < ehSectionEnd ) { 219 219 pint_t currentCFI = p; 220 - //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p); 220 + fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p); 221 221 uint64_t cfiLength = addressSpace.get32(p); 222 222 p += 4; 223 223 if ( cfiLength == 0xffffffff ) { ··· 244 244 // parse pc begin and range 245 245 pint_t pcStart = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding); 246 246 pint_t pcRange = addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F); 247 - //fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 247 + fprintf(stderr, "FDE with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 248 248 // test if pc is within the function this FDE covers 249 249 if ( (pcStart < pc) && (pc <= pcStart+pcRange) ) { 250 250 // parse rest of info ··· 269 269 fdeInfo->fdeInstructions = p; 270 270 fdeInfo->pcStart = pcStart; 271 271 fdeInfo->pcEnd = pcStart+pcRange; 272 - //fprintf(stderr, "findFDE(pc=0x%llX) found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 272 + fprintf(stderr, "findFDE(pc=0x%llX) found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 273 273 return true; 274 274 } 275 275 else { 276 - //fprintf(stderr, "findFDE(pc=0x%llX) not found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 276 + fprintf(stderr, "findFDE(pc=0x%llX) not found with pcRange [0x%08llX, 0x%08llX)\n",(uint64_t)pc, (uint64_t)pcStart, (uint64_t)(pcStart+pcRange)); 277 277 // pc is not in begin/range, skip this FDE 278 278 } 279 279 } 280 280 else { 281 281 // malformed CIE, now augmentation describing pc range encoding 282 - //fprintf(stderr, "malformed CIE\n"); 282 + fprintf(stderr, "malformed CIE\n"); 283 283 } 284 284 } 285 285 else { 286 286 // malformed FDE. CIE is bad 287 - //fprintf(stderr, "malformed FDE, cieStart=0x%llX, ehSectionStart=0x%llX, ehSectionEnd=0x%llX\n", 288 - // (uint64_t)cieStart, (uint64_t)ehSectionStart, (uint64_t)ehSectionEnd); 287 + fprintf(stderr, "malformed FDE, cieStart=0x%llX, ehSectionStart=0x%llX, ehSectionEnd=0x%llX\n", 288 + (uint64_t)cieStart, (uint64_t)ehSectionStart, (uint64_t)ehSectionEnd); 289 289 } 290 290 p = nextCFI; 291 291 } 292 292 } 293 - //fprintf(stderr, "findFDE(pc=0x%llX) not found\n",(uint64_t)pc); 293 + fprintf(stderr, "findFDE(pc=0x%llX) not found\n",(uint64_t)pc); 294 294 return false; 295 295 } 296 296
+5 -5
src/libcxxdarwin/src-unwind/UnwindCursor.hpp
··· 488 488 if ( !foundFDE ) { 489 489 // otherwise, search cache of previously found FDEs 490 490 pint_t cachedFDE = DwarfFDECache<A>::findFDE(mh, pc); 491 - //fprintf(stderr, "getInfoFromDwarfSection(pc=0x%llX) cachedFDE=0x%llX\n", (uint64_t)pc, (uint64_t)cachedFDE); 491 + fprintf(stderr, "getInfoFromDwarfSection(pc=0x%llX) cachedFDE=0x%llX\n", (uint64_t)pc, (uint64_t)cachedFDE); 492 492 if ( cachedFDE != 0 ) { 493 493 foundFDE = CFI_Parser<A>::findFDE(fAddressSpace, pc, ehSectionStart, sectionLength, cachedFDE, &fdeInfo, &cieInfo); 494 494 foundInCache = foundFDE; 495 - //fprintf(stderr, "cachedFDE=0x%llX, foundInCache=%d\n", (uint64_t)cachedFDE, foundInCache); 495 + fprintf(stderr, "cachedFDE=0x%llX, foundInCache=%d\n", (uint64_t)cachedFDE, foundInCache); 496 496 } 497 497 } 498 498 #endif ··· 516 516 fInfo.extra = (unw_word_t)mh; 517 517 if ( !foundInCache && (sectionOffsetOfFDE == 0) ) { 518 518 // don't add to cache entries the compact encoding table can find quickly 519 - //fprintf(stderr, "getInfoFromDwarfSection(pc=0x%0llX), mh=0x%llX, start_ip=0x%0llX, fde=0x%0llX, personality=0x%0llX\n", 520 - // (uint64_t)pc, (uint64_t)mh, fInfo.start_ip, fInfo.unwind_info, fInfo.handler); 519 + fprintf(stderr, "getInfoFromDwarfSection(pc=0x%0llX), mh=0x%llX, start_ip=0x%0llX, fde=0x%0llX, personality=0x%0llX\n", 520 + (uint64_t)pc, (uint64_t)mh, fInfo.start_ip, fInfo.unwind_info, fInfo.handler); 521 521 #if !FOR_DYLD 522 522 DwarfFDECache<A>::add(mh, fdeInfo.pcStart, fdeInfo.pcEnd, fdeInfo.fdeStart); 523 523 #endif ··· 525 525 return true; 526 526 } 527 527 } 528 - //DEBUG_MESSAGE("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc); 528 + DEBUG_MESSAGE("can't find/use FDE for pc=0x%llX\n", (uint64_t)pc); 529 529 return false; 530 530 } 531 531
+43 -4
src/libcxxdarwin/src-unwind/UnwindLevel1.c
··· 39 39 #include "unwind.h" 40 40 #include "InternalMacros.h" 41 41 42 + extern void* __gxx_personality_v0; 43 + 42 44 #if __ppc__ || __i386__ || __x86_64__ 43 45 44 46 static _Unwind_Reason_Code unwind_phase1(unw_context_t* uc, struct _Unwind_Exception* exception_object) 45 47 { 46 48 unw_cursor_t cursor1; 47 49 unw_init_local(&cursor1, uc); 50 + 51 + int count = 0; 48 52 49 53 // walk each frame looking for a place to stop 50 - for (bool handlerNotFound = true; handlerNotFound; ) { 54 + for (bool handlerNotFound = true; handlerNotFound; count++) { 51 55 52 56 // ask libuwind to get next frame (skip over first which is _Unwind_RaiseException) 53 57 int stepResult = unw_step(&cursor1); 54 58 if ( stepResult == 0 ) { 59 + if (count < 2) continue; 55 60 DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): unw_step() reached bottom => _URC_END_OF_STACK\n", exception_object); 56 61 return _URC_END_OF_STACK; 57 62 } ··· 83 88 // if there is a personality routine, ask it if it will want to stop at this frame 84 89 if ( frameInfo.handler != 0 ) { 85 90 __personality_routine p = (__personality_routine)(long)(frameInfo.handler); 86 - DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): calling personality function %p\n", exception_object, p); 87 - _Unwind_Reason_Code personalityResult = (*p)(1, _UA_SEARCH_PHASE, 91 + _Unwind_Reason_Code personalityResult; 92 + 93 + if (((long)p) == 0x432080) 94 + personalityResult = _URC_CONTINUE_UNWIND; 95 + else 96 + { 97 + 98 + DEBUG_PRINT_UNWINDING("unwind_phase1(ex_ojb=%p): calling personality function %p\n", exception_object, p); 99 + personalityResult = (*p)(1, _UA_SEARCH_PHASE, 88 100 exception_object->exception_class, exception_object, 89 101 (struct _Unwind_Context*)(&cursor1)); 102 + } 103 + 90 104 switch ( personalityResult ) { 91 105 case _URC_HANDLER_FOUND: 92 106 // found a catch clause or locals that need destructing in this frame ··· 279 293 DEBUG_PRINT_API("_Unwind_RaiseException(ex_obj=%p)\n", exception_object); 280 294 unw_context_t uc; 281 295 unw_getcontext(&uc); 282 - 296 + #if 0 283 297 void* bt[3]; 284 298 backtrace(bt, 3); 285 299 300 + // rsp = 56 301 + // rbp = 48 286 302 char* ptr = ((char*)&uc) + 128; 287 303 *((long*) ptr) = bt[2]; 304 + 305 + void* origRsp; 306 + void* origRbp; 307 + 308 + ptr = ((char*)&uc) + 56; 309 + 310 + long* stack = (long*) ptr; 311 + while (true) 312 + { 313 + if (*stack == bt[2]) 314 + { 315 + origRbp = *(stack-1); 316 + origRsp = ++stack; 317 + } 318 + ptr++; 319 + stack = (long*) ptr; 320 + } 321 + *((long*) ptr) = 0x7FFFFFFFDAB8LL; 322 + ptr = ((char*)&uc) + 48; 323 + *((long*) ptr) = 0x7fffffffdaf0; 324 + printf("Fixed\n"); 325 + 288 326 //unw_set_reg(&uc, UNW_REG_IP, bt[2]); 327 + #endif 289 328 290 329 // mark that this is a non-forced unwind, so _Unwind_Resume() can do the right thing 291 330 exception_object->private_1 = 0;
+3
src/libmach-o/leb.h
··· 30 30 #define LEB_H 31 31 #include <stdint.h> 32 32 33 + __attribute__ ((visibility ("default"))) 33 34 uint64_t uleb128(const uint8_t*& p); 35 + 36 + __attribute__ ((visibility ("default"))) 34 37 int64_t sleb128(const uint8_t*& p); 35 38 36 39 #endif
+27
src/libncurses/CMakeLists.txt
··· 1 + project(ncurses.5.4.dylib) 2 + 3 + cmake_minimum_required(VERSION 2.4.0) 4 + if(COMMAND cmake_policy) 5 + cmake_policy(SET CMP0003 NEW) 6 + endif(COMMAND cmake_policy) 7 + 8 + enable_language(ASM_NASM) 9 + 10 + #if (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 11 + # message(FATAL_ERROR "Clang is the only supported compiler.") 12 + #endif (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 13 + 14 + #configure_file(config.h.in config.h) 15 + #set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fblocks -std=c++0x") 16 + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c99") 17 + 18 + set(libncurses_SRCS 19 + wrap.c 20 + ) 21 + 22 + add_library(ncurses.5.4.dylib SHARED ${libncurses_SRCS}) 23 + # -luuid to make uuid_ functions available for Darwin apps 24 + target_link_libraries(ncurses.5.4.dylib -lncurses) 25 + 26 + install(TARGETS ncurses.5.4.dylib DESTINATION lib${SUFFIX}) 27 +
+148
src/libncurses/wrap.c
··· 1 + #include <curses.h> 2 + #include <stdlib.h> 3 + #include <stdint.h> 4 + 5 + uint32_t __darwin_acs_map[256]; 6 + 7 + WINDOW* __darwin_initscr(void) 8 + { 9 + WINDOW* win = initscr(); 10 + 11 + for (int i = 0; i < 256; i++) 12 + __darwin_acs_map[i] = acs_map[i]; 13 + 14 + return win; 15 + } 16 + 17 + int __darwin_wborder (WINDOW * w,uint32_t c1,uint32_t c2,uint32_t c3,uint32_t c4,uint32_t c5,uint32_t c6,uint32_t c7,uint32_t c8) 18 + { 19 + return wborder(w,c1,c2,c3,c4,c5,c6,c7,c8); 20 + } 21 + 22 + int __darwin_pechochar (WINDOW * w, const uint32_t c) 23 + { 24 + return pechochar(w, c); 25 + } 26 + 27 + int __darwin_slk_attroff (const uint32_t c) 28 + { 29 + return slk_attroff(c); 30 + } 31 + 32 + int __darwin_slk_attron (const uint32_t c) 33 + { 34 + return slk_attron(c); 35 + } 36 + 37 + int __darwin_slk_attrset (const uint32_t c) 38 + { 39 + return slk_attrset(c); 40 + } 41 + 42 + uint32_t __darwin_termattrs (void) 43 + { 44 + return termattrs(); 45 + } 46 + 47 + int __darwin_vidattr (uint32_t c) 48 + { 49 + return vidattr(c); 50 + } 51 + 52 + int __darwin_vidputs (uint32_t, NCURSES_OUTC); 53 + 54 + int __darwin_waddch (WINDOW *w, const uint32_t c) 55 + { 56 + return waddch(w, c); 57 + } 58 + 59 + int __darwin_waddchnstr (WINDOW * w,const uint32_t * c,int n) 60 + { 61 + chtype* nc = malloc(sizeof(chtype)*n); 62 + for (int i = 0; i < n; i++) 63 + nc[i] = c[i]; 64 + int rv = waddchnstr(w, nc, n); 65 + free(nc); 66 + return rv; 67 + } 68 + 69 + int __darwin_wbkgd (WINDOW * w, uint32_t c) 70 + { 71 + return wbkgd(w, c); 72 + } 73 + 74 + void __darwin_wbkgdset (WINDOW *w,uint32_t c) 75 + { 76 + wbkgdset(w, c); 77 + } 78 + 79 + int __darwin_wechochar (WINDOW *w, const uint32_t c) 80 + { 81 + return wechochar(w, c); 82 + } 83 + 84 + int __darwin_whline (WINDOW *w, uint32_t c, int n) 85 + { 86 + return whline(w, c, n); 87 + } 88 + 89 + uint32_t __darwin_winch (WINDOW *w) 90 + { 91 + return winch(w); 92 + } 93 + 94 + int __darwin_winchnstr (WINDOW *w, uint32_t *c, int n) 95 + { 96 + chtype* nc = malloc(sizeof(chtype)*n); 97 + int rv = winchnstr(w, nc, n); 98 + for (int i = 0; i < n; i++) 99 + c[i] = nc[i]; 100 + free(nc); 101 + return rv; 102 + } 103 + 104 + int __darwin_winsch (WINDOW *w, uint32_t c) 105 + { 106 + return winsch(w, c); 107 + } 108 + 109 + int __darwin_wvline (WINDOW *w,uint32_t c,int n) 110 + { 111 + return wvline(w,c,n); 112 + } 113 + 114 + int __darwin_slk_attroff_sp (SCREEN*, const uint32_t); 115 + int __darwin_slk_attron_sp (SCREEN*, const uint32_t); 116 + int __darwin_slk_attrset_sp (SCREEN*, const uint32_t); 117 + uint32_t __darwin_termattrs_sp (SCREEN*); 118 + int __darwin_vidattr_sp (SCREEN*, uint32_t); 119 + int __darwin_vidputs_sp (SCREEN*, uint32_t, NCURSES_SP_OUTC); 120 + 121 + uint32_t __darwin_slk_attr (void) 122 + { 123 + return slk_attr(); 124 + } 125 + 126 + int __darwin_slk_attr_set (const uint32_t a,short s,void* p) 127 + { 128 + return slk_attr_set(a,s,p); 129 + } 130 + int __darwin_wattr_on (WINDOW *w, uint32_t a, void *p) 131 + { 132 + return wattr_on(w,a,p); 133 + } 134 + 135 + int __darwin_wattr_off (WINDOW *w, uint32_t a, void *p) 136 + { 137 + return wattr_off(w,a,p); 138 + } 139 + 140 + int __darwin_wchgat (WINDOW *w, int i, uint32_t a, short s, const void *p) 141 + { 142 + return wchgat(w, i, a, s, p); 143 + } 144 + 145 + uint32_t __darwin_slk_attr_sp (SCREEN*); 146 + int __darwin_slk_attr_set_sp (SCREEN*, const uint32_t, short, void*); 147 + 148 +
+30
src/util/Bidimap.h
··· 1 + #ifndef BIDIMAP_H 2 + #define BIDIMAP_H 3 + #include <algorithm> 4 + 5 + namespace Darling 6 + { 7 + 8 + template<typename T, size_t N> class Bidimap 9 + { 10 + public: 11 + Bidimap(T aToB[N], T bToA[N]) 12 + : m_aToB(aToB), m_bToA(bToA) 13 + { 14 + std::fill(&aToB[0], &aToB[N], 0); 15 + std::fill(&bToA[0], &bToA[N], 0); 16 + } 17 + void put(T a, T b) 18 + { 19 + m_aToB[a] = b; 20 + m_bToA[b] = a; 21 + } 22 + private: 23 + T *m_aToB, *m_bToA; 24 + }; 25 + 26 + } 27 + 28 + 29 + #endif 30 +
-10
tests/argv.c
··· 1 - #include <stdio.h> 2 - 3 - int main(int argc, char* argv[]) { 4 - printf("argc=%d\n", argc); 5 - printf("argv[0]=%p\n", argv[0]); 6 - printf("argv[0]=%s\n", argv[0]); 7 - printf("argv[1]=%p\n", argv[1]); 8 - printf("argv[1]=%s\n", argv[1]); 9 - return 0; 10 - }
-11
tests/atexit.c
··· 1 - #include <stdio.h> 2 - #include <stdlib.h> 3 - 4 - void f() { 5 - puts("atexit"); 6 - } 7 - 8 - int main() { 9 - atexit(f); 10 - return 0; 11 - }
-11
tests/class.cc
··· 1 - #include <stdio.h> 2 - 3 - class C { 4 - public: 5 - C() {} 6 - }; 7 - 8 - int main() { 9 - C c; 10 - puts("OK"); 11 - }
-22
tests/ctor_dtor.c
··· 1 - #include <stdio.h> 2 - 3 - __attribute__((constructor)) void ctor() { 4 - puts("ctor"); 5 - } 6 - 7 - __attribute__((constructor)) void ctor2() { 8 - puts("ctor2"); 9 - } 10 - 11 - __attribute__((destructor)) void dtor() { 12 - puts("dtor"); 13 - } 14 - 15 - __attribute__((destructor)) void dtor2() { 16 - puts("dtor2"); 17 - } 18 - 19 - int main() { 20 - puts("main"); 21 - return 0; 22 - }
-22
tests/dirent.c
··· 1 - #include <dirent.h> 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - #include <string.h> 5 - #include <sys/types.h> 6 - 7 - int main() { 8 - DIR* dir = opendir("/tmp"); 9 - if (!dir) 10 - abort(); 11 - int found = 0; 12 - struct dirent* ent; 13 - while ((ent = readdir(dir)) != NULL) { 14 - printf("%s\n", ent->d_name); 15 - if (!strcmp(ent->d_name, ".")) 16 - found = 1; 17 - } 18 - closedir(dir); 19 - if (!found) 20 - abort(); 21 - return 0; 22 - }
-69
tests/dylib/dlfcn.c
··· 1 - #include <dlfcn.h> 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - 5 - int main() { 6 - const char* err; 7 - 8 - #ifdef __APPLE__ 9 - void* h = dlopen("mach/dylib/lib.dylib", RTLD_NOW); 10 - #else 11 - void* h = dlopen("mach/dylib/lib.so", RTLD_NOW); 12 - #endif 13 - if (!h) { 14 - fprintf(stderr, "dlopen failed: %s\n", dlerror()); 15 - abort(); 16 - } 17 - 18 - if ((err = dlerror())) { 19 - fprintf(stderr, "dlopen failed (dlerror): %s\n", err); 20 - abort(); 21 - } 22 - 23 - int (*hello)(const char*) = (int(*)(const char*))dlsym(h, "hello"); 24 - if (!hello) { 25 - fprintf(stderr, "dlsym failed: %s\n", dlerror()); 26 - abort(); 27 - } 28 - 29 - if ((err = dlerror())) { 30 - fprintf(stderr, "dlsym failed (dlerror): %s\n", err); 31 - abort(); 32 - } 33 - 34 - if (hello("world") != 42) { 35 - fprintf(stderr, "hello failed\n"); 36 - abort(); 37 - } 38 - 39 - int (*hell)(const char*) = (int(*)(const char*))dlsym(h, "hell"); 40 - if (hell) { 41 - fprintf(stderr, "dlsym unexcepctedly succeeded: %s\n", dlerror()); 42 - abort(); 43 - } 44 - 45 - if (!(err = dlerror())) { 46 - fprintf(stderr, "dlsym unexcepctedly succeeded (dlerror)\n"); 47 - abort(); 48 - } 49 - 50 - printf("The error message for failing dlsym: %s\n", err); 51 - 52 - if (dlerror()) { 53 - fprintf(stderr, "dlerror has still been set\n"); 54 - abort(); 55 - } 56 - 57 - int* check_value = (int*)dlsym(h, "check_value"); 58 - if (!check_value) { 59 - fprintf(stderr, "dlsym failed: %s\n", dlerror()); 60 - abort(); 61 - } 62 - 63 - if (*check_value != 999) { 64 - fprintf(stderr, "initializer function didn't run?\n"); 65 - abort(); 66 - } 67 - 68 - return 0; 69 - }
-12
tests/dylib/lib.c
··· 1 - #include <stdio.h> 2 - 3 - int check_value; 4 - 5 - __attribute__((constructor)) static void init() { 6 - check_value = 999; 7 - } 8 - 9 - int hello(const char* arg) { 10 - printf("Hello, %s!\n", arg); 11 - return 42; 12 - }
-3
tests/dylib/lib.h
··· 1 - extern int check_value; 2 - 3 - int hello(const char* arg);
-9
tests/dylib/main.c
··· 1 - #include "lib.h" 2 - 3 - #include <stdlib.h> 4 - 5 - int main() { 6 - if (hello("world") != 42) 7 - abort(); 8 - return 0; 9 - }
-8
tests/dylib/weak.h
··· 1 - template <class T> 2 - class C { 3 - public: 4 - static int weak; 5 - }; 6 - 7 - template <class T> 8 - int C<T>::weak = 0;
-9
tests/dylib/weak_lib.cc
··· 1 - #include <stdio.h> 2 - 3 - #include "weak.h" 4 - 5 - __attribute__((constructor)) void init_weak() { 6 - printf("init_weak before: %d %p\n", C<int>::weak, &C<int>::weak); 7 - C<int>::weak = 42; 8 - printf("init_weak after: %d %p\n", C<int>::weak, &C<int>::weak); 9 - }
-24
tests/dylib/weak_main.cc
··· 1 - #include <dlfcn.h> 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - 5 - #include "weak.h" 6 - 7 - int main() { 8 - #ifdef DL 9 - int dlflags = RTLD_NOW; 10 - # ifdef __APPLE__ 11 - void* h = dlopen("mach/dylib/weak_lib.dylib", dlflags); 12 - # else 13 - void* h = dlopen("mach/dylib/weak_lib.so", dlflags); 14 - # endif 15 - if (!h) { 16 - printf("%s\n", dlerror()); 17 - abort(); 18 - } 19 - #endif 20 - printf("%d %p\n", C<int>::weak, &C<int>::weak); 21 - if (C<int>::weak != 42) { 22 - abort(); 23 - } 24 - }
-5
tests/fflush_null.c
··· 1 - #include <stdio.h> 2 - 3 - int main() { 4 - return fflush(NULL); 5 - }
-6
tests/getenv.c
··· 1 - #include <stdio.h> 2 - #include <stdlib.h> 3 - int main() { 4 - printf("%s\n", getenv("HOME")); 5 - return 0; 6 - }
-22
tests/getrusage.c
··· 1 - #include <stdio.h> 2 - #include <sys/resource.h> 3 - #include <sys/time.h> 4 - 5 - int main() { 6 - struct rusage ru; 7 - int r = getrusage(RUSAGE_SELF, &ru); 8 - printf("ret=%d\n", r); 9 - printf("utime=%d.%d stime=%d.%d\n" 10 - "maxrss=%ld ixrss=%ld idrss=%ld isrss=%ld\n" 11 - "minflt=%ld majflt=%ld nswap=%ld\n" 12 - "inblock=%ld oublock=%ld msgsnd=%ld msgrcv=%ld\n" 13 - "nsignals=%ld nvcsw=%ld nivcsw=%ld\n" 14 - , 15 - (int)ru.ru_utime.tv_sec, (int)ru.ru_utime.tv_usec, 16 - (int)ru.ru_stime.tv_sec, (int)ru.ru_stime.tv_usec, 17 - ru.ru_maxrss, ru.ru_ixrss, ru.ru_idrss, ru.ru_isrss, 18 - ru.ru_minflt, ru.ru_majflt, ru.ru_nswap, 19 - ru.ru_inblock, ru.ru_oublock, ru.ru_msgsnd, ru.ru_msgrcv, 20 - ru.ru_nsignals, ru.ru_nvcsw, ru.ru_nivcsw); 21 - return 0; 22 - }
-10
tests/gettimeofday.c
··· 1 - #include <stdio.h> 2 - #include <sys/time.h> 3 - 4 - int main() { 5 - struct timeval tv; 6 - int r = gettimeofday(&tv, NULL); 7 - printf("%d %d\n", tv.tv_sec, tv.tv_usec); 8 - return 0; 9 - } 10 -
-9
tests/hello.c
··· 1 - #include <stdio.h> 2 - int main() { 3 - #ifdef __x86_64__ 4 - printf("Hello, 64bit world!\n"); 5 - #else 6 - printf("Hello, 32bit world!\n"); 7 - #endif 8 - return 0; 9 - }
-5
tests/hello_cpp.cc
··· 1 - #include <iostream> 2 - 3 - int main() { 4 - std::cout << "Hello, world!" << std::endl; 5 - }
-19
tests/mycat.c
··· 1 - #include <stdio.h> 2 - 3 - int main(int argc, char* argv[]) { 4 - if (argc < 2) { 5 - fprintf(stderr, "need file name\n"); 6 - return 0; 7 - } 8 - 9 - FILE* fp = fopen(argv[1], "rb"); 10 - char buf[4096]; 11 - size_t len; 12 - while (1) { 13 - len = fread(buf, 1, 4096, fp); 14 - fwrite(buf, 1, len, stdout); 15 - if (len != 4096) break; 16 - } 17 - fclose(fp); 18 - return 0; 19 - }
-10
tests/nsgetexecpath.c
··· 1 - #include <mach-o/dyld.h> 2 - #include <stdio.h> 3 - 4 - int main() { 5 - char buf[4096]; 6 - unsigned int size = 4095; 7 - int r = _NSGetExecutablePath(buf, &size); 8 - printf("r=%d %s\n", r, buf); 9 - return 0; 10 - }
-4
tests/printf.c
··· 1 - int main(int argc) { 2 - printf("%d\n", argc); 3 - return 0; 4 - }
-38
tests/pthread.c
··· 1 - #define _GNU_SOURCE 2 - #include <pthread.h> 3 - #include <stdio.h> 4 - #include <stdlib.h> 5 - 6 - pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 7 - 8 - int main() { 9 - { 10 - pthread_mutexattr_t attr; 11 - if (pthread_mutexattr_init(&attr) != 0) { 12 - abort(); 13 - } 14 - if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL) != 0) { 15 - abort(); 16 - } 17 - if (pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE) != 0) { 18 - abort(); 19 - } 20 - } 21 - 22 - { 23 - pthread_rwlockattr_t attr; 24 - if (pthread_rwlockattr_init(&attr) != 0) { 25 - abort(); 26 - } 27 - if (pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE) != 0) { 28 - abort(); 29 - } 30 - } 31 - 32 - // TODO(hamaji): PTHREAD_MUTEX_INITIALIZER has a different implementation... 33 - #if 0 34 - if (pthread_mutex_lock(&g_mutex) != 0) { 35 - abort(); 36 - } 37 - #endif 38 - }
-12
tests/putc.c
··· 1 - // It's very unfortunate that apple's putc_unlocked is a macro and depends on 2 - // the layout of FILE. 3 - #include <stdio.h> 4 - 5 - int main() { 6 - putc_unlocked('h', stdout); 7 - putc_unlocked('o', stdout); 8 - putc_unlocked('g', stdout); 9 - putc_unlocked('e', stdout); 10 - putc_unlocked('\n', stdout); 11 - return 0; 12 - }
+55
tests/runtest.sh
··· 1 + #!/bin/sh 2 + 3 + BUILDSERVER="osx" 4 + 5 + runtest() { 6 + source="$1" 7 + source_fn=$(echo "$source" | sed 's/\//_/g') 8 + 9 + set -e 10 + 11 + echo "=====" 12 + echo "Running test '$source'" 13 + echo "=====" 14 + 15 + cflags="$(grep '// CFLAGS' "$source" || true)" 16 + cflags="-w $(echo "$cflags" | cut -b 12-)" 17 + 18 + echo "Copying the source code to Darwin..." 19 + scp "$source" "$BUILDSERVER:/tmp/$$.$source_fn" >/dev/null 20 + echo "Building the source code for Darwin..." 21 + ssh "$BUILDSERVER" "g++ $cflags '/tmp/$$.$source_fn' -o '/tmp/$$.$source_fn.bin'" 22 + echo "Copying the binary over..." 23 + scp "$BUILDSERVER:/tmp/$$.$source_fn.bin" "/tmp" >/dev/null 24 + ssh "$BUILDSERVER" "rm -f /tmp/$$.$source_fn*" 25 + 26 + echo "Running Darwin binary..." 27 + out_darwin=$(dyld "/tmp/$$.$source_fn.bin") 28 + rm -f "/tmp/$$.$source_fn.bin" 29 + 30 + echo "Compiling native..." 31 + g++ $cflags "$source" -o "/tmp/$$.$source_fn.bin" 32 + echo "Running native binary..." 33 + out_native=$("/tmp/$$.$source_fn.bin") 34 + 35 + if [ "$out_darwin" != "$out_native" ]; then 36 + echo "*** ERROR: Output doesn't match!" 37 + echo "---" 38 + echo "Darwin build:" 39 + echo "---" 40 + echo "$out_darwin" 41 + echo "---" 42 + echo "Native build:" 43 + echo "---" 44 + echo "$out_native" 45 + exit 1 46 + fi 47 + rm -f "/tmp/$$.$source_fn.bin" 48 + 49 + echo "Everything OK, outputs match" 50 + } 51 + 52 + for test in "$@"; do 53 + runtest "$test" 54 + done 55 +
-9
tests/setlocale.c
··· 1 - #include <locale.h> 2 - #include <stdio.h> 3 - 4 - int main() { 5 - char* p = setlocale(2, ""); 6 - printf("%p\n", p); 7 - printf("%s\n", p); 8 - return 0; 9 - }
+75
tests/src/fork_wait.c
··· 1 + #include <unistd.h> 2 + #include <signal.h> 3 + #include <stdlib.h> 4 + #include <stdio.h> 5 + #include <string.h> 6 + #include <sys/wait.h> 7 + 8 + static void handler(int); 9 + void test(int handleIt); 10 + 11 + int main() 12 + { 13 + printf("First pass...\n"); 14 + test(1); 15 + printf("Second pass...\n"); 16 + test(0); 17 + 18 + return 0; 19 + } 20 + 21 + void test(int handleIt) 22 + { 23 + pid_t child = fork(); 24 + if (child) 25 + { 26 + sleep(1); 27 + kill(child, SIGSYS); 28 + 29 + int status; 30 + pid_t p = wait(&status); 31 + 32 + if (WIFSIGNALED(status) == handleIt) 33 + { 34 + printf("WIFSIGNALED...\n"); 35 + exit(1); 36 + } 37 + if (!WIFEXITED(status) == handleIt) 38 + { 39 + printf("!WIFEXITED...\n"); 40 + exit(1); 41 + } 42 + } 43 + else 44 + { 45 + signal(SIGSYS, handler); 46 + 47 + if (!handleIt) 48 + { 49 + struct sigaction act; 50 + 51 + memset(&act, 0, sizeof(act)); 52 + act.sa_handler = SIG_DFL; 53 + sigaction(SIGSYS, &act, NULL); 54 + } 55 + 56 + 57 + sleep(10); 58 + exit(1); 59 + } 60 + } 61 + 62 + static void handler(int sig) 63 + { 64 + if (sig != SIGSYS) 65 + { 66 + printf("Bad signal code: %d\n", sig); 67 + exit(1); 68 + } 69 + else 70 + { 71 + printf("Handler!\n"); 72 + exit(0); 73 + } 74 + } 75 +
+26
tests/src/pthread_threads.c
··· 1 + // CFLAGS: -lpthread 2 + #include <pthread.h> 3 + #include <stdio.h> 4 + #include <unistd.h> 5 + 6 + void* mythread(void*); 7 + 8 + int main() 9 + { 10 + pthread_t th, th2; 11 + void* rv; 12 + pthread_create(&th, 0, mythread, 0); 13 + sleep(1); 14 + pthread_create(&th2, 0, mythread, 0); 15 + printf("Waiting for thread...\n"); 16 + pthread_join(th, &rv); 17 + pthread_join(th2, &rv); 18 + printf("Thread joined!\n"); 19 + return 0; 20 + } 21 + 22 + void* mythread(void* p) 23 + { 24 + sleep(2); 25 + } 26 +
+18
tests/src/selfexec.c
··· 1 + #include <unistd.h> 2 + #include <stdio.h> 3 + 4 + int main(int argc, char** argv) 5 + { 6 + if (argc == 1) 7 + { 8 + execl(argv[0], argv[0], "Hello world", 0); 9 + return 1; 10 + } 11 + else 12 + { 13 + puts(argv[1]); 14 + return 0; 15 + } 16 + } 17 + 18 +
-12
tests/stack.c
··· 1 - #include <stdio.h> 2 - 3 - int fib(int n) { 4 - if (n < 2) return 1; 5 - return fib(n-1) + fib(n-2); 6 - } 7 - 8 - int main() { 9 - printf("%d\n", fib(20)); 10 - return 0; 11 - } 12 -
-12
tests/stat.c
··· 1 - #include <fcntl.h> 2 - #include <stdio.h> 3 - #include <sys/stat.h> 4 - 5 - int main(int argc, char* argv[]) { 6 - struct stat buf; 7 - int fd = open(argv[0], O_RDONLY); 8 - int ret = fstat(fd, &buf); 9 - printf("ret=%d size=%d size_offset=%ld\n", 10 - ret, buf.st_size, (char*)&buf.st_size - (char*)&buf); 11 - return 0; 12 - }
-11
tests/stat_type.c
··· 1 - #include <fcntl.h> 2 - #include <stdio.h> 3 - #include <sys/stat.h> 4 - 5 - int main(int argc, char* argv[]) { 6 - struct stat buf; 7 - int ret = stat("/tmp", &buf); 8 - if (!S_ISDIR(buf.st_mode)) 9 - abort(); 10 - return 0; 11 - }
-6
tests/stderr.c
··· 1 - #include <stdio.h> 2 - 3 - int main() { 4 - fprintf(stderr, "Hello, world!\n"); 5 - return 0; 6 - }
-12
tests/strcmp.c
··· 1 - #include <string.h> 2 - 3 - int main(int argc, char* argv[]) { 4 - puts("run"); 5 - if (strcmp(argv[argc-1], "a.out")) { 6 - puts("yes"); 7 - } else { 8 - puts("no"); 9 - } 10 - puts("done"); 11 - return 0; 12 - }
-17
tests/uname.c
··· 1 - #include <stddef.h> 2 - #include <stdio.h> 3 - #include <stdlib.h> 4 - #include <sys/utsname.h> 5 - 6 - int main(int argc, char* argv[]) { 7 - struct utsname buf; 8 - if (uname(&buf) != 0) 9 - abort(); 10 - printf("sysname=%s\nnodename=%s\nrelease=%s\nversion=%s\nmachine=%s\n", 11 - buf.sysname, buf.nodename, buf.release, buf.version, buf.machine); 12 - printf("sysname=%lu\nnodename=%lu\nrelease=%lu\nversion=%lu\nmachine=%lu\n", 13 - offsetof(struct utsname, sysname), offsetof(struct utsname, nodename), 14 - offsetof(struct utsname, release), offsetof(struct utsname, version), 15 - offsetof(struct utsname, machine)); 16 - return 0; 17 - }
-117
tools/runtests.sh
··· 1 - #!/bin/sh 2 - # 3 - # Copyright 2011 Shinichiro Hamaji. All rights reserved. 4 - # 5 - # Redistribution and use in source and binary forms, with or without 6 - # modification, are permitted provided that the following conditions 7 - # are met: 8 - # 9 - # 1. Redistributions of source code must retain the above copyright 10 - # notice, this list of conditions and the following disclaimer. 11 - # 12 - # 2. Redistributions in binary form must reproduce the above 13 - # copyright notice, this list of conditions and the following 14 - # disclaimer in the documentation and/or other materials 15 - # provided with the distribution. 16 - # 17 - # THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 18 - # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 - # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 - # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 21 - # CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 - # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 - # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 24 - # USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 25 - # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 - # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 27 - # OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 - # SUCH DAMAGE. 29 - 30 - set -e 31 - 32 - # Run small unit tests 33 - 34 - for i in mach/*.bin; do 35 - echo "Running $i" 36 - ./ld-mac ./$i 37 - done 38 - 39 - # Run regressions tests with real compilers 40 - 41 - MAC_TOOL_DIR=/usr/i686-apple-darwin10 42 - MAC_BIN_DIR=$MAC_TOOL_DIR/usr/bin 43 - 44 - apple() { 45 - gcc="$1" 46 - shift 47 - PATH=$MAC_BIN_DIR ./ld-mac $MAC_BIN_DIR/$gcc --sysroot=$MAC_TOOL_DIR "$@" 48 - } 49 - 50 - # Run GCC with ld-mac 51 - 52 - echo "Running gcc -c mach/hello.c" 53 - ./ld-mac $MAC_BIN_DIR/gcc -c mach/hello.c 54 - echo "Running gcc mach/hello.c" 55 - ./ld-mac $MAC_BIN_DIR/gcc mach/hello.c 56 - echo "Running gcc -g mach/hello.c" 57 - PATH=$MAC_BIN_DIR ./ld-mac $MAC_BIN_DIR/gcc -g mach/hello.c 58 - 59 - # Run clang with ld-mac 60 - 61 - echo "Running clang -c mach/hello.c" 62 - ./ld-mac $MAC_BIN_DIR/clang -c mach/hello.c 63 - 64 - # Check dylib 65 - 66 - echo "Running dylib tests" 67 - 68 - apple gcc -g -dynamiclib mach/dylib/lib.c -o mach/dylib/lib.dylib 69 - apple gcc -g mach/dylib/main.c mach/dylib/lib.dylib -o mach/dylib/main 70 - 71 - echo "Running mach/dylib/main" 72 - ./ld-mac mach/dylib/main 73 - 74 - echo "Running dylib tests" 75 - 76 - apple gcc -g -dynamiclib mach/dylib/lib.c -o mach/dylib/lib.dylib 77 - apple gcc -g mach/dylib/main.c mach/dylib/lib.dylib -o mach/dylib/main 78 - 79 - echo "Running mach/dylib/main" 80 - ./ld-mac mach/dylib/main 81 - 82 - apple gcc -g mach/dylib/dlfcn.c -o mach/dylib/dlfcn 83 - 84 - echo "Running mach/dylib/dlfcn" 85 - ./ld-mac mach/dylib/dlfcn 86 - 87 - # Check dylib with weak symbols 88 - 89 - echo "Running dylib tests with a weak symbol" 90 - 91 - apple g++ -g -fPIC -dynamiclib mach/dylib/weak_lib.cc -o mach/dylib/weak_lib.dylib 92 - apple g++ -g -fPIC mach/dylib/weak_main.cc -o mach/dylib/weak_main mach/dylib/weak_lib.dylib 93 - apple g++ -g -fPIC mach/dylib/weak_main.cc -o mach/dylib/weak_main-dl -DDL 94 - 95 - echo "Running mach/dylib/weak_main" 96 - ./ld-mac mach/dylib/weak_main 97 - 98 - echo "Running mach/dylib/weak_main-dl" 99 - ./ld-mac mach/dylib/weak_main-dl 100 - 101 - # Compile and run unit tests with clang 102 - 103 - # Need this file from Xcode 4 104 - CLANG=$MAC_BIN_DIR/clang-137 105 - if [ -x $CLANG ]; then 106 - for i in mach/*.c; do 107 - echo "Compiling $i with clang" 108 - ./ld-mac $CLANG -Wl,-syslibroot,$MAC_TOOL_DIR -isysroot $MAC_TOOL_DIR $i -o $i.clang.bin 109 - echo "Running $i.clang.bin" 110 - ./ld-mac $i.clang.bin 111 - done 112 - else 113 - echo "$CLANG not found, skipping some tests with it" 114 - fi 115 - 116 - echo 117 - echo '*** ALL TESTS PASS ***'
+1 -1
tools/valueof.sh
··· 18 18 19 19 END 20 20 21 - gcc -w $cfile -o $cfile.bin 21 + gcc -w $3 $cfile -o $cfile.bin 22 22 $cfile.bin 23 23 24 24 rm $cfile*