···11+#!/bin/sh
22+#
33+# This file is part of Darling.
44+#
55+# Copyright (C) 2015 Lubos Dolezel
66+#
77+# Darling is free software: you can redistribute it and/or modify
88+# it under the terms of the GNU General Public License as published by
99+# the Free Software Foundation, either version 3 of the License, or
1010+# (at your option) any later version.
1111+#
1212+# Darling is distributed in the hope that it will be useful,
1313+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1414+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1515+# GNU General Public License for more details.
1616+#
1717+# You should have received a copy of the GNU General Public License
1818+# along with Darling. If not, see <http://www.gnu.org/licenses/>.
1919+#
2020+2121+SYSTEM_ROOT_NAME="system-root"
2222+BIND_DIRECTORIES="dev etc home tmp"
2323+MAKE_DIRECTORIES="Applications Volumes"
2424+2525+if [ $# -eq 0 ]; then
2626+ >&2 echo "This is Darling, a runtime environment for OS X applications."
2727+ >&2 echo
2828+ >&2 echo "Copyright (C) 2012-2015 Lubos Dolezel"
2929+ >&2 echo "Includes software components which are Copyright (C) Apple Computer, Inc. and many others."
3030+ >&2 echo
3131+ >&2 echo -e "Usage:\tdarling PROGRAM [ARGUMENTS...]\tRun the specified program"
3232+ >&2 echo -e "\tdarling shell\t\t\tStart bash shell in prefix"
3333+ >&2 echo -e "\tdarling hdiutil\t\t\tMount DMG disk images"
3434+ >&2 echo -e "\tdarling pkgutil\t\t\tInstall PKG packages"
3535+ >&2 echo
3636+ >&2 echo "The prefix is specified by the DPREFIX environment variable."
3737+ >&2 echo "The default DPREFIX is \$HOME/.darling"
3838+ exit 1
3939+fi
4040+4141+set -e
4242+4343+if [ -z "$DPREFIX" ]; then
4444+ export DPREFIX="$HOME/.darling"
4545+fi
4646+4747+if [ ! -d "$DPREFIX" ]; then
4848+ >&2 echo "Setting up prefix at $DPREFIX"
4949+5050+ mkdir -p "${DPREFIX}"
5151+ pushd "${DPREFIX}" >/dev/null
5252+5353+ ln -s / "${SYSTEM_ROOT_NAME}"
5454+ for dir in ${BIND_DIRECTORIES}; do
5555+ ln -s "${SYSTEM_ROOT_NAME}/${dir}" "${dir}"
5656+ done
5757+5858+ for dir in ${MAKE_DIRECTORIES}; do
5959+ mkdir "${dir}"
6060+ done
6161+6262+ ln -s home Users
6363+6464+ # TODO: install bash and coreutils
6565+6666+ popd >/dev/null
6767+fi
6868+6969+dyld_path="${0%darling}dyld"
7070+7171+case "$1" in
7272+"shell")
7373+ if [ $# -gt 2 ]; then
7474+ exec "${dyld_path}" /usr/local/bin/bash -c "${*:2}"
7575+ else
7676+ exec "${dyld_path}" /usr/local/bin/bash
7777+ fi
7878+ ;;
7979+"hdiutil")
8080+ >2& echo "Not implemented yet"
8181+ exit 1
8282+ ;;
8383+"pkgutil")
8484+ >2& echo "Not implemented yet"
8585+ exit 1
8686+ ;;
8787+*)
8888+ exec "${dyld_path}" "$1" "${@:2}"
8989+ ;;
9090+esac
+19
src/dyld/dirstructure.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "dirstructure.h"
221#include <sstream>
322#include <unistd.h>
+19
src/dyld/dirstructure.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef DIRSTRUCTURE_H
221#define DIRSTRUCTURE_H
322
+19
src/dyld/dyld-multilib.c
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include <sys/types.h>
221#include <sys/stat.h>
322#include <sys/wait.h>
+23-1
src/dyld/dyld.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include <libdyld/MachOMgr.h>
221#include <libdyld/MachOObject.h>
322#include <iostream>
···1029#include <libdyld/arch.h>
1130#include <regex>
1231#include "dirstructure.h"
3232+#include <libdyld/VirtualPrefix.h>
13331434static void printHelp(const char* argv0);
1535static std::string locateBundleExecutable(std::string bundlePath);
···5777 mgr->setSysRoot(path);
5878 if (const char* path = getenv("DYLD_TRAMPOLINE"))
5979 mgr->setUseTrampolines(true, path);
8080+ if (const char* path = getenv("DPREFIX"))
8181+ __prefix_set(path);
60826161- obj = new MachOObject(argv[1]);
8383+ obj = new MachOObject(__prefix_translate_path(argv[1]));
6284 if (!obj->isMainModule())
6385 {
6486 throw std::runtime_error("This is not a Mach-O executable; dynamic libraries, "
+24-1
src/dyld/dyldd.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include <libdyld/DylibSearch.h>
221#include <libdyld/MachOMgr.h>
322#include <libdyld/MachOObject.h>
···928#include <unistd.h>
1029#include <cstdlib>
1130#include <cstring>
3131+#include <libdyld/VirtualPrefix.h>
12321333#define ANSI_COLOR_RED "\x1b[31m"
1434#define ANSI_COLOR_GREEN "\x1b[32m"
···3757 MachOMgr* mgr = MachOMgr::instance();
38583959 mgr->detectSysRootFromPath(argv[1]);
6060+ if (const char* path = getenv("DPREFIX"))
6161+ __prefix_set(path);
6262+4063 mgr->setLoadAnyArchitecture(true);
41644242- obj = new MachOObject(argv[1]);
6565+ obj = new MachOObject(__prefix_translate_path(argv[1]));
43664467 mgr->add(obj, true);
4568
···22#include "../base.h"
33#include "../errno.h"
44#include <asm/unistd.h>
55+#include <libdyld/VirtualPrefix.h>
5667long sys_truncate(const char* path, long long length)
78{
89 int ret;
9101010- // TODO: translate path
1111-1211#ifdef __NR_truncate64
1313- ret = LINUX_SYSCALL(__NR_truncate64, path, LL_ARG(length));
1212+ ret = LINUX_SYSCALL(__NR_truncate64, __prefix_translate_path(path),
1313+ LL_ARG(length));
1414#else
1515- ret = LINUX_SYSCALL(__NR_truncate, path, LL_ARG(length));
1515+ ret = LINUX_SYSCALL(__NR_truncate, __prefix_translate_path(path),
1616+ LL_ARG(length));
1617#endif
1718 if (ret < 0)
1819 ret = errno_linux_to_bsd(ret);
+2-3
src/kernel/emulation/linux/unistd/unlink.c
···22#include "../base.h"
33#include "../errno.h"
44#include <asm/unistd.h>
55+#include <libdyld/VirtualPrefix.h>
5667long sys_unlink(const char* path)
78{
89 int ret;
9101010- // TODO: case translation
1111-1212- ret = LINUX_SYSCALL(__NR_unlink, path);
1111+ ret = LINUX_SYSCALL(__NR_unlink, __prefix_translate_path(path));
1312 if (ret < 0)
1413 ret = errno_linux_to_bsd(ret);
1514
-2
src/kernel/emulation/linux/xattr/fgetxattr.c
···88 unsigned long size, unsigned int pos, int options)
99{
1010 int ret;
1111-1212- // TODO: handle case conversion
13111412 if (pos != 0)
1513 return -ERANGE;
-2
src/kernel/emulation/linux/xattr/flistxattr.c
···77{
88 int ret;
991010- // TODO: handle case conversion
1111-1210 ret = LINUX_SYSCALL(__NR_flistxattr, fd, namebuf, size);
13111412 if (ret < 0)
-2
src/kernel/emulation/linux/xattr/fremovexattr.c
···77{
88 int ret;
991010- // TODO: handle case conversion
1111-1210 ret = LINUX_SYSCALL(__NR_fremovexattr, fd, name);
13111412 if (ret < 0)
-2
src/kernel/emulation/linux/xattr/fsetxattr.c
···99{
1010 int ret;
11111212- // TODO: handle case conversion
1313-1412 if (pos != 0)
1513 return -ERANGE;
1614
+5-4
src/kernel/emulation/linux/xattr/getxattr.c
···33#include "../errno.h"
44#include "../../../../../platform-include/sys/errno.h"
55#include <asm/unistd.h>
66+#include <libdyld/VirtualPrefix.h>
6778#define XATTR_NOFOLLOW 1
89···1011 unsigned long size, unsigned int pos, int options)
1112{
1213 int ret;
1313-1414- // TODO: handle case conversion
15141615 if (pos != 0)
1716 return -ERANGE;
18171918 if (options & XATTR_NOFOLLOW)
2020- ret = LINUX_SYSCALL(__NR_lgetxattr, path, name, value, size);
1919+ ret = LINUX_SYSCALL(__NR_lgetxattr, __prefix_translate_path(path),
2020+ name, value, size);
2121 else
2222- ret = LINUX_SYSCALL(__NR_getxattr, path, name, value, size);
2222+ ret = LINUX_SYSCALL(__NR_getxattr, __prefix_translate_path(path),
2323+ name, value, size);
23242425 if (ret < 0)
2526 return errno_linux_to_bsd(ret);
+5-4
src/kernel/emulation/linux/xattr/listxattr.c
···22#include "../base.h"
33#include "../errno.h"
44#include <asm/unistd.h>
55+#include <libdyld/VirtualPrefix.h>
5667#define XATTR_NOFOLLOW 1
78···910{
1011 int ret;
11121212- // TODO: handle case conversion
1313-1413 if (options & XATTR_NOFOLLOW)
1515- ret = LINUX_SYSCALL(__NR_llistxattr, path, namebuf, size);
1414+ ret = LINUX_SYSCALL(__NR_llistxattr, __prefix_translate_path(path),
1515+ namebuf, size);
1616 else
1717- ret = LINUX_SYSCALL(__NR_listxattr, path, namebuf, size);
1717+ ret = LINUX_SYSCALL(__NR_listxattr, __prefix_translate_path(path),
1818+ namebuf, size);
18191920 if (ret < 0)
2021 return errno_linux_to_bsd(ret);
+5-4
src/kernel/emulation/linux/xattr/removexattr.c
···22#include "../base.h"
33#include "../errno.h"
44#include <asm/unistd.h>
55+#include <libdyld/VirtualPrefix.h>
5667#define XATTR_NOFOLLOW 1
78···910{
1011 int ret;
11121212- // TODO: handle case conversion
1313-1413 if (options & XATTR_NOFOLLOW)
1515- ret = LINUX_SYSCALL(__NR_lremovexattr, path, name);
1414+ ret = LINUX_SYSCALL(__NR_lremovexattr, __prefix_translate_path(path),
1515+ name);
1616 else
1717- ret = LINUX_SYSCALL(__NR_removexattr, path, name);
1717+ ret = LINUX_SYSCALL(__NR_removexattr, __prefix_translate_path(path),
1818+ name);
18191920 if (ret < 0)
2021 return errno_linux_to_bsd(ret);
+9-4
src/kernel/emulation/linux/xattr/setxattr.c
···33#include "../errno.h"
44#include "../../../../../platform-include/sys/errno.h"
55#include <asm/unistd.h>
66+#include <libdyld/VirtualPrefix.h>
6778#define XATTR_NOFOLLOW 1
89···1112{
1213 int ret;
13141414- // TODO: handle case conversion
1515-1615 if (pos != 0)
1716 return -ERANGE;
18171918 if (options & XATTR_NOFOLLOW)
2020- ret = LINUX_SYSCALL(__NR_lsetxattr, path, name, value, size);
1919+ {
2020+ ret = LINUX_SYSCALL(__NR_lsetxattr, __prefix_translate_path(path),
2121+ name, value, size);
2222+ }
2123 else
2222- ret = LINUX_SYSCALL(__NR_setxattr, path, name, value, size);
2424+ {
2525+ ret = LINUX_SYSCALL(__NR_setxattr, __prefix_translate_path(path),
2626+ name, value, size);
2727+ }
23282429 if (ret < 0)
2530 return errno_linux_to_bsd(ret);
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "DylibSearch.h"
221#include "darling-config.h"
322#include <stdexcept>
423#include <iostream>
524#include "MachOObject.h"
625#include "MachOMgr.h"
2626+#include "VirtualPrefix.h"
727#include <regex.h>
828#include <unistd.h>
929#include <util/stlutils.h>
···101121 return epath;
102122103123 // If absolute, search in sysroot
104104- if (dylib[0] == '/' && !MachOMgr::instance()->sysRoot().empty())
124124+ if (dylib[0] == '/')
105125 {
106106- std::vector<std::string> roots = string_explode(MachOMgr::instance()->sysRoot(), ':');
126126+ const char* prefix = __prefix_get();
107127108108- for (std::string path : roots)
128128+ if (!MachOMgr::instance()->sysRoot().empty())
109129 {
110110- path += '/';
130130+ std::vector<std::string> roots = string_explode(MachOMgr::instance()->sysRoot(), ':');
131131+132132+ for (const std::string& in_path : roots)
133133+ {
134134+ std::string path;
135135+136136+ if (prefix != nullptr)
137137+ path = prefix;
138138+139139+ path += in_path;
140140+ path += '/';
141141+ path += dylib;
142142+143143+ epath = checkPresence(path);
144144+ if (!epath.empty())
145145+ return epath;
146146+ }
147147+ }
148148+ if (prefix != nullptr)
149149+ {
150150+ std::string path = prefix;
111151 path += dylib;
112152113153 epath = checkPresence(path);
···157197158198std::string DylibSearch::resolveInPathList(std::string name, const std::vector<std::string>& paths)
159199{
200200+ const char* prefix = __prefix_get();
160201 for (const std::string& e : paths)
161202 {
162162- std::string path = e + "/" + name;
203203+ std::string path;
204204+205205+ if (prefix)
206206+ path = prefix;
207207+208208+ path += e + "/" + name;
163209164210 if (::access(path.c_str(), F_OK) == 0)
165211 return path;
+19
src/libdyld/MachOMgr.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "MachOMgr.h"
221#include <cassert>
322#include <algorithm>
+20-1
src/libdyld/MachOMgr.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef MACHOMGR_H
221#define MACHOMGR_H
322#include <stdint.h>
···114133 inline bool loadAnyArchitecture() const { return m_loadAny; }
115134116135 bool detectSysRootFromPath(std::string path);
117117- inline void setSysRoot(const std::string& sysroot) { m_sysroot = sysroot; }
136136+ inline void setSysRoot(std::string sysroot) { m_sysroot = sysroot; }
118137 inline const std::string& sysRoot() const { return m_sysroot; }
119138 inline bool hasSysRoot() const { return !m_sysroot.empty(); }
120139
+19
src/libdyld/MachOObject.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "dl_public.h"
221#include "MachOObject.h"
322#include <limits>
+19
src/libdyld/MachOObject.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef MACHOOBJECT_H
221#define MACHOOBJECT_H
322#include <libmach-o/MachO.h>
+19
src/libdyld/NativeObject.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "NativeObject.h"
221#include <dlfcn.h>
322#include <sstream>
+19
src/libdyld/NativeObject.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef NATIVEOBJECT_H
221#define NATIVEOBJECT_H
322#include <string>
+263
src/libdyld/VirtualPrefix.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+#include "VirtualPrefix.h"
2121+#include <string>
2222+#include <cstring>
2323+#include <pthread.h>
2424+#include <list>
2525+#include <cassert>
2626+#include <unistd.h>
2727+#include <iostream>
2828+#include <cstdio>
2929+3030+static std::string g_prefix;
3131+static std::string g_cwd;
3232+static pthread_rwlock_t g_cwdLock = PTHREAD_RWLOCK_INITIALIZER;
3333+static const char SYSTEM_ROOT[] = __SYSTEM_ROOT;
3434+3535+static std::string canonicalize_path(const std::string& in_path);
3636+3737+void __prefix_set(const char* path)
3838+{
3939+ char cwd[256];
4040+4141+ getcwd(cwd, sizeof(cwd));
4242+4343+ g_prefix = path;
4444+ if (g_prefix[g_prefix.length()-1] != '/')
4545+ g_prefix += '/';
4646+4747+ if (strncmp(cwd, path, strlen(path)) == 0)
4848+ {
4949+ g_cwd = path + strlen(path);
5050+ if (g_cwd.empty())
5151+ g_cwd = "/";
5252+ }
5353+ else
5454+ {
5555+ g_cwd = SYSTEM_ROOT;
5656+ g_cwd += cwd;
5757+ g_cwd += '/';
5858+ }
5959+}
6060+6161+const char* __prefix_get(void)
6262+{
6363+ if (g_prefix.empty())
6464+ return nullptr;
6565+ else
6666+ return g_prefix.c_str();
6767+}
6868+6969+const char* __prefix_translate_path(const char* path)
7070+{
7171+ static thread_local char resolved_path[1024];
7272+ std::string str;
7373+7474+ if (g_prefix.empty())
7575+ return path;
7676+7777+ if (path[0] != '/')
7878+ {
7979+ pthread_rwlock_rdlock(&g_cwdLock);
8080+ str = g_cwd;
8181+ pthread_rwlock_unlock(&g_cwdLock);
8282+ }
8383+ str += path;
8484+8585+ // Resolve . and ..
8686+ str = canonicalize_path(str);
8787+8888+ // std::cout << "CWD: " << g_cwd << std::endl;
8989+ // std::cout << "Can1: " << path << " -> " << str << std::endl;
9090+ if (str.compare(0, sizeof(SYSTEM_ROOT)-1, SYSTEM_ROOT) == 0)
9191+ {
9292+ // Leave virtual prefix
9393+ str = str.substr(sizeof(SYSTEM_ROOT)-1);
9494+ if (str.empty())
9595+ str = "/";
9696+ }
9797+ else if (str.compare(0, 5, "/proc") != 0)
9898+ {
9999+ // Apply virtual prefix
100100+ str = g_prefix + str;
101101+ }
102102+103103+ // std::cout << "Can2: " << path << " -> " << str << std::endl;
104104+105105+ // TODO: make case insensitive
106106+107107+ strncpy(resolved_path, str.c_str(), sizeof(resolved_path)-1);
108108+ resolved_path[sizeof(resolved_path)-1] = '\0';
109109+110110+ return resolved_path;
111111+}
112112+113113+const char* __prefix_untranslate_path(const char* path, unsigned long count)
114114+{
115115+ static thread_local char resolved_path[1024];
116116+ size_t test_len;
117117+118118+ // FIXME: The following strcmp is a bit of a hack needed for isatty()
119119+ // and friends.
120120+ if (g_prefix.empty() || !count || path[0] != '/'
121121+ || strncmp(path, "/dev/", 5) == 0)
122122+ {
123123+ memcpy(resolved_path, path, count);
124124+ resolved_path[count] = '\0';
125125+ return resolved_path;
126126+ }
127127+128128+ test_len = (path[count-1] != '/') ? (g_prefix.length()-1)
129129+ : (g_prefix.length());
130130+131131+ if (strncmp(path, g_prefix.c_str(), test_len) == 0)
132132+ {
133133+ size_t len = count - (g_prefix.length()-1);
134134+ memcpy(resolved_path, path + g_prefix.length() - 1,
135135+ count - (g_prefix.length() - 1));
136136+137137+ if (len > 0)
138138+ resolved_path[len] = '\0';
139139+ else
140140+ strcpy(resolved_path, "/");
141141+ }
142142+ else
143143+ {
144144+ size_t len = std::min<size_t>(sizeof(resolved_path)
145145+ - sizeof(SYSTEM_ROOT), count);
146146+147147+ strcpy(resolved_path, SYSTEM_ROOT);
148148+ strncat(resolved_path, path, len);
149149+ resolved_path[len + sizeof(SYSTEM_ROOT)-1] = '\0';
150150+ }
151151+152152+ return resolved_path;
153153+}
154154+155155+void __prefix_cwd(const char* in_path)
156156+{
157157+ if (!*in_path)
158158+ return;
159159+160160+ std::string path;
161161+162162+ // std::cout << "CWD to " << in_path << std::endl;
163163+164164+ pthread_rwlock_wrlock(&g_cwdLock);
165165+ if (in_path[0] != '/')
166166+ {
167167+ path = g_cwd;
168168+ path += in_path;
169169+ }
170170+ else
171171+ path = in_path;
172172+173173+ g_cwd = canonicalize_path(path);
174174+175175+ if (g_cwd[g_cwd.length()-1] != '/')
176176+ g_cwd += '/';
177177+178178+ pthread_rwlock_unlock(&g_cwdLock);
179179+}
180180+181181+void __prefix_cwd_fd(int fd)
182182+{
183183+ char path[1024];
184184+ int count;
185185+186186+ if (g_prefix.empty())
187187+ return;
188188+189189+ sprintf(path, "/proc/self/fd/%d", fd);
190190+ count = readlink(path, path, sizeof(path)-1);
191191+192192+ if (count < 0)
193193+ return;
194194+195195+ __prefix_cwd(__prefix_untranslate_path(path, count));
196196+}
197197+198198+bool __prefix_is_system_root(const char* path)
199199+{
200200+ return strcmp(__prefix_translate_path(path), "/") == 0;
201201+}
202202+203203+int __prefix_get_dyld_path(char* buf, unsigned long size)
204204+{
205205+ int len;
206206+ len = readlink("/proc/self/exe", buf, size);
207207+208208+ if (len < 0)
209209+ buf[0] = '\0';
210210+ else
211211+ buf[len] = '\0';
212212+213213+ return len;
214214+}
215215+216216+std::string canonicalize_path(const std::string& in_path)
217217+{
218218+ std::list<std::string> path_components;
219219+ size_t pos = 0, last_pos;
220220+ std::string path;
221221+222222+ assert(in_path[0] == '/');
223223+224224+ while (pos != std::string::npos)
225225+ {
226226+ size_t len;
227227+ last_pos = pos + 1;
228228+229229+ pos = in_path.find('/', last_pos);
230230+ len = (pos == std::string::npos) ? pos : (pos - last_pos);
231231+ path_components.push_back(in_path.substr(last_pos, len));
232232+ }
233233+234234+ for (std::list<std::string>::iterator it = path_components.begin();
235235+ it != path_components.end(); )
236236+ {
237237+ if (*it == "." || it->empty())
238238+ {
239239+ it = path_components.erase(it);
240240+ }
241241+ else if (*it == "..")
242242+ {
243243+ if (it != path_components.begin())
244244+ {
245245+ it--;
246246+ it = path_components.erase(it);
247247+ }
248248+ it = path_components.erase(it);
249249+ }
250250+ else
251251+ it++;
252252+ }
253253+254254+ path.reserve(in_path.size());
255255+256256+ for (const std::string& comp : path_components)
257257+ {
258258+ path += '/';
259259+ path += comp;
260260+ }
261261+262262+ return path;
263263+}
+62
src/libdyld/VirtualPrefix.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+2020+#ifndef VIRTUALPREFIX_H
2121+#define VIRTUALPREFIX_H
2222+#include <stdbool.h>
2323+2424+#ifdef __cplusplus
2525+extern "C" {
2626+#endif
2727+2828+#define __SYSTEM_ROOT "/system-root"
2929+3030+// Set prefix path. Should be run only once at startup.
3131+// If this is never called, then __prefix_translate_path()
3232+// is a no-op.
3333+void __prefix_set(const char* path);
3434+3535+// Returns the current prefix or NULL;
3636+const char* __prefix_get(void);
3737+3838+// Translate from path in prefix to physical path.
3939+const char* __prefix_translate_path(const char* path);
4040+4141+// Translate from physical path to path in prefix.
4242+// The path is expected to be canonical.
4343+const char* __prefix_untranslate_path(const char* path, unsigned long count);
4444+4545+// Called whenever current working directory changes.
4646+// This is used to resolve relative paths passed to
4747+// __prefix_translate_path().
4848+void __prefix_cwd(const char* path);
4949+5050+void __prefix_cwd_fd(int fd);
5151+5252+// Is the given path equivalent to __SYSTEM_ROOT?
5353+bool __prefix_is_system_root(const char* path);
5454+5555+int __prefix_get_dyld_path(char* buf, unsigned long size);
5656+5757+#ifdef __cplusplus
5858+}
5959+#endif
6060+6161+#endif /* VIRTUALPREFIX_H */
6262+
+19
src/libdyld/dl_public.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "dl_public.h"
221#include "MachOMgr.h"
322#include "MachOObject.h"
+19
src/libdyld/dl_public.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef DL_PUBLIC_H
221#define DL_PUBLIC_H
322#include <dlfcn.h>
+19
src/libdyld/dyld_priv.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "dyld_priv.h"
221#include <link.h>
322#include <map>
+19
src/libdyld/dyld_priv.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef DYLD_PRIV_H
221#define DYLD_PRIV_H
322#include <stdint.h>
+1-1
src/libdyld/dyld_public.cpp
···11/*
22This file is part of Darling.
3344-Copyright (C) 2012-2013 Lubos Dolezel
44+Copyright (C) 2012-2015 Lubos Dolezel
5566Darling is free software: you can redistribute it and/or modify
77it under the terms of the GNU General Public License as published by
+1-1
src/libdyld/dyld_public.h
···11/*
22This file is part of Darling.
3344-Copyright (C) 2012-2013 Lubos Dolezel
44+Copyright (C) 2012-2015 Lubos Dolezel
5566Darling is free software: you can redistribute it and/or modify
77it under the terms of the GNU General Public License as published by
+19
src/libdyld/threads.cpp
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#include "threads.h"
221#include <pthread.h>
322#include <sys/mman.h>
+19
src/libdyld/threads.h
···11+/*
22+This file is part of Darling.
33+44+Copyright (C) 2015 Lubos Dolezel
55+66+Darling is free software: you can redistribute it and/or modify
77+it under the terms of the GNU General Public License as published by
88+the Free Software Foundation, either version 3 of the License, or
99+(at your option) any later version.
1010+1111+Darling is distributed in the hope that it will be useful,
1212+but WITHOUT ANY WARRANTY; without even the implied warranty of
1313+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1414+GNU General Public License for more details.
1515+1616+You should have received a copy of the GNU General Public License
1717+along with Darling. If not, see <http://www.gnu.org/licenses/>.
1818+*/
1919+120#ifndef DYLD_THREADS_H
221#define DYLD_THREADS_H
322#include <stdint.h>