this repo has no description
1
fork

Configure Feed

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

Merge pull request #222 from bugaevc/no-virtual-prefix-squash

Get of rid of the VirtualPrefix, use the new 'darling' binary

authored by

Luboš Doležel and committed by
GitHub
0b95b740 667cb9ac

+285 -1303
+31 -1
CMakeLists.txt
··· 58 58 if (NOT DARLING_NO_EXECUTABLES) 59 59 install(FILES etc/dylib.conf etc/version.conf 60 60 DESTINATION libexec/darling/etc/darling) 61 - endif (NOT DARLING_NO_EXECUTABLES) 61 + install(FILES etc/resolv.conf 62 + DESTINATION libexec/darling/etc) 62 63 64 + install(DIRECTORY DESTINATION libexec/darling/Volumes) 65 + install(DIRECTORY DESTINATION libexec/darling/Volumes/SystemRoot) 66 + InstallSymlink(/ ${CMAKE_INSTALL_PREFIX}/libexec/darling/Volumes/DarlingEmulatedDrive) 67 + 68 + install(DIRECTORY DESTINATION libexec/darling/proc) 69 + 70 + install(DIRECTORY DESTINATION libexec/darling/var) 71 + install(DIRECTORY DESTINATION libexec/darling/var/root) 72 + install(DIRECTORY DESTINATION libexec/darling/var/run) 73 + InstallSymlink(/dev/log ${CMAKE_INSTALL_PREFIX}/libexec/darling/var/run/syslog) 74 + 75 + install(DIRECTORY DESTINATION libexec/darling/usr) 76 + install(DIRECTORY DESTINATION libexec/darling/usr/local) 77 + install(DIRECTORY DESTINATION libexec/darling/usr/local/share) 78 + InstallSymlink(/Volumes/SystemRoot${CMAKE_INSTALL_PREFIX}/share/darling ${CMAKE_INSTALL_PREFIX}/libexec/darling/usr/local/share/darling) 79 + 80 + InstallSymlink(/Volumes/SystemRoot/dev ${CMAKE_INSTALL_PREFIX}/libexec/darling/dev) 81 + InstallSymlink(/Volumes/SystemRoot/tmp ${CMAKE_INSTALL_PREFIX}/libexec/darling/tmp) 82 + InstallSymlink(/Volumes/SystemRoot/home ${CMAKE_INSTALL_PREFIX}/libexec/darling/Users) 83 + 84 + InstallSymlink(/proc/self/mounts ${CMAKE_INSTALL_PREFIX}/libexec/darling/etc/mtab) 85 + InstallSymlink(/Volumes/SystemRoot/etc/passwd ${CMAKE_INSTALL_PREFIX}/libexec/darling/etc/passwd) 86 + InstallSymlink(/Volumes/SystemRoot/etc/group ${CMAKE_INSTALL_PREFIX}/libexec/darling/etc/group) 87 + 88 + install(DIRECTORY DESTINATION libexec/darling/etc/ld.so.conf.d) 89 + install(CODE "execute_process(COMMAND bash ${DARLING_TOP_DIRECTORY}/src/setup-ld-so.sh WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/libexec/darling)") 90 + InstallSymlink(/Volumes/SystemRoot/lib ${CMAKE_INSTALL_PREFIX}/libexec/darling/lib) 91 + InstallSymlink(/Volumes/SystemRoot/lib64 ${CMAKE_INSTALL_PREFIX}/libexec/darling/lib64) 92 + endif (NOT DARLING_NO_EXECUTABLES)
-9
README.md
··· 61 61 make install 62 62 ```` 63 63 64 - To build the new, experimental `darling` executable: 65 - 66 - ```` 67 - cmake ../.. -DCMAKE_TOOLCHAIN_FILE=../../Toolchain-x86_64.cmake -DNEW_DARLING=TRUE 68 - make 69 - make install 70 - chmod +s $(which darling) 71 - ```` 72 - 73 64 #### For running i386 OS X binaries 74 65 75 66 <a href="http://teamcity.dolezel.info/viewType.html?buildTypeId=Darling_DebianStableX8664&guest=1">
+2
etc/resolv.conf
··· 1 + nameserver 8.8.8.8 2 + nameserver 8.8.4.4
+3 -1
src/darling-config.h.in
··· 9 9 #define DYLD_PATH "${CMAKE_INSTALL_PREFIX}/bin/dyld" 10 10 11 11 #define ETC_DARLING_PATH "/etc/darling" 12 + // Path where the system root gets "mounted" inside the prefix 13 + #define SYSTEM_ROOT "/Volumes/SystemRoot" 12 14 13 15 #cmakedefine MULTILIB 14 16 #cmakedefine FRAMEWORK_COREAUDIO ··· 17 19 #ifndef __APPLE__ 18 20 19 21 /* 20 - * Credit: 22 + * Credit: 21 23 * 22 24 * David Chisnall 23 25 * http://comments.gmane.org/gmane.comp.desktop.etoile.devel/1556
+3 -12
src/dyld/CMakeLists.txt
··· 37 37 set_target_properties(dyld-bin PROPERTIES OUTPUT_NAME dyld${SUFFIX}) 38 38 target_link_libraries(dyld-bin dyld darling-util mach-o) 39 39 40 - if (NEW_DARLING) 41 - add_executable(darling darling.c) 42 - endif (NEW_DARLING) 40 + add_executable(darling darling.c) 43 41 44 42 if (NOT DARLING_NO_EXECUTABLES) 45 43 add_executable(dyldd dyldd.cpp) 46 44 target_link_libraries(dyldd dyld darling-util mach-o) 47 45 install(TARGETS dyldd DESTINATION bin) 48 - if (NEW_DARLING) 49 - install(TARGETS darling DESTINATION bin) 50 - else (NEW_DARLING) 51 - install(PROGRAMS darling DESTINATION bin 52 - PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ 53 - GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) 54 - endif(NEW_DARLING) 46 + install(TARGETS darling DESTINATION bin 47 + PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE SETUID) 55 48 add_library(dexe_startup STATIC darling-so-start.S) 56 49 endif (NOT DARLING_NO_EXECUTABLES) 57 50 ··· 62 55 set_target_properties(dyld-multilib PROPERTIES OUTPUT_NAME dyld) 63 56 install(TARGETS dyld-multilib DESTINATION bin) 64 57 endif (BITS EQUAL 64) 65 - 66 -
-236
src/dyld/darling
··· 1 - #!/bin/bash 2 - # 3 - # This file is part of Darling. 4 - # 5 - # Copyright (C) 2015 Lubos Dolezel 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 Darling. If not, see <http://www.gnu.org/licenses/>. 19 - # 20 - 21 - export PATH="/bin:/sbin:/usr/bin:/usr/local/bin" 22 - 23 - SCRIPT=$(readlink -f "$0") 24 - SCRIPTPATH=$(dirname "$SCRIPT") 25 - DARLING_PREFIX=$(realpath "$SCRIPTPATH/..") 26 - 27 - selfmtime=$(stat -c %Y "$DARLING_PREFIX/bin/darling") 28 - 29 - check_prefix() { 30 - 31 - if [ ! -d "$DPREFIX" -o ! -f "$DPREFIX/.update-timestamp" ]; then 32 - setup_prefix "$DPREFIX" 33 - else 34 - 35 - updatets=$(cat $DPREFIX/.update-timestamp) 36 - case $updatets in 37 - disable*) 38 - ;; 39 - ''|*[!0-9]*) 40 - setup_prefix "$DPREFIX" 41 - ;; 42 - *) 43 - [ $updatets -lt $selfmtime ] && setup_prefix "$DPREFIX" 44 - ;; 45 - esac 46 - 47 - return 0 48 - fi 49 - } 50 - 51 - setup_prefix() { 52 - prefix_pkg="/tmp/prefix.$$.pkg" 53 - 54 - >&2 echo "Setting up prefix at $1" 55 - >&2 echo 56 - 57 - mkdir -p "$1" 58 - rm -f "$1/darling-prefix" 59 - 60 - rm -f "$1/system-root" 61 - ln -s / "$1/system-root" 62 - 63 - rm -f "$1/darling-prefix" 64 - ln -s "system-root${DARLING_PREFIX}" "$1/darling-prefix" 65 - 66 - rm -f "$1/dev" 67 - ln -sf "system-root/dev" "$1/dev" 68 - 69 - rm -f "$1/home" 70 - ln -sf "system-root/home" "$1/home" 71 - 72 - rm -f "$1/Users" 73 - ln -sf "home" "$1/Users" 74 - 75 - rm -f "$1/tmp" 76 - ln -sf "system-root/tmp" "$1/tmp" 77 - 78 - rm -f "$1/etc" 2>/dev/null || true 79 - mkdir -p "$1/etc" 80 - ln -sf "../system-root/etc/timezone" "$1/etc/timezone" 81 - ln -sf "../system-root/etc/resolv.conf" "$1/etc/resolv.conf" 82 - ln -sf "../system-root/etc/passwd" "$1/etc/passwd" 83 - ln -sf "../system-root/etc/group" "$1/etc/group" 84 - ln -sf "../system-root/etc/hosts" "$1/etc/hosts" 85 - ln -sf "../system-root/etc/localtime" "$1/etc/localtime" || true 86 - 87 - mkdir -p "$1/usr/share" 88 - rm -f "$1/usr/share/zoneinfo" 2>/dev/null || true 89 - ln -sf "../../system-root/usr/share/zoneinfo" "$1/usr/share/zoneinfo" 90 - 91 - mkdir -p "$1/Volumes" "$1/Applications" "$1/var/root" || true 92 - mkdir -p "$1/var/run" || true 93 - ln -sf "../../system-root/dev/log" "$1/var/run/syslog" || true 94 - 95 - # Clean up old cruft (symlinks) 96 - rm -f "$1/bin" "$1/usr/bin" "$1/etc" "$1/System/Library/Frameworks" "$1/System/Library/PrivateFrameworks" 2>/dev/null || true 97 - cp -rf "${DARLING_PREFIX}/libexec/darling/"* "$1" 98 - echo -n "$selfmtime" > "$1/.update-timestamp" 99 - 100 - install_pkg "org.darlinghq.pkg.OpenSSLCertificates" 101 - 102 - >&2 echo "Building manpage database..." 103 - "${dexec_path}" "${DPREFIX}/bin/bash" -c "/usr/libexec/makewhatis" 104 - 105 - >&2 echo "Prefix is ready." 106 - } 107 - 108 - install_pkg() { 109 - temp="/tmp/pkgs.$$" 110 - mkdir "$temp" || true 111 - 112 - >&2 echo "Getting latest version of $1..." 113 - version=$(wget "http://packages.darlinghq.org/${1}/latest.txt" -O- 2>/dev/null) 114 - pkgpath="$temp/${1}-${version}.pkg" 115 - 116 - >&2 echo "Downloading $1 (version $version)..." 117 - wget "http://packages.darlinghq.org/${1}/${1}-${version}.pkg" -O "$pkgpath" 2>/dev/null 118 - 119 - "${DARLING_PREFIX}/libexec/darling/usr/bin/installer" -pkg "/system-root${pkgpath}" -target / 120 - 121 - rm -rf "$temp" 122 - } 123 - 124 - is_sudo_allowed() { 125 - if type -p sudo &> /dev/null; then 126 - sudo -nl "$@" &> /dev/null && return 0 127 - fi 128 - return 1 129 - } 130 - 131 - launch_with_su() { 132 - if [ "$(id -u)" = 0 ]; then 133 - "$@" 134 - elif is_sudo_allowed; then 135 - sudo "$@" 136 - else 137 - local cmd=$(printf '%q ' "$@") 138 - su --shell=$BASH --command "$cmd" 139 - fi 140 - } 141 - 142 - darling_check() { 143 - # Returning values: 144 - # 0: module is loaded, file permissions are good 145 - # 1: module is loaded, file permissions are wrong 146 - # 2: module is not loaded 147 - grep -q darling_mach "/proc/modules" 148 - if [ $? -eq 0 ]; then 149 - [ -r "/dev/mach" -a -w "/dev/mach" ] && return 0 || return 1 150 - else 151 - return 2 152 - fi 153 - } 154 - 155 - darling_load() { 156 - if $(darling_check); then 157 - >&2 echo "Module is already loaded." 158 - else 159 - >&2 echo -n "Loading module... " 160 - launch_with_su modprobe darling-mach && >&2 echo "Done." || >&2 echo "Fail." 161 - sleep 1 # Wait for module loading 162 - launch_with_su chmod a+rw "/dev/mach" 163 - fi 164 - 165 - } 166 - 167 - darling_unload() { 168 - if $(darling_check); then 169 - >&2 echo -n "Unloading module... " 170 - launch_with_su rmmod darling-mach && >&2 echo "Done." || >&2 echo "Fail." 171 - else 172 - >&2 echo "Module is not loaded, so it can't be unloaded." 173 - fi 174 - } 175 - 176 - if [ $# -eq 0 ]; then 177 - >&2 echo "This is Darling, a runtime environment for OS X applications." 178 - >&2 echo 179 - >&2 echo "Copyright (C) 2012-2015 Lubos Dolezel" 180 - >&2 echo "Includes software components which are Copyright (C) Apple Computer, Inc. and many others." 181 - >&2 echo 182 - >&2 echo -e "Usage:\tdarling PROGRAM [ARGUMENTS...]\tRun the specified program" 183 - >&2 echo -e "\tdarling shell\t\t\tStart bash shell in prefix" 184 - #>&2 echo -e "\tdarling hdiutil\t\t\tMount DMG disk images" 185 - #>&2 echo -e "\tdarling pkgutil\t\t\tInstall PKG packages" 186 - >&2 echo -e "\tdarling load\t\t\tLoad kernel module" 187 - >&2 echo -e "\tdarling unload\t\t\tUnload kernel module" 188 - >&2 echo 189 - >&2 echo "The prefix is specified by the DPREFIX environment variable." 190 - >&2 echo "The default DPREFIX is \$HOME/.darling" 191 - exit 1 192 - fi 193 - 194 - set -e 195 - 196 - if [ -z "$DPREFIX" ]; then 197 - export DPREFIX="$HOME/.darling" 198 - fi 199 - 200 - if ! $(darling_check) && [ "$1" != "load" ] && [ "$1" != "unload" ]; then 201 - 2>&1 echo "Cannot open /dev/mach, running 'darling load'." 202 - darling_load 203 - fi 204 - 205 - dexec_path="${0%darling}dyld" 206 - #dexec_path="${DARLING_PREFIX}/bin/darling-exec" 207 - 208 - case "$1" in 209 - "shell") 210 - check_prefix 211 - 212 - if [ $# -gt 1 ]; then 213 - exec "${dexec_path}" "${DPREFIX}/bin/bash" -c "${*:2}" 214 - else 215 - exec "${dexec_path}" "${DPREFIX}/bin/bash" 216 - fi 217 - ;; 218 - #"hdiutil") 219 - # exec "${DPREFIX}/usr/bin/hdiutil" "${@:2}" 220 - # exit $? 221 - # ;; 222 - #"pkgutil") 223 - # >2& echo "Not implemented yet" 224 - # exit 1 225 - # ;; 226 - "load") 227 - darling_load 228 - ;; 229 - "unload") 230 - darling_unload 231 - ;; 232 - *) 233 - check_prefix 234 - exec "${dexec_path}" "$1" "${@:2}" 235 - ;; 236 - esac
+17 -1
src/dyld/darling-so-start.S
··· 3 3 4 4 .text 5 5 6 + // For running executables from inside the prefix 6 7 dyld_path: 8 + .ascii SYSTEM_ROOT 9 + .string DYLD_PATH 10 + 11 + // Additionally, we support running them from the host system 12 + dyld_host_path: 7 13 .string DYLD_PATH 8 14 9 15 proc_self_exe: ··· 56 62 movl $__NR_execve, %eax 57 63 syscall 58 64 65 + // If we failed to find dyld under the system root, 66 + // try again without it 67 + leaq dyld_host_path(%rip), %rdi // exec path 68 + movq %rsp, %rsi // argv 69 + movl 0(%rsp), %ecx // argc 70 + leaq 16(%rsp, %rcx, 8), %rdx // envp 71 + movq %rdi, (%rsi) // overwrite argc with dyld_path 72 + 73 + movl $__NR_execve, %eax 74 + syscall 75 + 59 76 fail: 60 77 movl $2, %edi 61 78 leaq failure_msg(%rip), %rsi ··· 64 81 syscall 65 82 66 83 ud2 67 -
+85 -59
src/dyld/darling.c
··· 37 37 #include "darling.h" 38 38 #include "darling-config.h" 39 39 40 - // Path where the system root gets "mounted" inside the prefix 41 - #define SYSTEM_ROOT "/system-root" 42 40 43 41 const char* DARLING_INIT_COMM = "darling-init"; 44 42 char *prefix; ··· 47 45 int main(int argc, const char** argv) 48 46 { 49 47 pid_t pidInit, pidChild; 50 - char path[4096]; 51 48 int wstatus; 52 49 53 50 if (argc <= 1) ··· 73 70 prefix = defaultPrefixPath(); 74 71 if (!prefix) 75 72 return 1; 76 - setenv("DPREFIX", prefix, 0); 73 + unsetenv("DPREFIX"); 77 74 78 75 if (!checkPrefixDir()) 79 76 setupPrefix(); ··· 81 78 82 79 pidInit = getInitProcess(); 83 80 81 + if (strcmp(argv[1], "shutdown") == 0) 82 + { 83 + if (pidInit == 0) 84 + { 85 + fprintf(stderr, "Darling container is not running\n"); 86 + return 1; 87 + } 88 + 89 + // TODO: when we have a working launchd, 90 + // this is where we ask it to shut down nicely 91 + 92 + kill(pidInit, SIGKILL); 93 + return 0; 94 + } 95 + 84 96 // If prefix's init is not running, start it up 85 97 if (pidInit == 0) 86 98 { ··· 91 103 92 104 if (strcmp(argv[1], "shell") != 0) 93 105 { 106 + char *path = realpath(argv[1], NULL); 107 + char *fullPath; 108 + 109 + if (path == NULL) 110 + { 111 + fprintf(stderr, "Cannot resolve path: %s\n", strerror(errno)); 112 + exit(1); 113 + } 114 + 94 115 const char *argv_child[argc + 1]; 95 116 96 - argv_child[0] = "dyld"; 97 - for (int i = 1; i < argc; i++) 117 + argv_child[0] = SYSTEM_ROOT DYLD_PATH; 118 + 119 + fullPath = malloc(strlen(SYSTEM_ROOT) + strlen(path) + 1); 120 + strcpy(fullPath, SYSTEM_ROOT); 121 + strcat(fullPath, path); 122 + argv_child[1] = fullPath; 123 + 124 + for (int i = 2; i < argc; i++) 98 125 argv_child[i] = argv[i]; 99 126 argv_child[argc] = NULL; 100 127 101 - pidChild = spawnChild(pidInit, DYLD_PATH, argv_child); 128 + pidChild = spawnChild(pidInit, SYSTEM_ROOT DYLD_PATH, argv_child); 129 + free(path); 130 + free(fullPath); 102 131 } 103 132 else 104 133 { 105 134 // Spawn the shell 106 - snprintf(path, sizeof(path), "%s/bin/bash", prefix); 107 135 if (argc > 2) 108 136 { 109 137 size_t total_len = 0; ··· 118 146 // Overwrite the last whitespace 119 147 *(to - 1) = '\0'; 120 148 121 - pidChild = spawnChild(pidInit, DYLD_PATH, 122 - (const char *[5]) {"dyld", path, "-c", buffer, NULL}); 149 + pidChild = spawnChild(pidInit, SYSTEM_ROOT DYLD_PATH, 150 + (const char *[5]) {SYSTEM_ROOT DYLD_PATH, "/bin/bash", "-c", buffer, NULL}); 123 151 } 124 152 else 125 - pidChild = spawnChild(pidInit, DYLD_PATH, 126 - (const char *[3]) {"dyld", path, NULL}); 153 + pidChild = spawnChild(pidInit, SYSTEM_ROOT DYLD_PATH, 154 + (const char *[3]) {SYSTEM_ROOT DYLD_PATH, "/bin/bash", NULL}); 127 155 } 128 156 129 157 // Drop the privileges so that we can be killed, etc by the user ··· 197 225 } 198 226 close(fdNS); 199 227 200 - snprintf(pathNS, sizeof(pathNS), "/proc/%d/ns/user", pidInit); 228 + /* 229 + snprintf(pathNS, sizeof(pathNS), SYSTEM_ROOT "/proc/%d/ns/user", pidInit); 201 230 fdNS = open(pathNS, O_RDONLY); 202 231 if (fdNS < 0) 203 232 { 204 233 fprintf(stderr, "Cannot open user namespace file: %s\n", strerror(errno)); 205 234 exit(1); 206 235 } 236 + */ 207 237 208 238 setresuid(g_originalUid, g_originalUid, g_originalUid); 209 239 setresgid(g_originalGid, g_originalGid, g_originalGid); 210 240 241 + /* 211 242 if (setns(fdNS, CLONE_NEWUSER) != 0) 212 243 { 213 244 fprintf(stderr, "Cannot join user namespace: %s\n", strerror(errno)); 214 245 exit(1); 215 246 } 216 247 close(fdNS); 248 + */ 217 249 218 250 setupChild(curPath); 219 251 ··· 231 263 char buffer1[4096]; 232 264 char buffer2[4096]; 233 265 234 - setenv("PATH", "/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin", 1); 266 + setenv("PATH", 267 + "/usr/bin:" 268 + "/bin:" 269 + "/usr/sbin:" 270 + "/sbin:" 271 + "/usr/local/bin", 272 + 1); 273 + 274 + setenv("LD_LIBRARY_PATH", 275 + SYSTEM_ROOT LIB_PATH, 276 + 1); 235 277 236 278 sscanf(getenv("HOME"), "/home/%4096s", buffer1); 237 279 snprintf(buffer2, sizeof(buffer2), "/Users/%s", buffer1); ··· 242 284 // We're currently inside our home directory 243 285 snprintf(buffer2, sizeof(buffer2), "/Users/%s", buffer1); 244 286 setenv("PWD", buffer2, 1); 245 - 246 - snprintf(buffer2, sizeof(buffer2), "%s/Users/%s", prefix, buffer1); 247 287 chdir(buffer2); 248 288 } 249 289 else 250 290 { 251 291 snprintf(buffer2, sizeof(buffer2), SYSTEM_ROOT "%s", curPath); 252 292 setenv("PWD", buffer2, 1); 253 - 254 - snprintf(buffer2, sizeof(buffer2), "%s" SYSTEM_ROOT "%s", prefix, curPath); 255 293 chdir(buffer2); 256 294 } 257 295 } ··· 288 326 { 289 327 pid_t pid; 290 328 int pipefd[2]; 291 - char idmap[100]; 329 + // char idmap[100]; 292 330 char buffer[1]; 293 331 FILE *file; 294 332 ··· 317 355 // The child 318 356 319 357 char *opts; 358 + char putOld[4096]; 320 359 321 360 // Since overlay cannot be mounted inside user namespaces, we have to setup a new mount namespace 322 361 // and do the mount while we can be root ··· 334 373 exit(1); 335 374 } 336 375 337 - opts = (char*) malloc(strlen(prefix)*2 + sizeof(LIBEXEC_PATH) + 50); 376 + opts = (char*) malloc(strlen(prefix)*2 + sizeof(LIBEXEC_PATH) + 100); 338 377 sprintf(opts, "lowerdir=%s,upperdir=%s,workdir=%s.workdir", LIBEXEC_PATH, prefix, prefix); 339 378 340 379 // Mount overlay onto our prefix ··· 346 385 347 386 free(opts); 348 387 388 + snprintf(putOld, sizeof(putOld), "%s" SYSTEM_ROOT, prefix); 389 + 390 + if (syscall(SYS_pivot_root, prefix, putOld) != 0) 391 + { 392 + fprintf(stderr, "Cannot pivot_root: %s\n", strerror(errno)); 393 + exit(1); 394 + } 395 + 396 + // mount procfs for our new PID namespace 397 + if (mount("proc", "/proc", "proc", 0, "") != 0) 398 + { 399 + fprintf(stderr, "Cannot mount procfs: %s\n", strerror(errno)); 400 + exit(1); 401 + } 402 + 349 403 // Drop the privileges 350 404 setresuid(g_originalUid, g_originalUid, g_originalUid); 351 405 setresgid(g_originalGid, g_originalGid, g_originalGid); ··· 353 407 354 408 prctl(PR_SET_NAME, DARLING_INIT_COMM, 0, 0); 355 409 410 + /* 356 411 if (unshare(CLONE_NEWUSER) != 0) 357 412 { 358 413 fprintf(stderr, "Cannot unshare user namespace: %s\n", strerror(errno)); 359 414 exit(1); 360 415 } 416 + */ 361 417 362 - // Tell the parent we're ready for it to set up UID/GID mappings 418 + // Tell the parent we're ready 363 419 write(pipefd[1], buffer, 1); 364 420 close(pipefd[1]); 365 421 // And wait for it to do it ··· 374 430 read(pipefd[0], buffer, 1); 375 431 close(pipefd[0]); 376 432 433 + /* 377 434 snprintf(idmap, sizeof(idmap), "/proc/%d/uid_map", pid); 378 435 379 436 file = fopen(idmap, "w"); ··· 399 456 { 400 457 fprintf(stderr, "Cannot set gid_map for the init process: %s\n", strerror(errno)); 401 458 } 459 + */ 402 460 403 461 // Resume the child 404 462 write(pipefd[1], buffer, 1); ··· 552 610 553 611 createDir(prefix); 554 612 555 - snprintf(path, sizeof(path), "%s" SYSTEM_ROOT, prefix); 556 - if (symlink("/", path) != 0) 557 - { 558 - fprintf(stderr, "Cannot symlink %s: %s\n", path, strerror(errno)); 559 - exit(1); 560 - } 561 - 562 - snprintf(path, sizeof(path), "%s/dev", prefix); 563 - if (symlink(SYSTEM_ROOT "/dev" + 1, path) != 0) 564 - { 565 - fprintf(stderr, "Cannot symlink %s: %s\n", path, strerror(errno)); 566 - exit(1); 567 - } 568 - 569 - snprintf(path, sizeof(path), "%s/tmp", prefix); 570 - if (symlink(SYSTEM_ROOT "/tmp" + 1, path) != 0) 571 - { 572 - fprintf(stderr, "Cannot symlink %s: %s\n", path, strerror(errno)); 573 - exit(1); 574 - } 575 - 576 - snprintf(path, sizeof(path), "%s/Users", prefix); 577 - if (symlink(SYSTEM_ROOT "/home" + 1, path) != 0) 578 - { 579 - fprintf(stderr, "Cannot symlink %s: %s\n", path, strerror(errno)); 580 - exit(1); 581 - } 582 - 613 + // The user needs to be able to create mountpoints, 583 614 snprintf(path, sizeof(path), "%s/Volumes", prefix); 584 615 createDir(path); 616 + // ... to install applications, 585 617 snprintf(path, sizeof(path), "%s/Applications", prefix); 586 618 createDir(path); 587 619 588 - snprintf(path, sizeof(path), "%s/var", prefix); 620 + // ... and to put stuff in /usr/local 621 + snprintf(path, sizeof(path), "%s/usr", prefix); 589 622 createDir(path); 590 - snprintf(path, sizeof(path), "%s/var/root", prefix); 623 + snprintf(path, sizeof(path), "%s/usr/local", prefix); 591 624 createDir(path); 592 - snprintf(path, sizeof(path), "%s/var/run", prefix); 625 + snprintf(path, sizeof(path), "%s/usr/local/share", prefix); 593 626 createDir(path); 594 - 595 - snprintf(path, sizeof(path), "%s/var/run/syslog", prefix); 596 - if (symlink("../.." SYSTEM_ROOT "/dev/log", path) != 0) 597 - { 598 - fprintf(stderr, "Cannot symlink %s: %s\n", path, strerror(errno)); 599 - exit(1); 600 - } 601 627 602 628 seteuid(0); 603 629 setegid(0);
+2 -3
src/dyld/dirstructure.cpp
··· 33 33 std::stringstream ss; 34 34 std::string path; 35 35 36 - prefix = getenv("DPREFIX"); 37 36 home = getenv("HOME"); 38 - if (!prefix || !home) 37 + if (!home) 39 38 return std::string(); // give up on this user 40 39 41 - ss << prefix << home << '/' << "Library" << '/'; 40 + ss << home << '/' << "Library" << '/'; 42 41 return ss.str(); 43 42 } 44 43
+12 -22
src/dyld/dyld.cpp
··· 32 32 #include <regex> 33 33 #include <fstream> 34 34 #include "dirstructure.h" 35 - #include <libdyld/VirtualPrefix.h> 36 35 #include <sys/personality.h> 37 36 #include <sys/mman.h> 38 37 #include <errno.h> ··· 52 51 printHelp(argv[0]); 53 52 return 1; 54 53 } 55 - 54 + 56 55 if (!HasUserDirectoryStructure()) 57 56 SetupUserDirectoryStructure(); 58 57 59 58 try 60 59 { 61 60 MachOMgr* mgr = MachOMgr::instance(); 62 - std::string executable, unprefixed_argv0; 61 + std::string executable; 63 62 const char* pretendArgv0; 64 - 63 + 65 64 pretendArgv0 = findFakeArgv0(argv[1]); 66 65 67 66 executable = locateBundleExecutable(argv[1]); ··· 89 88 mgr->setSysRoot(path); 90 89 if (const char* path = getenv("DYLD_TRAMPOLINE")) 91 90 mgr->setUseTrampolines(true, path); 92 - if (const char* path = getenv("DPREFIX")) 93 - { 94 - __prefix_set(path); 95 - unprefixed_argv0 = __prefix_untranslate_path(argv[1], strlen(argv[1])); 96 - } 97 - 91 + 98 92 if (getenv("DYLD_GDBJIT") != nullptr) 99 93 Darling::SetupGDBJIT(); 100 94 ··· 115 109 116 110 if (pretendArgv0 != nullptr) 117 111 argv[1] = (char*) pretendArgv0; 118 - else if (!unprefixed_argv0.empty()) 119 - argv[1] = (char*) unprefixed_argv0.c_str(); 120 112 exit(main(argc-1, &argv[1], envp)); 121 113 } 122 114 else 123 115 { 124 116 MachOObject* obj; 125 - 117 + 126 118 if (::mmap(0, 4096, PROT_READ|PROT_EXEC, MAP_FIXED|MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) != 0) 127 119 { 128 120 if (errno == EPERM) ··· 138 130 throw std::runtime_error("This is not a Mach-O executable; dynamic libraries, " 139 131 "kernel extensions and other Mach-O files cannot be executed with dyld"); 140 132 } 141 - 133 + 142 134 if (pretendArgv0 != nullptr) 143 135 argv[1] = (char*) pretendArgv0; 144 - else if (!unprefixed_argv0.empty()) 145 - argv[1] = (char*) unprefixed_argv0.c_str(); 146 - 136 + 147 137 obj->setCommandLine(argc-1, &argv[1], envp); 148 138 149 139 obj->load(); ··· 161 151 { 162 152 char buf[4096]; 163 153 int rd; 164 - 154 + 165 155 rd = readlink("/proc/self/exe", buf, sizeof(buf)-1); 166 156 if (rd <= 0) 167 157 return std::string(); 168 158 buf[rd] = 0; 169 - 159 + 170 160 return std::string(buf); 171 161 } 172 162 ··· 201 191 { 202 192 std::regex re(".*/([^\\.]+)\\.app/?$", std::regex::icase); 203 193 std::smatch match; 204 - 194 + 205 195 std::string myBundlePath = "./" + bundlePath; // TODO: fix the regexp to work without this 206 - 196 + 207 197 if (std::regex_match(myBundlePath, match, re)) 208 198 { 209 199 std::stringstream ss; ··· 245 235 static const char* findFakeArgv0(char* a0) 246 236 { 247 237 char* excl; 248 - 238 + 249 239 excl = strchr(a0, '!'); 250 240 if (excl == nullptr) 251 241 return nullptr;
+19 -22
src/dyld/dyldd.cpp
··· 28 28 #include <unistd.h> 29 29 #include <cstdlib> 30 30 #include <cstring> 31 - #include <libdyld/VirtualPrefix.h> 32 31 33 32 #define ANSI_COLOR_RED "\x1b[31m" 34 33 #define ANSI_COLOR_GREEN "\x1b[32m" ··· 49 48 { 50 49 if (argc != 2 || strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) 51 50 showHelp(argv[0]); 52 - 51 + 53 52 try 54 53 { 55 54 MachOObject* obj; 56 55 std::set<std::string> deps; 57 56 MachOMgr* mgr = MachOMgr::instance(); 58 - 57 + 59 58 mgr->detectSysRootFromPath(argv[1]); 60 - if (const char* path = getenv("DPREFIX")) 61 - __prefix_set(path); 62 - 59 + 63 60 mgr->setLoadAnyArchitecture(true); 64 - 65 - obj = new MachOObject(__prefix_translate_path(argv[1])); 66 - 61 + 62 + obj = new MachOObject(argv[1]); 63 + 67 64 mgr->add(obj, true); 68 - 65 + 69 66 std::cout << c(ANSI_COLOR_GRAY) << "Resolving dependencies of " << obj->path() << "\n\n" << c(ANSI_COLOR_RESET); 70 - 67 + 71 68 resolve(obj, deps); 72 - 69 + 73 70 mgr->remove(obj); 74 71 } 75 72 catch (const std::exception& e) ··· 85 82 { 86 83 LoadableObject* dep; 87 84 std::string dylib = d.name; 88 - 85 + 89 86 if (dylib.empty()) 90 87 continue; 91 - 88 + 92 89 std::string path = DylibSearch::instance()->resolve(dylib, obj); 93 90 if (path.empty()) 94 91 { 95 92 if (deps.find(dylib) == deps.end()) 96 93 { 97 94 deps.insert(dylib); 98 - 95 + 99 96 std::cout << dylib << " => " << c(ANSI_COLOR_RED) << "not found" << c(ANSI_COLOR_RESET) << std::endl; 100 97 } 101 - 98 + 102 99 continue; 103 100 } 104 101 105 102 dep = LoadableObject::instantiateForPath(path, obj); 106 - 103 + 107 104 if (deps.find(dep->path()) != deps.end()) 108 105 { 109 106 dep->delRef(); 110 107 continue; 111 108 } 112 - 109 + 113 110 deps.insert(dep->path()); 114 - 111 + 115 112 if (MachOObject* mach = dynamic_cast<MachOObject*>(dep)) 116 113 { 117 114 std::cout << dylib << " => " << c(ANSI_COLOR_BLUE) << dep->path() << c(ANSI_COLOR_RESET) << std::endl; 118 - 115 + 119 116 resolve(mach, deps); 120 117 } 121 118 else ··· 135 132 std::cerr << "Copyright (C) 2012-2014 Lubos Dolezel\n\n"; 136 133 std::cerr << "Usage: " << argv0 << " executable\n\n"; 137 134 std::cerr << "If your terminal supports colors, then native dependencies are " << c(ANSI_COLOR_GREEN) << "green" << c(ANSI_COLOR_RESET) 138 - << " and Mach-O dependencies are " << c(ANSI_COLOR_BLUE) << "blue" << c(ANSI_COLOR_RESET) << ".\n"; 139 - 135 + << " and Mach-O dependencies are " << c(ANSI_COLOR_BLUE) << "blue" << c(ANSI_COLOR_RESET) << ".\n"; 136 + 140 137 exit(1); 141 138 }
+2 -9
src/kernel/emulation/linux/dirent/getdirentries.c
··· 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 5 #include <sys/dirent.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 extern __SIZE_TYPE__ strlen(const char* s); 9 8 extern char* strcpy(char* dest, const char* src); ··· 51 50 bsd->d_ino = l64->d_ino; 52 51 bsd->d_type = l64->d_type; 53 52 strcpy(bsd->d_name, l64->d_name); 54 - 55 - if (strcmp(l64->d_name, __SYSTEM_ROOT+1) == 0) 56 - bsd->d_type = DT_DIR; 57 - 53 + 58 54 bsd->d_reclen = sizeof(struct bsd_dirent) + slen + 1; 59 55 bsd->d_namlen = slen; 60 56 ··· 97 93 bsd->d_ino = l64->d_ino; 98 94 bsd->d_type = l64->d_type; 99 95 strcpy(bsd->d_name, l64->d_name); 100 - 101 - if (strcmp(l64->d_name, __SYSTEM_ROOT+1) == 0) 102 - bsd->d_type = DT_DIR; 103 - 96 + 104 97 bsd->d_reclen = sizeof(struct bsd_dirent64) + slen + 1; 105 98 bsd->d_namlen = slen; 106 99 bsd->d_seekoff = 0;
+1 -3
src/kernel/emulation/linux/fcntl/open.c
··· 4 4 #include <asm/unistd.h> 5 5 //#include "../../../../platform-include/sys/fcntl.h" 6 6 #include "../../../../libc/include/fcntl.h" 7 - #include <libdyld/VirtualPrefix.h> 8 7 9 8 #ifndef O_NOFOLLOW 10 9 # define O_NOFOLLOW 0x0100 ··· 40 39 if (strcmp(filename, "/dev/random") == 0) 41 40 filename = "/dev/urandom"; 42 41 43 - ret = LINUX_SYSCALL(__NR_open, __prefix_translate_path(filename), 44 - linux_flags, mode); 42 + ret = LINUX_SYSCALL(__NR_open, filename, linux_flags, mode); 45 43 if (ret < 0) 46 44 ret = errno_linux_to_bsd(ret); 47 45
+6 -8
src/kernel/emulation/linux/misc/sysctl.c
··· 7 7 #include <mach/machine.h> 8 8 #include <mach/mach_init.h> 9 9 #include "../../../../../platform-include/sys/errno.h" 10 - #include "../../../../libdyld/VirtualPrefix.h" 11 10 #include "sysctl_inc.h" 12 11 #include <stddef.h> 13 12 #include <limits.h> ··· 58 57 { 59 58 return sysctl_name_to_oid((const char*) _new, (int*) old, oldlen); 60 59 } 61 - 60 + 62 61 if (name[0] == CTL_HW) 63 62 { 64 63 int* ovalue = (int*) old; ··· 89 88 if (*oldlen < sizeof(int)) 90 89 return -EINVAL; 91 90 *oldlen = sizeof(int); 92 - 91 + 93 92 switch (name[1]) 94 93 { 95 94 case HW_AVAILCPU: ··· 257 256 if (!lu.sysname[0]) 258 257 { 259 258 __linux_uname(&lu); 260 - version_conf = iniconfig_load(__prefix_translate_path(ETC_DARLING_PATH "/version.conf")); 259 + version_conf = iniconfig_load(ETC_DARLING_PATH "/version.conf"); 261 260 if (version_conf != NULL) 262 261 version_conf_sect = iniconfig_getsection(version_conf, "uname"); 263 262 } ··· 278 277 { 279 278 const char* dot; 280 279 unsigned long cat_len; 281 - 280 + 282 281 if (*oid_len < 2) 283 282 return -EINVAL; 284 283 ··· 292 291 { 293 292 oid_name[0] = CTL_HW; 294 293 *oid_len = 2 * sizeof(int); 295 - 294 + 296 295 if (strcmp(dot+1, "activecpu") == 0) 297 296 oid_name[1] = HW_AVAILCPU; 298 297 else if (strcmp(dot+1, "ncpu") == 0) ··· 317 316 oid_name[1] = _HW_CPUTHREADTYPE; 318 317 else 319 318 return -ENOTDIR; 320 - 319 + 321 320 return 0; 322 321 } 323 322 else if (strncmp(name, "kern", cat_len) == 0) ··· 336 335 __simple_printf("Unknown sysctl: %s\n", name); 337 336 return -ENOTDIR; 338 337 } 339 -
+10 -106
src/kernel/emulation/linux/process/execve.c
··· 9 9 #include <stdint.h> 10 10 #include <stddef.h> 11 11 #include <stdbool.h> 12 - #include <libdyld/VirtualPrefix.h> 13 12 14 13 #define MH_MAGIC 0xfeedface 15 14 #define MH_CIGAM 0xcefaedfe ··· 40 39 uint32_t magic; 41 40 char magic_array[256]; 42 41 } m; 43 - 42 + 44 43 // Ideally, if everybody used binfmt_misc to allow direct 45 44 // execution of Mach-O binaries under Darling, this wouldn't 46 45 // be necessary. But we cannot rely on that. 47 - 46 + 48 47 fd = sys_open(fname, BSD_O_RDONLY, 0); 49 48 if (fd < 0) 50 49 return fd; ··· 52 51 ret = sys_read(fd, m.magic_array, sizeof(m.magic_array)); 53 52 if (ret < 4) 54 53 goto no_macho; 55 - 56 - if (__prefix_get() != NULL) 57 - { 58 - // Inject DPREFIX if DPREFIX is missing 59 - int i; 60 - bool has_dprefix = false; 61 - char** new_envp; 62 - 63 - for (i = 0; envp[i] != NULL; i++) 64 - { 65 - if (strncmp(envp[i], "DPREFIX=", 8) == 0) 66 - { 67 - has_dprefix = true; 68 - break; 69 - } 70 - } 71 - 72 - if (!has_dprefix) 73 - { 74 - char* dprefix; 75 - 76 - new_envp = (char**) __builtin_alloca(sizeof(char*) * (i+1)); 77 - dprefix = (char*) __builtin_alloca(strlen(__prefix_get()) + 9); 78 - 79 - for (i = 0; envp[i] != NULL; i++) 80 - new_envp[i] = envp[i]; 81 - 82 - strcpy(dprefix, "DPREFIX="); 83 - strcat(dprefix, __prefix_get()); 84 - new_envp[i++] = dprefix; 85 - new_envp[i] = NULL; 86 - 87 - envp = new_envp; 88 - } 89 - } 90 54 91 55 if (m.magic == MH_MAGIC || m.magic == MH_CIGAM 92 56 || m.magic == MH_MAGIC_64 || m.magic == MH_CIGAM_64 ··· 95 59 // It is a Mach-O file 96 60 int len, i; 97 61 char** modargvp; 98 - char *translated, *buf; 99 - 100 - len = __prefix_get_dyld_path(dyld_path, sizeof(dyld_path)-1); 62 + char *buf; 63 + 64 + len = LINUX_SYSCALL(__NR_readlink, "/proc/self/exe", dyld_path, sizeof(dyld_path)-1); 101 65 if (len < 0) 102 66 goto no_macho; 67 + dyld_path[len] = '\0'; 103 68 104 69 // Remove 64 or 32 suffix if present 105 70 if (strcmp(&dyld_path[len - 2], "32") == 0 ··· 117 82 // Allocate a new argvp, execute dyld_path 118 83 modargvp = (char**) __builtin_alloca(sizeof(void*) * (len+1)); 119 84 modargvp[0] = dyld_path; 120 - 121 - translated = (char*) __prefix_translate_path_link(fname); 122 - buf = __builtin_alloca(strlen(translated) + 2 + strlen(argvp[0])); 123 - 124 - strcpy(buf, translated); 85 + 86 + buf = __builtin_alloca(strlen(fname) + 2 + strlen(argvp[0])); 87 + 88 + strcpy(buf, fname); 125 89 strcat(buf, "!"); 126 90 strcat(buf, argvp[0]); 127 91 modargvp[1] = buf; ··· 132 96 argvp = modargvp; 133 97 fname = dyld_path; 134 98 } 135 - else if (__prefix_get() != NULL) 136 - { 137 - // shebang handling... 138 - if (m.magic_array[0] == '#' && m.magic_array[1] == '!') 139 - { 140 - char *nl, *interp, *arg; 141 - char** modargvp; 142 - int i, j, len = 0; 143 - 144 - nl = memchr(m.magic_array, '\n', sizeof(m.magic_array)); 145 - if (nl == NULL) 146 - goto no_macho; 147 - 148 - *nl = '\0'; 149 - 150 - for (i = 2; isspace(m.magic_array[i]); i++); 151 - 152 - interp = &m.magic_array[i]; 153 - 154 - for (i = 0; !isspace(interp[i]) && interp[i]; i++); 155 - 156 - if (interp[i] == '\0') 157 - arg = NULL; 158 - else 159 - arg = &interp[i]; 160 - 161 - if (arg != NULL) 162 - { 163 - *arg = '\0'; // terminate interp 164 - while (isspace(*arg)) 165 - arg++; 166 - if (*arg == '\0') 167 - arg = NULL; // no argument, just whitespace 168 - } 169 - 170 - // Count original arguments 171 - while (argvp[len++]); 172 - 173 - // Allocate a new argvp 174 - modargvp = (char**) __builtin_alloca(sizeof(void*) * (len+2)); 175 - 176 - i = 0; 177 - modargvp[i++] = interp; 178 - if (arg != NULL) 179 - modargvp[i++] = arg; 180 - modargvp[i] = fname; 181 - 182 - // Append original arguments 183 - for (j = 1; j < len+1; j++) 184 - modargvp[i+j] = argvp[j]; 185 - 186 - argvp = modargvp; 187 - fname = (char*) __prefix_translate_path(modargvp[0]); 188 - } 189 - else 190 - { 191 - fname = (char*) __prefix_translate_path(fname); 192 - } 193 - } 194 99 195 100 no_macho: 196 101 sys_close(fd); ··· 201 106 202 107 return ret; 203 108 } 204 -
+4 -10
src/kernel/emulation/linux/stat/lstat.c
··· 3 3 #include "../base.h" 4 4 #include "../errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 long sys_lstat(const char* path, struct stat* stat) 9 8 { ··· 11 10 struct linux_stat lstat; 12 11 13 12 #ifdef __NR_lstat64 14 - ret = LINUX_SYSCALL(__NR_lstat64, __prefix_translate_path_link(path), &lstat); 13 + ret = LINUX_SYSCALL(__NR_lstat64, path, &lstat); 15 14 #else 16 - ret = LINUX_SYSCALL(__NR_lstat, __prefix_translate_path_link(path), &lstat); 15 + ret = LINUX_SYSCALL(__NR_lstat, path, &lstat); 17 16 #endif 18 17 19 18 if (ret < 0) 20 19 return errno_linux_to_bsd(ret); 21 - else if (__prefix_is_system_root(path)) 22 - lstat.st_mode = (lstat.st_mode & ~0120000) | 0040000; // make directory 23 20 24 21 stat_linux_to_bsd(&lstat, stat); 25 22 ··· 32 29 struct linux_stat lstat; 33 30 34 31 #ifdef __NR_lstat64 35 - ret = LINUX_SYSCALL(__NR_lstat64, __prefix_translate_path_link(path), &lstat); 32 + ret = LINUX_SYSCALL(__NR_lstat64, path, &lstat); 36 33 #else 37 - ret = LINUX_SYSCALL(__NR_lstat, __prefix_translate_path_link(path), &lstat); 34 + ret = LINUX_SYSCALL(__NR_lstat, path, &lstat); 38 35 #endif 39 36 40 37 if (ret < 0) 41 38 return errno_linux_to_bsd(ret); 42 - else if (__prefix_is_system_root(path)) 43 - lstat.st_mode = (lstat.st_mode & ~0120000) | 0040000; // make directory 44 39 45 40 stat_linux_to_bsd64(&lstat, stat); 46 41 47 42 return 0; 48 43 } 49 -
+1 -3
src/kernel/emulation/linux/stat/mkdir.c
··· 3 3 #include "../base.h" 4 4 #include "../errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 long sys_mkdir(const char* path, unsigned int mode) 9 8 { 10 9 int ret; 11 10 12 - ret = LINUX_SYSCALL(__NR_mkdir, __prefix_translate_path(path), mode); 11 + ret = LINUX_SYSCALL(__NR_mkdir, path, mode); 13 12 14 13 if (ret < 0) 15 14 return errno_linux_to_bsd(ret); 16 15 17 16 return 0; 18 17 } 19 -
+1 -4
src/kernel/emulation/linux/stat/mkfifo.c
··· 3 3 #include "../base.h" 4 4 #include "../errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 #define LINUX_S_IFIFO 0010000 9 8 ··· 11 10 { 12 11 int ret; 13 12 14 - ret = LINUX_SYSCALL(__NR_mknod, __prefix_translate_path(path), 15 - mode | LINUX_S_IFIFO, 0); 13 + ret = LINUX_SYSCALL(__NR_mknod, path, mode | LINUX_S_IFIFO, 0); 16 14 17 15 if (ret < 0) 18 16 return errno_linux_to_bsd(ret); 19 17 20 18 return 0; 21 19 } 22 -
+1 -3
src/kernel/emulation/linux/stat/rmdir.c
··· 3 3 #include "../base.h" 4 4 #include "../errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 long sys_rmdir(const char* path) 9 8 { 10 9 int ret; 11 10 12 - ret = LINUX_SYSCALL(__NR_rmdir, __prefix_translate_path(path)); 11 + ret = LINUX_SYSCALL(__NR_rmdir, path); 13 12 14 13 if (ret < 0) 15 14 return errno_linux_to_bsd(ret); 16 15 17 16 return 0; 18 17 } 19 -
+4 -10
src/kernel/emulation/linux/stat/stat.c
··· 3 3 #include "../base.h" 4 4 #include "../errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 long sys_stat(const char* path, struct stat* stat) 9 8 { ··· 11 10 struct linux_stat lstat; 12 11 13 12 #ifdef __NR_stat64 14 - ret = LINUX_SYSCALL(__NR_stat64, __prefix_translate_path(path), &lstat); 13 + ret = LINUX_SYSCALL(__NR_stat64, path, &lstat); 15 14 #else 16 - ret = LINUX_SYSCALL(__NR_stat, __prefix_translate_path(path), &lstat); 15 + ret = LINUX_SYSCALL(__NR_stat, path, &lstat); 17 16 #endif 18 17 19 18 if (ret < 0) 20 19 return errno_linux_to_bsd(ret); 21 - else if (__prefix_is_system_root(path)) 22 - lstat.st_mode = (lstat.st_mode & ~0120000) | 0040000; // make directory 23 20 24 21 stat_linux_to_bsd(&lstat, stat); 25 22 ··· 32 29 struct linux_stat lstat; 33 30 34 31 #ifdef __NR_stat64 35 - ret = LINUX_SYSCALL(__NR_stat64, __prefix_translate_path(path), &lstat); 32 + ret = LINUX_SYSCALL(__NR_stat64, path, &lstat); 36 33 #else 37 - ret = LINUX_SYSCALL(__NR_stat, __prefix_translate_path(path), &lstat); 34 + ret = LINUX_SYSCALL(__NR_stat, path, &lstat); 38 35 #endif 39 36 40 37 if (ret < 0) 41 38 return errno_linux_to_bsd(ret); 42 - else if (__prefix_is_system_root(path)) 43 - lstat.st_mode = (lstat.st_mode & ~0120000) | 0040000; // make directory 44 39 45 40 stat_linux_to_bsd64(&lstat, stat); 46 41 47 42 return 0; 48 43 } 49 -
+1 -3
src/kernel/emulation/linux/time/utimes.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_utimes(const char* path, struct bsd_timeval* tv) 8 7 { ··· 14 13 ltv[1].tv_sec = tv[1].tv_sec; 15 14 ltv[1].tv_usec = tv[1].tv_usec; 16 15 17 - ret = LINUX_SYSCALL(__NR_utimes, __prefix_translate_path(path), ltv); 16 + ret = LINUX_SYSCALL(__NR_utimes, path, ltv); 18 17 if (ret < 0) 19 18 ret = errno_linux_to_bsd(ret); 20 19 21 20 return ret; 22 21 } 23 -
+2 -5
src/kernel/emulation/linux/unistd/access.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_access(const char* filename, int amode) 8 7 { 9 8 int ret; 10 9 11 10 #ifdef __NR_access 12 - ret = LINUX_SYSCALL(__NR_access, __prefix_translate_path(filename), amode); 11 + ret = LINUX_SYSCALL(__NR_access, filename, amode); 13 12 #else 14 - ret = LINUX_SYSCALL(__NR_faccessat, LINUX_AT_FDCWD, 15 - __prefix_translate_path(filename), amode, 0); 13 + ret = LINUX_SYSCALL(__NR_faccessat, LINUX_AT_FDCWD, filename, amode, 0); 16 14 #endif 17 15 18 16 if (ret < 0) ··· 20 18 21 19 return ret; 22 20 } 23 -
+1 -8
src/kernel/emulation/linux/unistd/chdir.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 - long sys_chdir(const char* in_path) 6 + long sys_chdir(const char* path) 8 7 { 9 8 int ret; 10 - const char* path; 11 - 12 - path = __prefix_translate_path(in_path); 13 9 ret = LINUX_SYSCALL(__NR_chdir, path); 14 10 if (ret < 0) 15 11 ret = errno_linux_to_bsd(ret); 16 - else 17 - __prefix_cwd(in_path); 18 12 19 13 return ret; 20 14 } 21 -
+1 -3
src/kernel/emulation/linux/unistd/chmod.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_chmod(const char* path, int mode) 8 7 { 9 8 int ret; 10 9 11 - ret = LINUX_SYSCALL(__NR_chmod, __prefix_translate_path(path), mode); 10 + ret = LINUX_SYSCALL(__NR_chmod, path, mode); 12 11 if (ret < 0) 13 12 ret = errno_linux_to_bsd(ret); 14 13 15 14 return ret; 16 15 } 17 -
+4 -9
src/kernel/emulation/linux/unistd/chmod_extended.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_chmod_extended(const char* path, int uid, int gid, int mode, void* xsec) 8 7 { 9 8 int ret; 10 - const char* xpath; 11 - 12 - xpath = __prefix_translate_path(path); 13 9 14 - ret = LINUX_SYSCALL(__NR_chmod, xpath, mode); 10 + ret = LINUX_SYSCALL(__NR_chmod, path, mode); 15 11 if (ret < 0) 16 12 return errno_linux_to_bsd(ret); 17 - 18 - ret = LINUX_SYSCALL(__NR_chown, xpath, uid, gid); 13 + 14 + ret = LINUX_SYSCALL(__NR_chown, path, uid, gid); 19 15 if (ret < 0) 20 16 return errno_linux_to_bsd(ret); 21 - 17 + 22 18 return ret; 23 19 } 24 -
+2 -4
src/kernel/emulation/linux/unistd/chown.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_chown(const char* path, int uid, int gid) 8 7 { 9 8 int ret; 10 9 11 10 #ifdef __NR_chown32 12 - ret = LINUX_SYSCALL(__NR_chown32, __prefix_translate_path(path), uid, gid); 11 + ret = LINUX_SYSCALL(__NR_chown32, path, uid, gid); 13 12 #else 14 - ret = LINUX_SYSCALL(__NR_chown, __prefix_translate_path(path), uid, gid); 13 + ret = LINUX_SYSCALL(__NR_chown, path, uid, gid); 15 14 #endif 16 15 if (ret < 0) 17 16 ret = errno_linux_to_bsd(ret); 18 17 19 18 return ret; 20 19 } 21 -
+1 -5
src/kernel/emulation/linux/unistd/chroot.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_chroot(const char* path) 8 7 { 9 8 int ret; 10 9 11 - // TODO: should we support chroot with virtual prefixes? 12 - 13 - ret = LINUX_SYSCALL(__NR_chroot, __prefix_translate_path(path)); 10 + ret = LINUX_SYSCALL(__NR_chroot, path); 14 11 if (ret < 0) 15 12 ret = errno_linux_to_bsd(ret); 16 13 17 14 return ret; 18 15 } 19 -
-4
src/kernel/emulation/linux/unistd/fchdir.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_fchdir(int fd) 8 7 { ··· 11 10 ret = LINUX_SYSCALL1(__NR_fchdir, fd); 12 11 if (ret < 0) 13 12 ret = errno_linux_to_bsd(ret); 14 - else 15 - __prefix_cwd_fd(fd); 16 13 17 14 return ret; 18 15 } 19 -
+2 -4
src/kernel/emulation/linux/unistd/lchown.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_lchown(const char* path, int uid, int gid) 8 7 { 9 8 int ret; 10 9 11 10 #ifdef __NR_chown32 12 - ret = LINUX_SYSCALL(__NR_lchown32, __prefix_translate_path_link(path), uid, gid); 11 + ret = LINUX_SYSCALL(__NR_lchown32, path, uid, gid); 13 12 #else 14 - ret = LINUX_SYSCALL(__NR_lchown, __prefix_translate_path_link(path), uid, gid); 13 + ret = LINUX_SYSCALL(__NR_lchown, path, uid, gid); 15 14 #endif 16 15 if (ret < 0) 17 16 ret = errno_linux_to_bsd(ret); 18 17 19 18 return ret; 20 19 } 21 -
+1 -11
src/kernel/emulation/linux/unistd/link.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 #include "../../../../../platform-include/sys/errno.h" 7 6 8 7 extern char* strcpy(char* dst, const char* src); ··· 10 9 long sys_link(const char* path, const char* link) 11 10 { 12 11 int ret; 13 - char resolved_path[1024]; 14 - char resolved_link[1024]; 15 - 16 - if (!path || !link) 17 - return -EINVAL; 18 12 19 - strcpy(resolved_path, __prefix_translate_path(path)); 20 - strcpy(resolved_link, __prefix_translate_path(link)); 21 - 22 - ret = LINUX_SYSCALL(__NR_link, resolved_path, resolved_link); 13 + ret = LINUX_SYSCALL(__NR_link, path, link); 23 14 if (ret < 0) 24 15 ret = errno_linux_to_bsd(ret); 25 16 26 17 return ret; 27 18 } 28 -
+1 -3
src/kernel/emulation/linux/unistd/mknod.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_mknod(const char* path, int mode, int dev) 8 7 { 9 8 int ret; 10 9 11 - ret = LINUX_SYSCALL(__NR_mknod, __prefix_translate_path(path), mode, dev); 10 + ret = LINUX_SYSCALL(__NR_mknod, path, mode, dev); 12 11 if (ret < 0) 13 12 ret = errno_linux_to_bsd(ret); 14 13 15 14 return ret; 16 15 } 17 -
+1 -15
src/kernel/emulation/linux/unistd/readlink.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 extern __SIZE_TYPE__ strlen(const char* str); 8 7 ··· 10 9 { 11 10 int ret; 12 11 13 - ret = LINUX_SYSCALL(__NR_readlink, __prefix_translate_path_link(path), 14 - buf, count); 12 + ret = LINUX_SYSCALL(__NR_readlink, path, buf, count); 15 13 if (ret < 0) 16 14 ret = errno_linux_to_bsd(ret); 17 - /*else 18 - { 19 - const char* xl; 20 - __SIZE_TYPE__ newlen; 21 - 22 - xl = __prefix_untranslate_path(buf, ret); 23 - newlen = strlen(xl); 24 - 25 - memcpy(buf, xl, (newlen < count) ? newlen : count); 26 - ret = newlen; 27 - }*/ 28 15 29 16 return ret; 30 17 } 31 -
+1 -11
src/kernel/emulation/linux/unistd/rename.c
··· 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 5 #include "../../../../../platform-include/sys/errno.h" 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 extern char* strcpy(char* dst, const char* src); 9 8 10 9 long sys_rename(const char* oldpath, const char* newpath) 11 10 { 12 11 int ret; 13 - char resolved_oldpath[1024]; 14 - char resolved_newpath[1024]; 15 - 16 - if (!oldpath || !newpath) 17 - return -EINVAL; 18 12 19 - strcpy(resolved_oldpath, __prefix_translate_path(oldpath)); 20 - strcpy(resolved_newpath, __prefix_translate_path(newpath)); 21 - 22 - ret = LINUX_SYSCALL(__NR_rename, resolved_oldpath, resolved_newpath); 13 + ret = LINUX_SYSCALL(__NR_rename, oldpath, newpath); 23 14 24 15 if (ret < 0) 25 16 return errno_linux_to_bsd(ret); 26 17 27 18 return 0; 28 19 } 29 -
+1 -11
src/kernel/emulation/linux/unistd/symlink.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 #include "../../../../../platform-include/sys/errno.h" 7 6 8 7 extern char* strcpy(char* dst, const char* src); ··· 10 9 long sys_symlink(const char* path, const char* link) 11 10 { 12 11 int ret; 13 - //char resolved_path[1024]; 14 - char resolved_link[1024]; 15 - 16 - if (!path || !link) 17 - return -EINVAL; 18 - 19 - //strcpy(resolved_path, __prefix_translate_path(path)); 20 - strcpy(resolved_link, __prefix_translate_path_link(link)); 21 12 22 - ret = LINUX_SYSCALL(__NR_symlink, path, resolved_link); 13 + ret = LINUX_SYSCALL(__NR_symlink, path, link); 23 14 if (ret < 0) 24 15 ret = errno_linux_to_bsd(ret); 25 16 26 17 return ret; 27 18 } 28 -
+2 -6
src/kernel/emulation/linux/unistd/truncate.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_truncate(const char* path, long long length) 8 7 { 9 8 int ret; 10 9 11 10 #ifdef __NR_truncate64 12 - ret = LINUX_SYSCALL(__NR_truncate64, __prefix_translate_path(path), 13 - LL_ARG(length)); 11 + ret = LINUX_SYSCALL(__NR_truncate64, path, LL_ARG(length)); 14 12 #else 15 - ret = LINUX_SYSCALL(__NR_truncate, __prefix_translate_path(path), 16 - LL_ARG(length)); 13 + ret = LINUX_SYSCALL(__NR_truncate, path, LL_ARG(length)); 17 14 #endif 18 15 if (ret < 0) 19 16 ret = errno_linux_to_bsd(ret); 20 17 21 18 return ret; 22 19 } 23 -
+1 -3
src/kernel/emulation/linux/unistd/unlink.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 long sys_unlink(const char* path) 8 7 { 9 8 int ret; 10 9 11 - ret = LINUX_SYSCALL(__NR_unlink, __prefix_translate_path_link(path)); 10 + ret = LINUX_SYSCALL(__NR_unlink, path); 12 11 if (ret < 0) 13 12 ret = errno_linux_to_bsd(ret); 14 13 15 14 return ret; 16 15 } 17 -
+3 -7
src/kernel/emulation/linux/xattr/getxattr.c
··· 3 3 #include "../errno.h" 4 4 #include "../../../../../platform-include/sys/errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 #define XATTR_NOFOLLOW 1 9 8 ··· 11 10 unsigned long size, unsigned int pos, int options) 12 11 { 13 12 int ret; 14 - 13 + 15 14 if (pos != 0) 16 15 return -ERANGE; 17 16 18 17 if (options & XATTR_NOFOLLOW) 19 - ret = LINUX_SYSCALL(__NR_lgetxattr, __prefix_translate_path(path), 20 - name, value, size); 18 + ret = LINUX_SYSCALL(__NR_lgetxattr, path, name, value, size); 21 19 else 22 - ret = LINUX_SYSCALL(__NR_getxattr, __prefix_translate_path(path), 23 - name, value, size); 20 + ret = LINUX_SYSCALL(__NR_getxattr, path, name, value, size); 24 21 25 22 if (ret < 0) 26 23 return errno_linux_to_bsd(ret); 27 24 28 25 return 0; 29 26 } 30 -
+2 -6
src/kernel/emulation/linux/xattr/listxattr.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 #define XATTR_NOFOLLOW 1 8 7 ··· 11 10 int ret; 12 11 13 12 if (options & XATTR_NOFOLLOW) 14 - ret = LINUX_SYSCALL(__NR_llistxattr, __prefix_translate_path(path), 15 - namebuf, size); 13 + ret = LINUX_SYSCALL(__NR_llistxattr, path, namebuf, size); 16 14 else 17 - ret = LINUX_SYSCALL(__NR_listxattr, __prefix_translate_path(path), 18 - namebuf, size); 15 + ret = LINUX_SYSCALL(__NR_listxattr, path, namebuf, size); 19 16 20 17 if (ret < 0) 21 18 return errno_linux_to_bsd(ret); 22 19 23 20 return ret; 24 21 } 25 -
+2 -6
src/kernel/emulation/linux/xattr/removexattr.c
··· 2 2 #include "../base.h" 3 3 #include "../errno.h" 4 4 #include <asm/unistd.h> 5 - #include <libdyld/VirtualPrefix.h> 6 5 7 6 #define XATTR_NOFOLLOW 1 8 7 ··· 11 10 int ret; 12 11 13 12 if (options & XATTR_NOFOLLOW) 14 - ret = LINUX_SYSCALL(__NR_lremovexattr, __prefix_translate_path(path), 15 - name); 13 + ret = LINUX_SYSCALL(__NR_lremovexattr, path, name); 16 14 else 17 - ret = LINUX_SYSCALL(__NR_removexattr, __prefix_translate_path(path), 18 - name); 15 + ret = LINUX_SYSCALL(__NR_removexattr, path, name); 19 16 20 17 if (ret < 0) 21 18 return errno_linux_to_bsd(ret); 22 19 23 20 return ret; 24 21 } 25 -
+2 -6
src/kernel/emulation/linux/xattr/setxattr.c
··· 3 3 #include "../errno.h" 4 4 #include "../../../../../platform-include/sys/errno.h" 5 5 #include <asm/unistd.h> 6 - #include <libdyld/VirtualPrefix.h> 7 6 8 7 #define XATTR_NOFOLLOW 1 9 8 ··· 17 16 18 17 if (options & XATTR_NOFOLLOW) 19 18 { 20 - ret = LINUX_SYSCALL(__NR_lsetxattr, __prefix_translate_path(path), 21 - name, value, size); 19 + ret = LINUX_SYSCALL(__NR_lsetxattr, path, name, value, size); 22 20 } 23 21 else 24 22 { 25 - ret = LINUX_SYSCALL(__NR_setxattr, __prefix_translate_path(path), 26 - name, value, size); 23 + ret = LINUX_SYSCALL(__NR_setxattr, path, name, value, size); 27 24 } 28 25 29 26 if (ret < 0) ··· 31 28 32 29 return ret; 33 30 } 34 -
+2 -5
src/libdyld/CMakeLists.txt
··· 31 31 dyld_priv.cpp 32 32 dl_public.cpp 33 33 binfmt_misc.cpp 34 - 34 + 35 35 MachOObject.cpp 36 36 LoadableObject.cpp 37 37 NativeObject.cpp ··· 39 39 DylibSearch.cpp 40 40 environ.c 41 41 threads.cpp 42 - VirtualPrefix.cpp 43 42 gdbjit.cpp 44 43 ) 45 44 ··· 63 62 64 63 SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/darling") 65 64 #SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--enable-new-dtags") 66 - SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 65 + SET(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 67 66 SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 68 67 69 68 set_source_files_properties(environ.c COMPILE_FLAGS "-no-integrated-as") ··· 72 71 target_link_libraries(dyld PRIVATE -ldl -lpthread mach-o darling-util) 73 72 74 73 install(TARGETS dyld DESTINATION ${CMAKE_INSTALL_LIBDIR}/darling) 75 - 76 -
+36 -57
src/libdyld/DylibSearch.cpp
··· 23 23 #include <iostream> 24 24 #include "MachOObject.h" 25 25 #include "MachOMgr.h" 26 - #include "VirtualPrefix.h" 27 26 //#include "DummyObject.h" 28 27 #include <regex.h> 29 28 #include <unistd.h> ··· 39 38 { 40 39 try 41 40 { 42 - if (__prefix_get() != nullptr) 43 - m_config = new IniConfig(__prefix_translate_path(ETC_DARLING_PATH "/dylib.conf")); 44 - else 45 - m_config = new IniConfig(LIBEXEC_PATH ETC_DARLING_PATH "/dylib.conf"); 41 + m_config = new IniConfig(ETC_DARLING_PATH "/dylib.conf"); 46 42 } 47 43 catch (const std::exception& e) 48 44 { ··· 85 81 if (dylib.compare(0, 16, "@executable_path") == 0) 86 82 { 87 83 MachOObject* mainModule = MachOMgr::instance()->mainModule(); 88 - 84 + 89 85 if (!mainModule) 90 86 throw std::runtime_error("Cannot resolve @executable_path without a main module"); 91 - 87 + 92 88 dylib.replace(0, 16, mainModule->directory()); 93 89 } 94 90 else if (dylib.compare(0, 12, "@loader_path") == 0) ··· 100 96 return resolveViaRpath(dylib, requester); 101 97 } 102 98 } 103 - 99 + 104 100 // Search in configuration 105 101 if (const char* aliasTarget = resolveAlias(dylib)) 106 102 { 107 103 std::string p; 108 - 104 + 109 105 if (!strchr(aliasTarget, '/')) 110 106 { 111 - p = LIB_PATH; 107 + p = SYSTEM_ROOT LIB_PATH; 112 108 p += '/'; 113 109 p += aliasTarget; 114 110 // std::cout << p << std::endl; 115 111 } 116 - 112 + 117 113 return p; 118 114 } 119 - 115 + 120 116 // Search in extra paths 121 117 std::string epath; 122 118 epath = resolveInPathList(dylib, m_extraPaths); 123 119 if (!epath.empty()) 124 120 return epath; 125 - 121 + 126 122 // Search in DYLD_LIBRARY_PATH 127 123 epath = resolveInLdPath(dylib); 128 124 if (!epath.empty()) 129 125 return epath; 130 - 126 + 131 127 // Try the path as is 132 128 epath = checkPresence(dylib); 133 129 if (!epath.empty()) ··· 136 132 // If absolute, search in sysroot 137 133 if (dylib[0] == '/') 138 134 { 139 - const char* prefix = __prefix_get(); 140 - 135 + 141 136 if (!MachOMgr::instance()->sysRoot().empty()) 142 137 { 143 138 std::vector<std::string> roots = string_explode(MachOMgr::instance()->sysRoot(), ':'); ··· 145 140 for (const std::string& in_path : roots) 146 141 { 147 142 std::string path; 148 - 149 - if (prefix != nullptr) 150 - path = prefix; 151 - 143 + 152 144 path += in_path; 153 145 path += '/'; 154 146 path += dylib; ··· 158 150 return epath; 159 151 } 160 152 } 161 - if (prefix != nullptr) 162 - { 163 - std::string path = prefix; 164 - path += dylib; 165 - 166 - epath = checkPresence(path); 167 - if (!epath.empty()) 168 - return epath; 169 - } 170 153 } 171 - 154 + 172 155 /*if (MachOMgr::instance()->ignoreMissingDependencies()) 173 156 { 174 - 157 + 175 158 }*/ 176 159 177 160 return std::string(); ··· 180 163 std::string DylibSearch::checkPresence(const std::string& path) 181 164 { 182 165 std::string str = path; 183 - 166 + 184 167 if (::access(str.c_str(), F_OK) == 0) 185 168 return str; 186 - 169 + 187 170 str += ".dylib"; 188 - 171 + 189 172 if (::access(str.c_str(), F_OK) == 0) 190 173 return str; 191 - 174 + 192 175 for (const std::string& suffix : m_suffixes) 193 176 { 194 177 str = path + suffix; 195 - 178 + 196 179 if (::access(str.c_str(), F_OK) == 0) 197 180 return str; 198 181 } 199 - 182 + 200 183 return std::string(); 201 184 } 202 185 ··· 209 192 return std::string(); 210 193 211 194 elems = string_explode(name, ':'); 212 - 195 + 213 196 return resolveInPathList(name, elems); 214 197 } 215 198 216 199 std::string DylibSearch::resolveInPathList(std::string name, const std::vector<std::string>& paths) 217 200 { 218 - const char* prefix = __prefix_get(); 219 201 for (const std::string& e : paths) 220 202 { 221 203 std::string path; 222 - 223 - if (prefix) 224 - path = prefix; 225 - 204 + 226 205 path += e + "/" + name; 227 206 228 207 if (::access(path.c_str(), F_OK) == 0) ··· 249 228 if (std::regex_match(library, match, m_reFrameworkPath)) 250 229 { 251 230 std::string name, version; 252 - 231 + 253 232 name = match[1]; 254 233 version = match[2]; 255 - 234 + 256 235 if (m_config->hasSection(name)) 257 236 { 258 237 const IniConfig::ValueMap* m = m_config->getSection(name); 259 238 auto it = m->find(version); 260 - 239 + 261 240 if (it != m->end()) 262 241 return it->second.c_str(); 263 242 } 264 243 } 265 - 244 + 266 245 if (std::regex_match(library, match, m_reDefaultFrameworkPath)) 267 246 { 268 247 std::string name; 269 - 248 + 270 249 name = match[1]; 271 - 250 + 272 251 if (m_config->hasSection(name)) 273 252 { 274 253 const IniConfig::ValueMap* m = m_config->getSection(name); 275 254 auto it = m->find("default"); 276 - 255 + 277 256 if (it != m->end()) 278 257 return it->second.c_str(); 279 258 else 280 259 return m->begin()->second.c_str(); 281 260 } 282 261 } 283 - 262 + 284 263 return nullptr; 285 264 } 286 265 ··· 301 280 { 302 281 std::string expanded = name; 303 282 std::string result; 304 - 283 + 305 284 expanded.replace(0, 6, rpath); 306 285 307 286 if (print) 308 287 std::cerr << "dyld: Expanding \"" << name << "\" -> \"" << expanded << "\"\n"; 309 288 310 289 result = resolve(expanded, requester); 311 - 290 + 312 291 if (!result.empty()) 313 292 { 314 293 if (print) ··· 321 300 std::cerr << "dyld: @rpath expansion not successful\n"; 322 301 } 323 302 } 324 - 303 + 325 304 return std::string(); 326 305 } 327 306 ··· 329 308 { 330 309 char* real; 331 310 std::string rv; 332 - 311 + 333 312 real = ::realpath(path.c_str(), nullptr); 334 - 313 + 335 314 if (real) 336 315 { 337 316 rv = real; 338 - 317 + 339 318 free(real); 340 319 return rv; 341 320 }
-523
src/libdyld/VirtualPrefix.cpp
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2015 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #include "darling-config.h" 21 - #include "VirtualPrefix.h" 22 - #include <string> 23 - #include <cstring> 24 - #include <pthread.h> 25 - #include <list> 26 - #include <cassert> 27 - #include <unistd.h> 28 - #include <sys/stat.h> 29 - #include <iostream> 30 - #include <cstdio> 31 - #include <dirent.h> 32 - 33 - static std::string g_prefix; 34 - static std::list<std::string> g_prefixComponents; 35 - static std::string g_cwd; 36 - static pthread_rwlock_t g_cwdLock = PTHREAD_RWLOCK_INITIALIZER; 37 - static const char SYSTEM_ROOT[] = __SYSTEM_ROOT; 38 - 39 - static std::list<std::string> explode_path(const std::string& path); 40 - static std::string join_path(const std::list<std::string>& path_components); 41 - 42 - static std::list<std::string>& canonicalize_path(std::list<std::string>& path_components); 43 - static std::string resolve_path(std::list<std::string>& path_components, bool symlink); 44 - static const char* translate_path_common(const char* path, bool symlink); 45 - 46 - void __prefix_set(const char* path) 47 - { 48 - char cwd[256]; 49 - size_t pos = 0, last_pos; 50 - 51 - getcwd(cwd, sizeof(cwd)); 52 - 53 - assert(path[0] == '/'); 54 - assert(g_prefix.empty()); 55 - 56 - g_prefix = path; 57 - g_prefixComponents.clear(); 58 - 59 - while (pos != std::string::npos) 60 - { 61 - size_t len; 62 - last_pos = pos + 1; 63 - 64 - pos = g_prefix.find('/', last_pos); 65 - len = (pos == std::string::npos) ? pos : (pos - last_pos); 66 - g_prefixComponents.push_back(g_prefix.substr(last_pos, len)); 67 - } 68 - 69 - if (g_prefix[g_prefix.length()-1] != '/') 70 - g_prefix += '/'; 71 - 72 - if (strncmp(cwd, path, strlen(path)) == 0) 73 - { 74 - g_cwd = cwd + strlen(path); 75 - if (g_cwd.empty() || g_cwd[g_cwd.length()-1] != '/') 76 - g_cwd += "/"; 77 - } 78 - else 79 - { 80 - g_cwd = SYSTEM_ROOT; 81 - g_cwd += cwd; 82 - g_cwd += '/'; 83 - } 84 - 85 - // std::cout << "### Prefix initialized with cwd " << g_cwd << " from " << cwd << std::endl; 86 - } 87 - 88 - const char* __prefix_get(void) 89 - { 90 - if (g_prefix.empty()) 91 - return nullptr; 92 - else 93 - return g_prefix.c_str(); 94 - } 95 - 96 - const char* translate_path_common(const char* path, bool symlink) 97 - { 98 - static thread_local char resolved_path[1024]; 99 - std::string str; 100 - std::list<std::string> path_components; 101 - 102 - if (!path) 103 - return nullptr; 104 - 105 - if (g_prefix.empty()) 106 - return path; 107 - 108 - // std::cout << "\tCWD is " << g_cwd << std::endl; 109 - 110 - if (path[0] != '/') 111 - { 112 - pthread_rwlock_rdlock(&g_cwdLock); 113 - str = g_cwd; 114 - pthread_rwlock_unlock(&g_cwdLock); 115 - } 116 - str += path; 117 - // std::cout << "*** Before explode: " << str << std::endl; 118 - 119 - path_components = explode_path(str); 120 - str = resolve_path(path_components, symlink); 121 - 122 - strncpy(resolved_path, str.c_str(), sizeof(resolved_path)-1); 123 - resolved_path[sizeof(resolved_path)-1] = '\0'; 124 - 125 - // std::cout << "*** In: " << path << "; out: " << resolved_path << std::endl; 126 - 127 - return resolved_path; 128 - } 129 - 130 - const char* __prefix_translate_path(const char* path) 131 - { 132 - return translate_path_common(path, false); 133 - } 134 - 135 - const char* __prefix_translate_path_link(const char* path) 136 - { 137 - return translate_path_common(path, true); 138 - } 139 - 140 - const char* __prefix_untranslate_path(const char* path, unsigned long count) 141 - { 142 - static thread_local char resolved_path[1024]; 143 - size_t test_len; 144 - 145 - // FIXME: The following strcmp is a bit of a hack needed for isatty() 146 - // and friends. 147 - if (g_prefix.empty() || !count || path[0] != '/' 148 - || strncmp(path, "/dev/", 5) == 0) 149 - { 150 - memcpy(resolved_path, path, count); 151 - resolved_path[count] = '\0'; 152 - return resolved_path; 153 - } 154 - 155 - test_len = (path[count-1] != '/') ? (g_prefix.length()-1) 156 - : (g_prefix.length()); 157 - 158 - if (strncmp(path, g_prefix.c_str(), test_len) == 0) 159 - { 160 - size_t len = count - (g_prefix.length()-1); 161 - memcpy(resolved_path, path + g_prefix.length() - 1, 162 - count - (g_prefix.length() - 1)); 163 - 164 - if (len > 0) 165 - resolved_path[len] = '\0'; 166 - else 167 - strcpy(resolved_path, "/"); 168 - } 169 - else 170 - { 171 - size_t len = std::min<size_t>(sizeof(resolved_path) 172 - - sizeof(SYSTEM_ROOT), count); 173 - 174 - strcpy(resolved_path, SYSTEM_ROOT); 175 - strncat(resolved_path, path, len); 176 - resolved_path[len + sizeof(SYSTEM_ROOT)-1] = '\0'; 177 - } 178 - 179 - // std::cout << "*** UNTRANSLATE: " << path << " -> " << resolved_path << std::endl; 180 - 181 - return resolved_path; 182 - } 183 - 184 - void __prefix_cwd(const char* in_path) 185 - { 186 - if (!*in_path) 187 - return; 188 - 189 - std::string path; 190 - std::list<std::string> path_components; 191 - 192 - // std::cout << "CWD to " << in_path << std::endl; 193 - 194 - pthread_rwlock_wrlock(&g_cwdLock); 195 - if (in_path[0] != '/') 196 - { 197 - path = g_cwd; 198 - path += in_path; 199 - } 200 - else 201 - path = in_path; 202 - 203 - path_components = explode_path(path); 204 - g_cwd = join_path(canonicalize_path(path_components)); 205 - 206 - if (g_cwd[g_cwd.length()-1] != '/') 207 - g_cwd += '/'; 208 - 209 - // std::cout << "\t+++ CWD In: " << in_path << "; out: " << g_cwd << std::endl; 210 - 211 - pthread_rwlock_unlock(&g_cwdLock); 212 - } 213 - 214 - void __prefix_cwd_fd(int fd) 215 - { 216 - char path[1024]; 217 - int count; 218 - 219 - if (g_prefix.empty()) 220 - return; 221 - 222 - sprintf(path, "/proc/self/fd/%d", fd); 223 - count = readlink(path, path, sizeof(path)-1); 224 - 225 - if (count < 0) 226 - return; 227 - 228 - __prefix_cwd(__prefix_untranslate_path(path, count)); 229 - } 230 - 231 - bool __prefix_is_system_root(const char* path) 232 - { 233 - return strcmp(__prefix_translate_path(path), "/") == 0; 234 - } 235 - 236 - int __prefix_get_dyld_path(char* buf, unsigned long size) 237 - { 238 - int len; 239 - len = readlink("/proc/self/exe", buf, size); 240 - 241 - if (len < 0) 242 - buf[0] = '\0'; 243 - else 244 - buf[len] = '\0'; 245 - 246 - return len; 247 - } 248 - 249 - std::list<std::string> explode_path(const std::string& path) 250 - { 251 - std::list<std::string> path_components; 252 - size_t pos = 0, last_pos; 253 - 254 - if (path.empty()) 255 - return path_components; 256 - 257 - while (pos != std::string::npos) 258 - { 259 - size_t len; 260 - 261 - if (pos != 0 || path[0] == '/') 262 - last_pos = pos + 1; // skip first slash 263 - else 264 - last_pos = pos; 265 - 266 - pos = path.find('/', last_pos); 267 - len = (pos == std::string::npos) ? pos : (pos - last_pos); 268 - path_components.push_back(path.substr(last_pos, len)); 269 - } 270 - 271 - return path_components; 272 - } 273 - 274 - std::string join_path(const std::list<std::string>& path_components) 275 - { 276 - std::string path; 277 - 278 - for (const std::string& comp : path_components) 279 - { 280 - path += '/'; 281 - path += comp; 282 - } 283 - 284 - return path; 285 - } 286 - 287 - std::list<std::string>& canonicalize_path(std::list<std::string>& path_components) 288 - { 289 - for (std::list<std::string>::iterator it = path_components.begin(); 290 - it != path_components.end(); ) 291 - { 292 - if (*it == "." || it->empty()) 293 - { 294 - it = path_components.erase(it); 295 - } 296 - else if (*it == "..") 297 - { 298 - if (it != path_components.begin()) 299 - { 300 - it--; 301 - it = path_components.erase(it); 302 - } 303 - it = path_components.erase(it); 304 - } 305 - else 306 - it++; 307 - } 308 - 309 - return path_components; 310 - } 311 - 312 - std::string resolve_path(std::list<std::string>& path_components, bool symlink) 313 - { 314 - std::string path, real_path; 315 - bool had_failure = false; 316 - 317 - real_path = g_prefix; 318 - 319 - // The resolution process is restarted when a symlink is encountered 320 - restart_process: 321 - 322 - canonicalize_path(path_components); 323 - path.clear(); 324 - 325 - for (std::list<std::string>::iterator it = path_components.begin(); 326 - it != path_components.end(); it++) 327 - { 328 - std::string& comp = *it; 329 - 330 - path += '/'; 331 - 332 - if (!had_failure) // check if there is any sense in using opendir() or lstat() again 333 - { 334 - DIR* dir; 335 - struct dirent* ent; 336 - struct stat st; 337 - bool isLink = false; 338 - bool is_system_root; 339 - 340 - real_path.replace(g_prefix.size(), std::string::npos, path); 341 - real_path += comp; 342 - 343 - // Do NOT perform symlink resolution on /system-root, 344 - // because that should look like a bind mount rather than 345 - // a symlink from inside the DPREFIX 346 - is_system_root = (it == path_components.begin()) 347 - && (comp == (SYSTEM_ROOT+1)); 348 - 349 - // We try an lstat() first as an optimization, 350 - // because the opendir() path below is VERY slow on NFS mounts. 351 - if (lstat(real_path.c_str(), &st) == 0) 352 - { 353 - isLink = S_ISLNK(st.st_mode); 354 - } 355 - else 356 - { 357 - // std::cout << "*** opendir: " << real_path << std::endl; 358 - real_path.resize(real_path.length() - comp.length()); 359 - 360 - dir = opendir(real_path.c_str()); 361 - 362 - if (dir != nullptr) 363 - { 364 - std::string best_match; 365 - unsigned char best_match_type; 366 - 367 - while ((ent = readdir(dir)) != nullptr) 368 - { 369 - // Commented out: replaced with lstat() above 370 - /* if (comp == ent->d_name) 371 - break; 372 - else*/ if (strcasecmp(comp.c_str(), ent->d_name) == 0) 373 - { 374 - best_match = ent->d_name; 375 - best_match_type = ent->d_type; 376 - } 377 - } 378 - 379 - if (ent != nullptr || !best_match.empty()) 380 - { 381 - if (ent == nullptr) 382 - { 383 - // correct the case 384 - comp = best_match; 385 - } 386 - else 387 - best_match_type = ent->d_type; 388 - 389 - if (best_match_type == DT_LNK && !is_system_root) 390 - { 391 - isLink = true; 392 - real_path += comp; 393 - } 394 - } 395 - else 396 - had_failure = true; 397 - 398 - closedir(dir); 399 - } 400 - else 401 - had_failure = true; 402 - } 403 - 404 - if (symlink && it == --path_components.end()) 405 - isLink = false; 406 - 407 - // Perform symlink resolution 408 - if (isLink && !is_system_root) 409 - { 410 - char link[4096]; 411 - int len; 412 - 413 - // std::cout << "*** readlink: " << real_path << std::endl; 414 - len = readlink(real_path.c_str(), link, sizeof(link)-1); 415 - 416 - if (len > 0) 417 - { 418 - std::list<std::string> link_components; 419 - 420 - link[len] = '\0'; 421 - 422 - /* 423 - if (strncmp(link, "@darling_prefix@", 16) == 0) 424 - { 425 - std::string copy; 426 - 427 - copy = link; 428 - copy.replace(0, 16, INSTALL_PREFIX); 429 - 430 - strcpy(link, copy.c_str()); 431 - } 432 - */ 433 - link_components = explode_path(link); 434 - 435 - if (link[0] == '/') 436 - { 437 - // absolute symlink 438 - it++; 439 - it = path_components.erase(path_components.begin(), it); 440 - } 441 - else 442 - { 443 - // relative symlink 444 - it = path_components.erase(it); 445 - } 446 - 447 - path_components.insert(it, 448 - link_components.begin(), 449 - link_components.end()); 450 - 451 - // We always restart the process 452 - // 1) For absolute symlinks, because we're moving to a completely different path 453 - // 2) For relative symlinks, because they may contain '..' 454 - goto restart_process; 455 - } 456 - } 457 - } 458 - 459 - path += comp; 460 - } 461 - 462 - if (!path_components.empty()) 463 - { 464 - if (*path_components.begin() == "proc" || path == "/dev/mach") 465 - { 466 - return path; 467 - } 468 - else if (*path_components.begin() == (SYSTEM_ROOT+1)) 469 - { 470 - if (!symlink || path_components.size() > 1) 471 - { 472 - // Exit virtual prefix 473 - path = path.substr(sizeof(SYSTEM_ROOT)-1); 474 - 475 - if (path.empty()) 476 - return "/"; 477 - else 478 - return path; 479 - } 480 - } 481 - } 482 - if (path.compare(0, sizeof(SHARE_PATH "/")-1, SHARE_PATH "/") == 0) 483 - { 484 - return path; 485 - } 486 - 487 - // Apply virtual prefix 488 - real_path.replace(g_prefix.size(), std::string::npos, path); 489 - return real_path; 490 - } 491 - 492 - /* 493 - void path_to_string(const std::list<std::string>& path, char* outPath, 494 - size_t maxLen) 495 - { 496 - size_t lenSoFar = 1; 497 - 498 - if (maxLen < 2) 499 - return; 500 - 501 - outPath[0] = '\0'; 502 - 503 - for (const std::string& comp : path) 504 - { 505 - if (lenSoFar+1 > maxLen) 506 - break; 507 - 508 - strcat(outPath, "/"); 509 - lenSoFar++; 510 - 511 - if (lenSoFar + comp.length() > maxLen) 512 - { 513 - strncat(outPath, comp.c_str(), maxLen - lenSoFar); 514 - break; 515 - } 516 - else 517 - { 518 - strcat(outPath, comp.c_str()); 519 - lenSoFar += comp.length(); 520 - } 521 - } 522 - } 523 - */
-66
src/libdyld/VirtualPrefix.h
··· 1 - /* 2 - This file is part of Darling. 3 - 4 - Copyright (C) 2015 Lubos Dolezel 5 - 6 - Darling is free software: you can redistribute it and/or modify 7 - it under the terms of the GNU General Public License as published by 8 - the Free Software Foundation, either version 3 of the License, or 9 - (at your option) any later version. 10 - 11 - Darling is distributed in the hope that it will be useful, 12 - but WITHOUT ANY WARRANTY; without even the implied warranty of 13 - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 - GNU General Public License for more details. 15 - 16 - You should have received a copy of the GNU General Public License 17 - along with Darling. If not, see <http://www.gnu.org/licenses/>. 18 - */ 19 - 20 - #ifndef VIRTUALPREFIX_H 21 - #define VIRTUALPREFIX_H 22 - #include <stdbool.h> 23 - 24 - #ifdef __cplusplus 25 - extern "C" { 26 - #endif 27 - 28 - #define __SYSTEM_ROOT "/system-root" 29 - 30 - // Set prefix path. Should be run only once at startup. 31 - // If this is never called, then __prefix_translate_path() 32 - // is a no-op. 33 - void __prefix_set(const char* path); 34 - 35 - // Returns the current prefix or NULL; 36 - const char* __prefix_get(void); 37 - 38 - // Translate from path in prefix to physical path. 39 - const char* __prefix_translate_path(const char* path); 40 - 41 - // Translate from path in prefix to physical path, treat the leaf node 42 - // as a symlink. 43 - const char* __prefix_translate_path_link(const char* path); 44 - 45 - // Translate from physical path to path in prefix. 46 - // The path is expected to be canonical. 47 - const char* __prefix_untranslate_path(const char* path, unsigned long count); 48 - 49 - // Called whenever current working directory changes. 50 - // This is used to resolve relative paths passed to 51 - // __prefix_translate_path(). 52 - void __prefix_cwd(const char* path); 53 - 54 - void __prefix_cwd_fd(int fd); 55 - 56 - // Is the given path equivalent to __SYSTEM_ROOT? 57 - bool __prefix_is_system_root(const char* path); 58 - 59 - int __prefix_get_dyld_path(char* buf, unsigned long size); 60 - 61 - #ifdef __cplusplus 62 - } 63 - #endif 64 - 65 - #endif /* VIRTUALPREFIX_H */ 66 -
+12
src/setup-ld-so.sh
··· 1 + #! /bin/bash 2 + 3 + # This runs as root, 4 + # with the current directory set to ${CMAKE_INSTALL_PREFIX}/libexec/darling 5 + 6 + for file in /etc/ld.so.conf $(find /etc/ld.so.conf.d/ -type f); do 7 + # Copy lines from e.g. /etc/ld.so.conf into ./etc/ld.so.conf, 8 + # prepending "/Volumes/SystemRoot" to each line that starts with a slash 9 + awk '/^\// { print "/Volumes/SystemRoot" $0 }; /^[^/]/' $file > .$file 10 + done 11 + 12 + unshare --mount bash -c "mount --rbind / Volumes/SystemRoot && ldconfig -r . -X"