this repo has no description
1
fork

Configure Feed

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

* CoreServices FileManager and DateTimeUtils work * Split out Cocoa vars from libobjcdarwin * Resolve binds in correct order * Fix name translation use in dlsym() * libc file attrlist dummy functions (cannot be supported)

+928 -135
+2 -2
CMakeLists.txt
··· 49 49 src/util/trace.cpp 50 50 src/util/stlutils.cpp 51 51 src/util/IniConfig.cpp 52 + src/util/leb.cpp 52 53 ) 53 54 54 55 add_library(util ${util-SRCS}) ··· 59 60 src/libmach-o/FatMachO.cpp 60 61 src/libmach-o/RebaseState.cpp 61 62 src/libmach-o/BindState.cpp 62 - src/libmach-o/leb.cpp 63 63 src/libmach-o/MachOImpl.cpp 64 64 ) 65 65 ··· 116 116 117 117 add_subdirectory(tests) 118 118 add_subdirectory(src/libSystem) 119 - #add_subdirectory(src/libcxxdarwin) 119 + add_subdirectory(src/Cocoa) 120 120 add_subdirectory(src/libobjcdarwin) 121 121 #add_subdirectory(src/libunwind-darwin-gcc) 122 122 add_subdirectory(src/libncurses)
+3
etc/dylib.conf
··· 6 6 /usr/lib/libz.1.dylib=libz.so.1 7 7 /usr/lib/libstdc++.6.dylib=libSystem.B.dylib.so 8 8 /usr/lib/libcrypto.0.9.8.dylib=libcrypto.so 9 + /usr/lib/libgcc_s.1.dylib=libgcc_s.so 10 + /usr/lib/libbz2.1.0.dylib=libbz2.so.1 9 11 #libncurses.5.4.dylib=libncurses.so.5 10 12 #/System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation=libCoreFoundation.so 11 13 /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation=libgnustep-corebase.so ··· 14 16 /System/Library/Frameworks/AppKit.framework/Versions/C/AppKit=libAppKit.so 15 17 /System/Library/Frameworks/Cocoa.framework/Versions/A/Cocoa=libCocoa.so 16 18 /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit=libIOKit.so 19 + /System/Library/Frameworks/Carbon.framework/Versions/A/Carbon=libCarbon.so 17 20 /System/Library/Frameworks/Security.framework/Versions/A/Security=libCoreSecurity.so 18 21 /System/Library/Frameworks/ApplicationServices.framework/Versions/A/ApplicationServices=/dev/null 19 22
+13
src/Cocoa/CMakeLists.txt
··· 1 + project(Cocoa) 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 + 9 + add_library(Cocoa SHARED zero.c) 10 + target_link_libraries(Cocoa -lgnustep-gui -lopal crashhandler) 11 + 12 + install(TARGETS Cocoa DESTINATION "lib${SUFFIX}/darling") 13 +
+7
src/Cocoa/visibility.h
··· 1 + #ifndef VISIBILITY_H 2 + #define VISIBILITY_H 3 + 4 + #define DARLING_VISIBLE __attribute__((visibility("default"))) 5 + 6 + #endif 7 +
+3 -1
src/CoreServices/CMakeLists.txt
··· 10 10 #endif (NOT "${CMAKE_CXX_COMPILER} ${CMAKE_CXX_COMPILER_ARG1}" MATCHES ".*clang") 11 11 12 12 #configure_file(config.h.in config.h) 13 - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x") 13 + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 14 14 #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fblocks") 15 15 16 16 include_directories(${CMAKE_CURRENT_SOURCE_DIR}) ··· 21 21 MacLocales.cpp 22 22 UnicodeUtilities.cpp 23 23 Gestalt.cpp 24 + FileManager.cpp 25 + DateTimeUtils.cpp 24 26 ) 25 27 26 28 add_library(CoreServices SHARED ${CoreServices_SRCS})
+80
src/CoreServices/DateTimeUtils.cpp
··· 1 + #include "DateTimeUtils.h" 2 + #include <climits> 3 + 4 + UTCDateTime time_tToUTC(time_t t) 5 + { 6 + UTCDateTime rv; 7 + uint64_t time = t + UNIX_OFFSET; 8 + 9 + rv.fraction = 0; 10 + rv.lowSeconds = time & 0xffffffff; 11 + rv.highSeconds = time >> 32; 12 + 13 + return rv; 14 + } 15 + 16 + OSErr UCConvertUTCDateTimeToCFAbsoluteTime(const UTCDateTime* in, CFAbsoluteTime* out) 17 + { 18 + uint64_t seconds = in->lowSeconds; 19 + seconds |= uint64_t(in->highSeconds) << 32; 20 + *out = seconds - CF_OFFSET; 21 + *out += (1.0/65535) * in->fraction; 22 + return noErr; 23 + } 24 + 25 + OSErr UCConvertSecondsToCFAbsoluteTime(uint32_t seconds, CFAbsoluteTime* out) 26 + { 27 + *out = seconds; 28 + return noErr; 29 + } 30 + 31 + OSErr UCConvertLongDateTimeToCFAbsoluteTime(int64_t seconds, CFAbsoluteTime* out) 32 + { 33 + *out = seconds; 34 + return noErr; 35 + } 36 + 37 + OSErr UCConvertCFAbsoluteTimeToUTCDateTime(CFAbsoluteTime in, UTCDateTime* out) 38 + { 39 + in += CF_OFFSET; 40 + 41 + if (in > 2.0e48) 42 + return paramErr; 43 + 44 + uint64_t seconds = uint64_t(in); 45 + 46 + out->lowSeconds = seconds & 0xffffffff; 47 + out->highSeconds = seconds >> 32; 48 + out->fraction = uint16_t((in-seconds) * 65535); 49 + 50 + return noErr; 51 + } 52 + 53 + OSErr UCConvertCFAbsoluteTimeToSeconds(CFAbsoluteTime in, uint32_t* out) 54 + { 55 + if (in <= UINT_MAX) 56 + { 57 + *out = uint32_t(in); 58 + return noErr; 59 + } 60 + else 61 + { 62 + *out = 0; 63 + return paramErr; 64 + } 65 + } 66 + 67 + OSErr UCConvertCFAbsoluteTimeToLongDateTime(CFAbsoluteTime in, int64_t* out) 68 + { 69 + if (in <= LLONG_MAX) 70 + { 71 + *out = int64_t(in); 72 + return noErr; 73 + } 74 + else 75 + { 76 + *out = 0; 77 + return paramErr; 78 + } 79 + } 80 +
+43
src/CoreServices/DateTimeUtils.h
··· 1 + #ifndef UTCUTILS_H 2 + #define UTCUTILS_H 3 + #include <stdint.h> 4 + #include <ctime> 5 + #include <CoreFoundation/CFDate.h> 6 + #include "MacErrors.h" 7 + 8 + #define UNIX_OFFSET 2082844800ll // 1970 - 1904 9 + #define CF_OFFSET 3061152000ll // 2001 - 1904: "Seconds" is since 2001+ 10 + 11 + #pragma pack(2) 12 + struct UTCDateTime 13 + { 14 + uint16_t highSeconds; 15 + uint32_t lowSeconds; 16 + uint16_t fraction; 17 + }; 18 + #pragma pack() 19 + 20 + typedef UTCDateTime LocalDateTime; 21 + typedef UTCDateTime* UTCDateTimePtr; 22 + typedef UTCDateTime** UTCDateTimeHandle; 23 + typedef LocalDateTime* LocalDateTimePtr; 24 + typedef LocalDateTime** LocalDateTimeHandle; 25 + 26 + extern "C" { 27 + 28 + OSErr UCConvertUTCDateTimeToCFAbsoluteTime(const UTCDateTime* in, CFAbsoluteTime* out); 29 + OSErr UCConvertSecondsToCFAbsoluteTime(uint32_t seconds, CFAbsoluteTime* out); 30 + OSErr UCConvertLongDateTimeToCFAbsoluteTime(int64_t seconds, CFAbsoluteTime* out); 31 + OSErr UCConvertCFAbsoluteTimeToUTCDateTime(CFAbsoluteTime in, UTCDateTime* out); 32 + OSErr UCConvertCFAbsoluteTimeToSeconds(CFAbsoluteTime in, uint32_t* out); 33 + OSErr UCConvertCFAbsoluteTimeToLongDateTime(CFAbsoluteTime in, int64_t* out); 34 + 35 + } 36 + 37 + namespace Darling 38 + { 39 + UTCDateTime time_tToUTC(time_t t); 40 + } 41 + 42 + #endif 43 +
+315
src/CoreServices/FileManager.cpp
··· 1 + #include "FileManager.h" 2 + #include <cstdlib> 3 + #include <string> 4 + #include <cstring> 5 + #include <sys/stat.h> 6 + #include <sys/types.h> 7 + #include <unistd.h> 8 + #include <algorithm> 9 + #include <memory> 10 + #include <errno.h> 11 + #include <iconv.h> 12 + #include <alloca.h> 13 + #include <libgen.h> 14 + #include "DateTimeUtils.h" 15 + #include "../util/stlutils.h" 16 + 17 + // Doesn't resolve the last symlink 18 + // Mallocates a new buffer 19 + static char* realpath_ns(const char* path); 20 + static bool FSRefMakePath(const FSRef* ref, std::string& out); 21 + // Is the current user member of the specified group? 22 + static bool hasgid(gid_t gid); 23 + 24 + OSStatus FSPathMakeRef(const uint8_t* path, FSRef* fsref, Boolean* isDirectory) 25 + { 26 + return FSPathMakeRefWithOptions(path, kFSPathMakeRefDoNotFollowLeafSymlink, fsref, isDirectory); 27 + } 28 + 29 + OSStatus FSPathMakeRefWithOptions(const uint8_t* path, long options, FSRef* fsref, Boolean* isDirectory) 30 + { 31 + if (!path || !fsref) 32 + return paramErr; 33 + 34 + std::string fullPath; 35 + char* rpath; 36 + 37 + if (options & kFSPathMakeRefDoNotFollowLeafSymlink) 38 + rpath = realpath_ns(reinterpret_cast<const char*>(path)); 39 + else 40 + rpath = realpath(reinterpret_cast<const char*>(path), nullptr); 41 + 42 + if (!rpath) 43 + return fnfErr; 44 + if (std::count(rpath, rpath+strlen(rpath), '/') > FSRef_MAX_DEPTH) 45 + { 46 + free(rpath); 47 + return unimpErr; 48 + } 49 + 50 + fullPath = rpath; 51 + free(rpath); 52 + 53 + memset(fsref, 0, sizeof(*fsref)); 54 + 55 + if (fullPath == "/") 56 + { 57 + if (isDirectory) 58 + *isDirectory = true; 59 + return noErr; 60 + } 61 + 62 + size_t pos = 1; 63 + struct stat st; 64 + int componentPos = 0; 65 + do 66 + { 67 + std::string component; 68 + 69 + pos = fullPath.find('/', pos); 70 + component = fullPath.substr(0, pos); 71 + 72 + if (::lstat(component.c_str(), &st) == -1) 73 + return makeOSStatus(errno); 74 + 75 + fsref->inodes[componentPos++] = st.st_ino; 76 + } 77 + while (pos != std::string::npos); 78 + 79 + if (isDirectory) 80 + *isDirectory = S_ISDIR(st.st_mode); 81 + 82 + return noErr; 83 + } 84 + 85 + char* realpath_ns(const char* path) 86 + { 87 + char *dup1, *dup2; 88 + char *dname, *bname; 89 + char *real, *complete; 90 + 91 + dup1 = strdup(path); 92 + dup2 = strdup(path); 93 + dname = dirname(dup1); 94 + bname = basename(dup2); 95 + 96 + real = realpath(dname, nullptr); 97 + complete = (char*) malloc(strlen(real) + strlen(bname) + 2); 98 + 99 + strcpy(complete, real); 100 + strcat(complete, "/"); 101 + strcat(complete, bname); 102 + 103 + free(real); 104 + free(dup1); 105 + free(dup2); 106 + 107 + return complete; 108 + } 109 + 110 + bool FSRefMakePath(const FSRef* fsref, std::string& out) 111 + { 112 + out = '/'; 113 + for (int i = 0; i < FSRef_MAX_DEPTH && fsref->inodes[i] != 0; i++) 114 + { 115 + ino_t inode = fsref->inodes[i]; 116 + DIR* dir = opendir(out.c_str()); 117 + struct dirent* ent; 118 + bool found = false; 119 + 120 + while ((ent = readdir(dir))) 121 + { 122 + if (ent->d_ino == inode) 123 + { 124 + found = true; 125 + if (!string_endsWith(out, "/")) 126 + out += '/'; 127 + out += ent->d_name; 128 + } 129 + } 130 + 131 + closedir(dir); 132 + 133 + if (!found) 134 + return false; 135 + } 136 + return true; 137 + } 138 + 139 + OSStatus FSRefMakePath(const FSRef* fsref, uint8_t* path, uint32_t maxSize) 140 + { 141 + std::string rpath; 142 + 143 + if (!fsref || !path || !maxSize) 144 + return paramErr; 145 + 146 + if (!FSRefMakePath(fsref, rpath)) 147 + return fnfErr; 148 + 149 + strncpy((char*) path, rpath.c_str(), maxSize); 150 + path[maxSize-1] = 0; 151 + 152 + return noErr; 153 + } 154 + 155 + OSStatus FSGetCatalogInfo(const FSRef* ref, uint32_t infoBits, FSCatalogInfo* infoOut, HFSUniStr255* nameOut, FSSpecPtr fsspec, FSRef* parentDir) 156 + { 157 + std::string path; 158 + 159 + if (!FSRefMakePath(ref, path)) 160 + return fnfErr; 161 + 162 + if (nameOut) 163 + { 164 + iconv_t ic = iconv_open("UTF-16", "UTF-8"); 165 + size_t s; 166 + const char* inbuf = path.c_str(); 167 + char* outbuf = reinterpret_cast<char*>(nameOut->unicode); 168 + size_t inbytesleft = path.size(), outbytesleft = sizeof(nameOut->unicode); 169 + 170 + if (ic == iconv_t(-1)) 171 + return -1; 172 + 173 + memset(nameOut->unicode, 0, outbytesleft); 174 + s = iconv(ic, (char**) &inbuf, &inbytesleft, &outbuf, &outbytesleft); 175 + 176 + iconv_close(ic); 177 + if (s == size_t(-1)) 178 + return -1; 179 + } 180 + 181 + if (parentDir) 182 + { 183 + memcpy(parentDir, ref, sizeof(FSRef)); 184 + ino_t* last = std::find(parentDir->inodes, parentDir->inodes+FSRef_MAX_DEPTH, 0); 185 + 186 + if (last != parentDir->inodes) 187 + *(last-1) = 0; 188 + } 189 + 190 + if (infoOut && infoBits != kFSCatInfoNone) 191 + { 192 + struct stat st; 193 + 194 + memset(infoOut, 0, sizeof(*infoOut)); 195 + 196 + if (::stat(path.c_str(), &st) != 0) 197 + return makeOSStatus(errno); 198 + 199 + if (infoBits & kFSCatInfoNodeFlags) 200 + { 201 + if (S_ISDIR(st.st_mode)) 202 + infoOut->nodeFlags = 4; 203 + } 204 + 205 + if (infoBits & (kFSCatInfoParentDirID|kFSCatInfoNodeID)) 206 + { 207 + if (infoBits & kFSCatInfoNodeID) 208 + infoOut->nodeID = ref->inodes[0]; 209 + for (int i = FSRef_MAX_DEPTH-1; i > 0; i--) 210 + { 211 + if (ref->inodes[i] == 0) 212 + continue; 213 + 214 + if (infoBits & kFSCatInfoParentDirID) 215 + infoOut->parentDirID = ref->inodes[i-1]; 216 + if (infoBits & kFSCatInfoNodeID) 217 + infoOut->nodeID = ref->inodes[i]; 218 + } 219 + } 220 + 221 + if (infoBits & kFSCatInfoDataSizes) 222 + { 223 + infoOut->dataLogicalSize = st.st_size; 224 + infoOut->dataPhysicalSize = st.st_blocks*512; 225 + } 226 + 227 + int uaccess; 228 + 229 + if (st.st_uid == getuid()) 230 + uaccess = st.st_mode & 0700; 231 + else if (hasgid(st.st_gid)) 232 + uaccess = st.st_mode & 070; 233 + else 234 + uaccess = st.st_mode & 07; 235 + 236 + if (infoBits & kFSCatInfoPermissions) 237 + { 238 + const uid_t uid = getuid(); 239 + 240 + infoOut->fsPermissionInfo.userID = st.st_uid; 241 + infoOut->fsPermissionInfo.groupID = st.st_gid; 242 + infoOut->fsPermissionInfo.mode = st.st_mode & 07777; 243 + infoOut->fsPermissionInfo.userAccess = uaccess; 244 + } 245 + 246 + if (infoBits & kFSCatInfoUserPrivs) 247 + { 248 + if (!(uaccess & 2)) 249 + infoOut->userPrivileges |= 0x4; // kioACUserNoMakeChangesMask 250 + if (getuid() != st.st_uid) 251 + infoOut->userPrivileges |= 0x80; // kioACUserNotOwnerMask 252 + } 253 + if (infoBits & kFSCatInfoCreateDate) 254 + infoOut->createDate = Darling::time_tToUTC(st.st_ctime); 255 + if (infoBits & kFSCatInfoContentMod) 256 + infoOut->attributeModDate = infoOut->contentModDate = Darling::time_tToUTC(st.st_mtime); 257 + if (infoBits & kFSCatInfoAccessDate) 258 + infoOut->accessDate = Darling::time_tToUTC(st.st_atime); 259 + } 260 + 261 + return noErr; 262 + } 263 + 264 + bool hasgid(gid_t gid) 265 + { 266 + gid_t* gids; 267 + int count; 268 + 269 + if (getegid() == gid) 270 + return true; 271 + 272 + while (true) 273 + { 274 + count = getgroups(0, nullptr); 275 + if (count == -1 && errno == EINVAL) 276 + continue; 277 + 278 + gids = (gid_t*) alloca(sizeof(gid_t)*count); 279 + if (getgroups(count, gids) != count) 280 + { 281 + count = 0; 282 + break; 283 + } 284 + } 285 + 286 + return std::find(gids, gids+count, gid) != (gids+count); 287 + } 288 + 289 + 290 + Boolean CFURLGetFSRef(CFURLRef urlref, FSRef* fsref) 291 + { 292 + char* buf; 293 + CFIndex len; 294 + CFStringRef sref = CFURLCopyFileSystemPath(urlref, kCFURLPOSIXPathStyle); 295 + 296 + if (!sref) 297 + return false; 298 + 299 + len = CFStringGetLength(sref)*4+1; 300 + buf = new char[len]; 301 + 302 + if (!CFStringGetCString(sref, buf, len, kCFStringEncodingUTF8)) 303 + { 304 + delete [] buf; 305 + return false; 306 + } 307 + 308 + CFRelease(sref); 309 + 310 + OSErr err = FSPathMakeRef((uint8_t*) buf, fsref, nullptr); 311 + delete [] buf; 312 + 313 + return err == noErr; 314 + } 315 +
+120
src/CoreServices/FileManager.h
··· 1 + #ifndef FILEMANAGER_H 2 + #define FILEMANAGER_H 3 + #include <stdint.h> 4 + #include <dirent.h> 5 + #include "MacErrors.h" 6 + #include "DateTimeUtils.h" 7 + #include <CoreFoundation/CFURL.h> 8 + 9 + extern "C" { 10 + 11 + constexpr size_t FSRef_MAX_DEPTH = 80 / sizeof(ino_t); 12 + 13 + struct FSRef 14 + { 15 + union 16 + { 17 + uint8_t hidden[80]; 18 + 19 + // Inode numbers leading to the file in the directory structure 20 + // 21 + // EXAMPLES: 22 + // All zeroes: / 23 + // sequence 1,2,0: [dir with inode 1]/[dir or file with inode 2] 24 + ino_t inodes[FSRef_MAX_DEPTH]; 25 + }; 26 + }; 27 + typedef FSRef* FSRefPtr; 28 + 29 + struct HFSUniStr255 30 + { 31 + uint16_t length; 32 + uint16_t unicode[255]; 33 + }; 34 + struct FSSpec; 35 + 36 + typedef FSSpec* FSSpecPtr; 37 + 38 + struct FSPermissionInfo 39 + { 40 + uint32_t userID, groupID; // uid, gid 41 + uint8_t reserved1; 42 + uint8_t userAccess; // mode for the current user 43 + uint16_t mode; // mode 44 + uint32_t reserved2; 45 + }; 46 + 47 + struct FSCatalogInfo 48 + { 49 + uint16_t nodeFlags; 50 + int16_t volume; 51 + uint32_t parentDirID; 52 + uint32_t nodeID; 53 + uint8_t sharingFlags; 54 + uint8_t userPrivileges; 55 + uint8_t reserved1; 56 + uint8_t reserved2; 57 + UTCDateTime createDate; 58 + UTCDateTime contentModDate; 59 + UTCDateTime attributeModDate; 60 + UTCDateTime accessDate; 61 + UTCDateTime backupDate; 62 + 63 + union 64 + { 65 + uint32_t permissions[4]; 66 + FSPermissionInfo fsPermissionInfo; 67 + }; 68 + 69 + uint8_t finderInfo[16]; 70 + uint8_t extFinderInfo[16]; 71 + uint64_t dataLogicalSize; 72 + uint64_t dataPhysicalSize; 73 + uint64_t rsrcLogicalSize; 74 + uint64_t rsrcPhysicalSize; 75 + uint32_t valence; // file count within a directory 76 + uint32_t textEncodingHint; 77 + }; 78 + 79 + enum 80 + { 81 + kFSPathMakeRefDefaultOptions = 0, 82 + kFSPathMakeRefDoNotFollowLeafSymlink = 1 83 + }; 84 + 85 + enum 86 + { 87 + kFSCatInfoNone = 0x0, 88 + kFSCatInfoTextEncoding = 0x1, 89 + kFSCatInfoNodeFlags = 0x2, 90 + kFSCatInfoVolume = 0x4, 91 + kFSCatInfoParentDirID = 0x8, 92 + kFSCatInfoNodeID = 0x10, 93 + kFSCatInfoCreateDate = 0x20, 94 + kFSCatInfoContentMod = 0x40, 95 + kFSCatInfoAttrMod = 0x80, 96 + kFSCatInfoAccessDate = 0x100, 97 + kFSCatInfoBackupDate = 0x200, 98 + kFSCatInfoPermissions = 0x400, 99 + kFSCatInfoFinderInfo = 0x800, 100 + kFSCatInfoFinderXInfo = 0x1000, 101 + kFSCatInfoValence = 0x2000, 102 + kFSCatInfoDataSizes = 0x4000, 103 + kFSCatInfoRsrcSizes = 0x8000, 104 + kFSCatInfoSharingFlags = 0x10000, 105 + kFSCatInfoUserPrivs = 0x20000, 106 + kFSCatInfoUserAccess = 0x80000, 107 + kFSCatInfoSetOwnership = 0x100000 108 + }; 109 + 110 + OSStatus FSPathMakeRef(const uint8_t* path, FSRef* fsref, Boolean* isDirectory); 111 + OSStatus FSPathMakeRefWithOptions(const uint8_t* path, long options, FSRef* fsref, Boolean* isDirectory); 112 + OSStatus FSRefMakePath(const FSRef* fsref, uint8_t* path, uint32_t maxSize); 113 + Boolean CFURLGetFSRef(CFURLRef urlref, FSRef* fsref); 114 + 115 + OSStatus FSGetCatalogInfo(const FSRef* ref, uint32_t infoBits, FSCatalogInfo* infoOut, HFSUniStr255* nameOut, FSSpecPtr fsspec, FSRef* parentDir); 116 + 117 + } 118 + 119 + #endif 120 +
+5 -3
src/CoreServices/MacErrors.h
··· 1 1 #ifndef MACERRORS_H 2 2 #define MACERRORS_H 3 - 4 - typedef long OSStatus; 3 + #include <CoreFoundation/CFBase.h> 5 4 6 5 inline OSStatus makeOSStatus(int errNo) { return 100000 + errNo; } 7 6 8 - #define unimpErr -4 7 + #define noErr 0 8 + #define unimpErr -4 9 + #define fnfErr -43 // file not found 10 + #define paramErr -50 9 11 10 12 #endif
+31 -11
src/dyld/MachOLoader.cpp
··· 109 109 { 110 110 } 111 111 112 - void MachOLoader::loadDylibs(const MachO& mach) 112 + void MachOLoader::loadDylibs(const MachO& mach, bool nobind) 113 113 { 114 114 for (std::string dylib : mach.dylibs()) 115 115 { 116 116 // __darwin_dlopen checks if already loaded 117 117 // automatically adds a reference if so 118 118 119 - if (!__darwin_dlopen(dylib.c_str(), DARWIN_RTLD_GLOBAL|DARWIN_RTLD_NOW)) 119 + int flags = DARWIN_RTLD_GLOBAL|DARWIN_RTLD_NOW; 120 + if (nobind) 121 + flags |= __DARLING_RTLD_NOBIND; 122 + 123 + if (!__darwin_dlopen(dylib.c_str(), flags)) 120 124 { 121 125 LOG << "Failed to dlopen " << dylib << ", throwing an exception\n"; 122 126 std::stringstream ss; ··· 229 233 230 234 m_last_addr = std::max(m_last_addr, (intptr)vmaddr + vmsize); 231 235 } 232 - 233 - if (mach.get_eh_frame().first) 234 - __register_frame(reinterpret_cast<void*>(mach.get_eh_frame().first + *slide)); 235 236 } 236 237 237 238 void MachOLoader::checkMmapMinAddr(intptr addr) ··· 473 474 474 475 475 476 476 - void MachOLoader::load(const MachO& mach, std::string sourcePath, Exports* exports) 477 + void MachOLoader::load(const MachO& mach, std::string sourcePath, Exports* exports, bool nobind) 477 478 { 478 479 if (!exports) 479 480 exports = &m_exports; ··· 489 490 doRebase(mach, slide); 490 491 doMProtect(); // decrease the segment protection value 491 492 492 - loadDylibs(mach); 493 + loadDylibs(mach, nobind); 493 494 494 495 loadInitFuncs(mach, slide); 495 496 496 497 loadExports(mach, base, exports); 497 498 498 - doBind(mach, slide); 499 + if (!nobind) 500 + doBind(mach, slide); 499 501 500 502 const FileMap::ImageMap* img = g_file_map.add(mach, slide, base); 501 503 502 - for (LoaderHookFunc* func : g_machoLoaderHooks) 503 - func(&img->header, slide); 504 + if (!nobind) 505 + { 506 + for (LoaderHookFunc* func : g_machoLoaderHooks) 507 + func(&img->header, slide); 508 + } 509 + else 510 + m_pendingBinds.push_back(PendingBind{ &mach, &img->header, slide }); 504 511 } 505 512 513 + void MachOLoader::doPendingBinds() 514 + { 515 + for (const PendingBind& b : m_pendingBinds) 516 + { 517 + doBind(*b.macho, b.slide); 518 + if (b.macho->get_eh_frame().first) 519 + __register_frame(reinterpret_cast<void*>(b.macho->get_eh_frame().first + b.slide)); 520 + for (LoaderHookFunc* func : g_machoLoaderHooks) 521 + func(b.header, b.slide); 522 + } 523 + m_pendingBinds.clear(); 524 + } 506 525 507 526 void MachOLoader::setupDyldData(const MachO& mach) 508 527 { ··· 549 568 // envCopy.push_back(envp[i]); 550 569 envCopy.push_back(0); 551 570 552 - load(mach, g_darwin_executable_path); 571 + load(mach, g_darwin_executable_path, nullptr, true); 553 572 setupDyldData(mach); 554 573 555 574 g_file_map.addWatchDog(m_last_addr + 1); ··· 558 577 559 578 mach.close(); 560 579 580 + doPendingBinds(); 561 581 runPendingInitFuncs(argc, argv, &envCopy[0], apple); 562 582 563 583 fflush(stdout);
+14 -2
src/dyld/MachOLoader.h
··· 59 59 void loadInitFuncs(const MachO& mach, intptr slide); 60 60 61 61 // Loads libraries this module depends on 62 - void loadDylibs(const MachO& mach); 62 + void loadDylibs(const MachO& mach, bool nobinds); 63 63 64 64 // Resolves all external symbols required by this module 65 65 void doBind(const MachO& mach, intptr slide); ··· 70 70 void loadExports(const MachO& mach, intptr base, Exports* exports); 71 71 72 72 // Loads a Mach-O file and does all the processing 73 - void load(const MachO& mach, std::string sourcePath, Exports* exports = 0); 73 + void load(const MachO& mach, std::string sourcePath, Exports* exports = 0, bool nobind = false); 74 74 75 75 // Dyld data contains an accessor to internal dyld functionality. This stores the accessor pointer. 76 76 void setupDyldData(const MachO& mach); 77 77 78 78 // Runs initializer functions that have not been run yet 79 79 void runPendingInitFuncs(int argc, char** argv, char** envp, char** apple); 80 + 81 + // Performs pending binds. Used when loading the main executable and its dependencies. 82 + void doPendingBinds(); 80 83 81 84 // Starts an application 82 85 void run(MachO& mach, int argc, char** argv, char** envp); ··· 105 108 int prot; 106 109 }; 107 110 std::vector<MProtect> m_mprotects; 111 + 112 + // Pending libs that require binding 113 + struct PendingBind 114 + { 115 + const MachO* macho; 116 + const mach_header* header; 117 + intptr slide; 118 + }; 119 + std::vector<PendingBind> m_pendingBinds; 108 120 }; 109 121 110 122 #endif
+11 -7
src/dyld/ld.cpp
··· 299 299 native_flags |= RTLD_NOLOAD; 300 300 if (flag & DARWIN_RTLD_NODELETE) 301 301 native_flags |= RTLD_NODELETE; 302 + if (flag & __DARLING_RTLD_NOBIND) 303 + native_flags |= __DARLING_RTLD_NOBIND; 302 304 return native_flags; 303 305 } 304 306 ··· 399 401 } 400 402 401 403 LoadedLibrary* lib = new LoadedLibrary; 404 + bool nobind = (flag & __DARLING_RTLD_NOBIND) != 0; 402 405 403 406 lib->name = name; 404 407 lib->refCount = 1; ··· 410 413 if (!global) 411 414 { 412 415 lib->exports = new Exports; 413 - g_loader->load(*machO, name, lib->exports); 416 + g_loader->load(*machO, name, lib->exports, nobind); 414 417 } 415 418 else 416 - g_loader->load(*machO, name, 0); 419 + g_loader->load(*machO, name, 0, nobind); 417 420 418 - char* apple[2] = { g_darwin_executable_path, 0 }; 419 - g_loader->runPendingInitFuncs(g_argc, g_argv, environ, apple); 421 + if (!nobind) 422 + { 423 + char* apple[2] = { g_darwin_executable_path, 0 }; 424 + g_loader->runPendingInitFuncs(g_argc, g_argv, environ, apple); 425 + } 420 426 421 427 g_ldLibraries[name] = lib; 422 428 return lib; ··· 519 525 Darling::MutexLock l(g_ldMutex); 520 526 g_ldError[0] = 0; 521 527 522 - symbol = translateSymbol(symbol); 523 - 524 528 if (handle == DARWIN_RTLD_NEXT || handle == DARWIN_RTLD_SELF || handle == DARWIN_RTLD_MAIN_ONLY || !handle) 525 529 { 526 530 LOG << "Cannot yet handle certain DARWIN_RTLD_* search strategies, falling back to RTLD_DEFAULT\n"; ··· 550 554 if (itSym == e.end()) 551 555 { 552 556 // Now try without a prefix 553 - sym = ::dlsym(RTLD_DEFAULT, symbol); 557 + sym = ::dlsym(RTLD_DEFAULT, translateSymbol(symbol)); 554 558 if (sym) 555 559 return sym; 556 560
+1
src/dyld/ld.h
··· 30 30 #define DARWIN_RTLD_NOLOAD 0x10 31 31 #define DARWIN_RTLD_NODELETE 0x80 32 32 #define DARWIN_RTLD_FIRST 0x100 33 + #define __DARLING_RTLD_NOBIND 0x20000000 33 34 34 35 #define DARWIN_RTLD_NEXT ((void*)-1) 35 36 #define DARWIN_RTLD_DEFAULT ((void*)-2)
+1 -1
src/dyld/public.cpp
··· 28 28 #include <set> 29 29 #include <link.h> 30 30 #include <stddef.h> 31 - #include "../libmach-o/leb.h" 31 + #include "../util/leb.h" 32 32 33 33 extern FileMap g_file_map; 34 34 extern "C" char* dyld_getDarwinExecutablePath();
+1
src/libSystem/CMakeLists.txt
··· 66 66 libc/getpwent.cpp 67 67 libc/signals.cpp 68 68 libc/termios.cpp 69 + libc/attrlist.cpp 69 70 common/auto.cpp 70 71 common/path.cpp 71 72 )
+16
src/libSystem/libc/attrlist.cpp
··· 1 + #include "attrlist.h" 2 + #include "darwin_errno_codes.h" 3 + #include <errno.h> 4 + 5 + int getattrlist(const char* path, struct attrlist* attrs, void* buf, size_t bufSize, unsigned long options) 6 + { 7 + errno = DARWIN_ENOTSUP; 8 + return -1; 9 + } 10 + 11 + int setattrlist(const char* path, struct attrlist* attrs, void* buf, size_t bufSize, unsigned long options) 12 + { 13 + errno = DARWIN_ENOTSUP; 14 + return -1; 15 + } 16 +
+17
src/libSystem/libc/attrlist.h
··· 1 + #ifndef LIBC_ATTRLIST_H 2 + #define LIBC_ATTRLIST_H 3 + #include <stddef.h> 4 + 5 + #ifdef __cplusplus 6 + extern "C" { 7 + #endif 8 + 9 + int getattrlist(const char* path, struct attrlist* attrs, void* buf, size_t bufSize, unsigned long options); 10 + int setattrlist(const char* path, struct attrlist* attrs, void* buf, size_t bufSize, unsigned long options); 11 + 12 + #ifdef __cplusplus 13 + } 14 + #endif 15 + 16 + #endif 17 +
-63
src/libmach-o/leb.cpp
··· 1 - // Copyright 2011 Shinichiro Hamaji. All rights reserved. 2 - // 3 - // Redistribution and use in source and binary forms, with or without 4 - // modification, are permitted provided that the following conditions 5 - // are met: 6 - // 7 - // 1. Redistributions of source code must retain the above copyright 8 - // notice, this list of conditions and the following disclaimer. 9 - // 10 - // 2. Redistributions in binary form must reproduce the above 11 - // copyright notice, this list of conditions and the following 12 - // disclaimer in the documentation and/or other materials 13 - // provided with the distribution. 14 - // 15 - // THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 16 - // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 - // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 - // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 19 - // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 - // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 - // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 - // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 - // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 - // SUCH DAMAGE. 27 - 28 - 29 - #include "leb.h" 30 - #include <stdint.h> 31 - 32 - uint64_t uleb128(const uint8_t*& p) 33 - { 34 - uint64_t r = 0; 35 - int s = 0; 36 - do 37 - { 38 - r |= (uint64_t)(*p & 0x7f) << s; 39 - s += 7; 40 - } 41 - while (*p++ >= 0x80); 42 - return r; 43 - } 44 - 45 - int64_t sleb128(const uint8_t*& p) 46 - { 47 - int64_t r = 0; 48 - int s = 0; 49 - for (;;) { 50 - uint8_t b = *p++; 51 - if (b < 0x80) 52 - { 53 - if (b & 0x40) 54 - r -= (0x80 - b) << s; 55 - else 56 - r |= (b & 0x3f) << s; 57 - break; 58 - } 59 - r |= (b & 0x7f) << s; 60 - s += 7; 61 - } 62 - return r; 63 - }
-39
src/libmach-o/leb.h
··· 1 - // Copyright 2011 Shinichiro Hamaji. All rights reserved. 2 - // 3 - // Redistribution and use in source and binary forms, with or without 4 - // modification, are permitted provided that the following conditions 5 - // are met: 6 - // 7 - // 1. Redistributions of source code must retain the above copyright 8 - // notice, this list of conditions and the following disclaimer. 9 - // 10 - // 2. Redistributions in binary form must reproduce the above 11 - // copyright notice, this list of conditions and the following 12 - // disclaimer in the documentation and/or other materials 13 - // provided with the distribution. 14 - // 15 - // THIS SOFTWARE IS PROVIDED BY Shinichiro Hamaji ``AS IS'' AND ANY 16 - // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 - // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 18 - // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Shinichiro Hamaji OR 19 - // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 20 - // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 - // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF 22 - // USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 23 - // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24 - // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 25 - // OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 - // SUCH DAMAGE. 27 - 28 - 29 - #ifndef LEB_H 30 - #define LEB_H 31 - #include <stdint.h> 32 - 33 - __attribute__ ((visibility ("default"))) 34 - uint64_t uleb128(const uint8_t*& p); 35 - 36 - __attribute__ ((visibility ("default"))) 37 - int64_t sleb128(const uint8_t*& p); 38 - 39 - #endif
-1
src/libobjcdarwin/CMakeLists.txt
··· 41 41 42 42 NSBundle_dyld.mm 43 43 misc.mm 44 - zero.c 45 44 ) 46 45 47 46 if(NOT OBJC_ABI_2)
+1 -1
src/libobjcdarwin/NameTranslate.cpp
··· 35 35 static bool ClassTranslator(char* name) 36 36 { 37 37 #ifdef __x86_64__ 38 - if (strncmp(name, "OBJC_EHTYPE_$_", 14) == 0) 38 + if (strncmp(name, "OBJC_EHTYPE_$_", 14) == 0 || strcmp(name, "OBJC_EHTYPE_id") == 0) 39 39 { 40 40 strcpy(name, "_objc_dummy_ehtype"); 41 41 return true;
src/libobjcdarwin/zero.c src/Cocoa/zero.c
+4 -4
src/thin/CMakeLists.txt
··· 9 9 target_link_libraries(AppKit -lgnustep-gui -lopal) 10 10 SET_TARGET_PROPERTIES(AppKit PROPERTIES LINKER_LANGUAGE C) 11 11 12 - add_library(Cocoa SHARED) 13 - target_link_libraries(Cocoa -lgnustep-gui -lopal crashhandler) 14 - SET_TARGET_PROPERTIES(Cocoa PROPERTIES LINKER_LANGUAGE C) 12 + add_library(Carbon SHARED) 13 + target_link_libraries(Carbon CoreServices) 14 + SET_TARGET_PROPERTIES(Carbon PROPERTIES LINKER_LANGUAGE C) 15 15 16 - install(TARGETS Cocoa AppKit DESTINATION "lib${SUFFIX}/darling") 16 + install(TARGETS AppKit Carbon DESTINATION "lib${SUFFIX}/darling") 17 17
+10
src/util/autofree.h
··· 1 + #ifndef AUTOFREE_H 2 + #define AUTOFREE_H 3 + 4 + struct autofree 5 + { 6 + void operator()(void* x) { free(x); } 7 + }; 8 + 9 + #endif 10 +
+159
src/util/leb.cpp
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2012 Lubos Dolezel 5 + Copyright (C) 2011 Shinichiro Hamaji 6 + 7 + Darling is free software: you can redistribute it and/or modify 8 + it under the terms of the GNU General Public License as published by 9 + the Free Software Foundation, either version 3 of the License, or 10 + (at your option) any later version. 11 + 12 + Darling is distributed in the hope that it will be useful, 13 + but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + GNU General Public License for more details. 16 + 17 + You should have received a copy of the GNU General Public License 18 + along with Foobar. If not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #include "leb.h" 22 + #include <stdint.h> 23 + #include <stdexcept> 24 + 25 + uint64_t uleb128(const uint8_t*& p) 26 + { 27 + uint64_t r = 0; 28 + int s = 0; 29 + do 30 + { 31 + r |= (uint64_t)(*p & 0x7f) << s; 32 + s += 7; 33 + } 34 + while (*p++ >= 0x80); 35 + return r; 36 + } 37 + 38 + int64_t sleb128(const uint8_t*& p) 39 + { 40 + int64_t r = 0; 41 + int s = 0; 42 + for (;;) 43 + { 44 + uint8_t b = *p++; 45 + if (b < 0x80) 46 + { 47 + if (b & 0x40) 48 + r -= (0x80 - b) << s; 49 + else 50 + r |= (b & 0x3f) << s; 51 + break; 52 + } 53 + r |= (b & 0x7f) << s; 54 + s += 7; 55 + } 56 + return r; 57 + } 58 + 59 + std::vector<uint8_t> uleb128(uint64_t v) 60 + { 61 + if (!v) 62 + return std::vector<uint8_t>({ 0 }); 63 + 64 + std::vector<uint8_t> rv; 65 + int bitsUsed = 0, bytesUsed; 66 + for (int i = 0; i < 64; i++) 67 + { 68 + if (v & (1ll << i)) 69 + bitsUsed = i+1; 70 + } 71 + 72 + // round it up to 7 bits 73 + bytesUsed = (bitsUsed+6) / 7; 74 + 75 + for (int i = 0; i < bytesUsed; i++) 76 + { 77 + uint8_t enc = (v >> (i*7)) & 0x7f; 78 + if (i+1 < bytesUsed) 79 + enc |= 0x80; 80 + rv.push_back(enc); 81 + } 82 + 83 + return rv; 84 + } 85 + 86 + 87 + void LEBStream::add(uint64_t v) 88 + { 89 + std::vector<uint8_t> enc = uleb128(v); 90 + m_data.insert(m_data.end(), enc.begin(), enc.end()); 91 + } 92 + 93 + size_t LEBStream::count() const 94 + { 95 + size_t count = 0; 96 + 97 + for (size_t i = 0; i < m_data.size(); i++) 98 + { 99 + if (!(m_data[i] & 0x80)) 100 + count++; 101 + } 102 + 103 + return count; 104 + } 105 + 106 + uint64_t LEBStream::pop() 107 + { 108 + if (!bytes()) 109 + throw std::underflow_error("LEBStream::pop()"); 110 + 111 + size_t start = 0; 112 + for (size_t i = 0; i < m_data.size()-1; i++) 113 + { 114 + if (!(m_data[i] & 0x80)) 115 + start = i+1; 116 + } 117 + 118 + const uint8_t* data = &m_data[start]; 119 + uint64_t v = uleb128(data); 120 + m_data.resize(start); 121 + return v; 122 + } 123 + 124 + LEBStreamIterator LEBStream::begin() const 125 + { 126 + return LEBStreamIterator(data(), 0, bytes()); 127 + } 128 + 129 + LEBStreamIterator LEBStream::end() const 130 + { 131 + return LEBStreamIterator(data(), bytes(), bytes()); 132 + } 133 + 134 + LEBStreamIterator::LEBStreamIterator(const uint8_t* data, size_t bytes, size_t pos) 135 + : m_data(data), m_bytes(bytes), m_pos(pos) 136 + { 137 + } 138 + 139 + uint64_t LEBStreamIterator::operator*() 140 + { 141 + if (m_pos >= m_bytes) 142 + return 0; 143 + 144 + const uint8_t* data = m_data + m_pos; 145 + return uleb128(data); 146 + } 147 + 148 + LEBStreamIterator& LEBStreamIterator::operator++(int) 149 + { 150 + while (m_data[m_pos] & 0x80 && m_pos < m_bytes) 151 + m_pos++; 152 + return *this; 153 + } 154 + 155 + bool LEBStreamIterator::operator!=(const LEBStreamIterator& that) 156 + { 157 + return m_pos != that.m_pos; 158 + } 159 +
+71
src/util/leb.h
··· 1 + /* 2 + This file is part of Darling. 3 + 4 + Copyright (C) 2012 Lubos Dolezel 5 + Copyright (C) 2011 Shinichiro Hamaji 6 + 7 + Darling is free software: you can redistribute it and/or modify 8 + it under the terms of the GNU General Public License as published by 9 + the Free Software Foundation, either version 3 of the License, or 10 + (at your option) any later version. 11 + 12 + Darling is distributed in the hope that it will be useful, 13 + but WITHOUT ANY WARRANTY; without even the implied warranty of 14 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 + GNU General Public License for more details. 16 + 17 + You should have received a copy of the GNU General Public License 18 + along with Foobar. If not, see <http://www.gnu.org/licenses/>. 19 + */ 20 + 21 + #ifndef LEB_H 22 + #define LEB_H 23 + #include <stdint.h> 24 + #include <vector> 25 + #include <stddef.h> 26 + 27 + std::vector<uint8_t> uleb128(uint64_t v); 28 + uint64_t uleb128(const uint8_t*& p); 29 + 30 + int64_t sleb128(const uint8_t*& p); 31 + 32 + class LEBStreamIterator; 33 + 34 + class LEBStream 35 + { 36 + public: 37 + LEBStream(); 38 + void add(uint64_t v); 39 + 40 + // log(N)! 41 + size_t count() const; 42 + 43 + // log(1) 44 + inline size_t bytes() const { return m_data.size(); } 45 + inline const uint8_t* data() const { return &m_data[0]; } 46 + 47 + // reverse of add() 48 + uint64_t pop(); 49 + 50 + LEBStreamIterator begin() const; 51 + LEBStreamIterator end() const; 52 + private: 53 + std::vector<uint8_t> m_data; 54 + }; 55 + 56 + class LEBStreamIterator 57 + { 58 + protected: 59 + LEBStreamIterator(const uint8_t* data, size_t bytes, size_t pos = 0); 60 + public: 61 + uint64_t operator*(); 62 + LEBStreamIterator& operator++(int); 63 + bool operator!=(const LEBStreamIterator& that); 64 + private: 65 + const uint8_t* m_data; 66 + size_t m_bytes, m_pos; 67 + 68 + friend class LEBStream; 69 + }; 70 + 71 + #endif