Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change how the mono search path is configured and change its default logic #57

Merged
merged 2 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,3 @@ The change was made for two reasons:

* Doorstop does not need to pass any arguments anymore. Instead, Doorstop passes all the information via environment variables.
* CoreCLR does not support easy method searching using wildcards yet.

## *Possibly* breaking: `target_assembly` directory is now always added to mono search path

In UnityDoorstop 3.x, the tool only loaded the `target_assembly` and left any other assembly resolving to the target assembly code.
**Starting Doorstop 4, `target_assembly`'s parent directory is set to mono DLL search path.**

This means that any additional assemblies that are placed into the same directory as `target_assembly` will receive priority during assembly resolving.
Note that this option for now only affects UnityMono as there is no similar search path priority available via current CoreCLR C hosting API.
1 change: 1 addition & 0 deletions assets/nix/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ ignore_disable_switch="0"
# (e.g. mscorlib is stripped in original game)
# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed
# Original Managed folder is added as a secondary folder in the search path
# To specify multiple paths, separate them with colons (:)
dll_search_path_override=""

# If 1, Mono debugger server will be enabled
Expand Down
1 change: 1 addition & 0 deletions assets/windows/doorstop_config.ini
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ ignore_disable_switch=false
# (e.g. mscorlib is stripped in original game)
# This option causes Mono to seek mscorlib and core libraries from a different folder before Managed
# Original Managed folder is added as a secondary folder in the search path
# To specify multiple paths, separate them with semicolons (;)
dll_search_path_override=

# If true, Mono debugger server will be enabled
Expand Down
62 changes: 49 additions & 13 deletions src/bootstrap.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,27 +134,65 @@ void *init_mono(const char *root_domain_name, const char *runtime_version) {
LOG("Overriding mono DLL search path");

size_t mono_search_path_len = strlen(root_dir) + 1;
char_t *target_path_full = get_full_path(config.target_assembly);
char_t *target_path_folder = get_folder_name(target_path_full);
mono_search_path_len += strlen(target_path_folder) + 1;
LOG("Adding %s to mono search path", target_path_folder);

char_t *override_dir_full = NULL;
bool_t has_override = config.mono_dll_search_path_override &&
strlen(config.mono_dll_search_path_override);
char_t *config_path_value = config.mono_dll_search_path_override;
bool_t has_override = config_path_value && strlen(config_path_value);
if (has_override) {
override_dir_full = get_full_path(config.mono_dll_search_path_override);
size_t path_start = 0;
override_dir_full = calloc(MAX_PATH, sizeof(char_t));
memset(override_dir_full, 0, MAX_PATH * sizeof(char_t));

bool_t found_path = FALSE;
for (size_t i = 0; i <= strlen(config_path_value); i++) {
char_t current_char = config_path_value[i];
if (current_char == *PATH_SEP || current_char == 0) {
if (i <= path_start) {
path_start++;
continue;
}

size_t path_len = i - path_start;
char_t *path = calloc(path_len + 1, sizeof(char_t));
strncpy(path, config_path_value + path_start, path_len);
path[path_len] = 0;

char_t *full_path = get_full_path(path);

if (strlen(override_dir_full) + strlen(full_path) + 2 >
MAX_PATH) {
LOG("Ignoring this root path because its absolute version "
"is too long: %s",
full_path);
free(path);
free(full_path);
path_start = i + 1;
continue;
}

if (found_path) {
strcat(override_dir_full, PATH_SEP);
}

strcat(override_dir_full, full_path);
LOG("Adding root path: %s", full_path);

free(path);
free(full_path);

found_path = TRUE;
path_start = i + 1;
}
}

mono_search_path_len += strlen(override_dir_full) + 1;
LOG("Adding root path: %s", override_dir_full);
}

char_t *mono_search_path = calloc(mono_search_path_len + 1, sizeof(char_t));
if (has_override) {
if (override_dir_full && strlen(override_dir_full)) {
strcat(mono_search_path, override_dir_full);
strcat(mono_search_path, PATH_SEP);
}
strcat(mono_search_path, target_path_folder);
strcat(mono_search_path, PATH_SEP);
strcat(mono_search_path, root_dir);

LOG("Mono search path: %s", mono_search_path);
Expand All @@ -166,8 +204,6 @@ void *init_mono(const char *root_domain_name, const char *runtime_version) {
if (override_dir_full) {
free(override_dir_full);
}
free(target_path_full);
free(target_path_folder);

hook_mono_jit_parse_options(0, NULL);

Expand Down
4 changes: 2 additions & 2 deletions src/nix/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ void load_config() {
try_get_env("DOORSTOP_MONO_DEBUG_ADDRESS", TEXT("127.0.0.1:10000"),
&config.mono_debug_address);
get_env_path("DOORSTOP_TARGET_ASSEMBLY", &config.target_assembly);
get_env_path("DOORSTOP_MONO_DLL_SEARCH_PATH_OVERRIDE",
&config.mono_dll_search_path_override);
try_get_env("DOORSTOP_MONO_DLL_SEARCH_PATH_OVERRIDE", TEXT(""),
&config.mono_dll_search_path_override);
get_env_path("DOORSTOP_CLR_RUNTIME_CORECLR_PATH",
&config.clr_runtime_coreclr_path);
get_env_path("DOORSTOP_CLR_CORLIB_DIR", &config.clr_corlib_dir);
Expand Down
6 changes: 3 additions & 3 deletions src/windows/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ static inline void init_config_file() {
load_path_file(config_path, TEXT("General"), TEXT("target_assembly"),
DEFAULT_TARGET_ASSEMBLY, &config.target_assembly);

load_path_file(config_path, TEXT("UnityMono"),
TEXT("dll_search_path_override"), NULL,
&config.mono_dll_search_path_override);
load_str_file(config_path, TEXT("UnityMono"),
TEXT("dll_search_path_override"), TEXT(""),
&config.mono_dll_search_path_override);
load_bool_file(config_path, TEXT("UnityMono"), TEXT("debug_enabled"),
TEXT("false"), &config.mono_debug_enabled);
load_bool_file(config_path, TEXT("UnityMono"), TEXT("debug_suspend"),
Expand Down
Loading