static void * do_actual_load(const char * filename, elf_t * lib, int flags) { (void)flags; if (!lib) { last_error = "could not open library (not found, or other failure)"; return NULL; } size_t lib_size = object_calculate_size(lib); if (lib_size < 4096) { lib_size = 4096; } uintptr_t load_addr = (uintptr_t)malloc(lib_size); object_load(lib, load_addr); object_postload(lib); node_t * item; while (item = list_pop(lib->dependencies)) { elf_t * lib = open_object(item->value); if (!lib) { free((void *)load_addr); last_error = "Failed to load a dependency."; return NULL; } if (!lib->loaded) { do_actual_load(item->value, lib, 0); TRACE_LD("Loaded %s at 0x%x", item->value, lib->base); } } TRACE_LD("Relocating %s", filename); object_relocate(lib); fclose(lib->file); if (lib->ctors) { for (size_t i = 0; i < lib->ctors_size; i += sizeof(uintptr_t)) { TRACE_LD(" 0x%x()", lib->ctors[i]); lib->ctors[i](); } } if (lib->init) { lib->init(); } return (void *)lib; }
static DiaObject * textobj_load(ObjectNode obj_node, int version, DiaContext *ctx) { Textobj *textobj; DiaObject *obj; AttributeNode attr; Point startpoint = {0.0, 0.0}; textobj = g_malloc0(sizeof(Textobj)); obj = &textobj->object; obj->type = &textobj_type; obj->ops = &textobj_ops; object_load(obj, obj_node, ctx); attr = object_find_attribute(obj_node, "text"); if (attr != NULL) { textobj->text = data_text(attribute_first_data(attr), ctx); } else { DiaFont* font = dia_font_new_from_style(DIA_FONT_MONOSPACE,1.0); textobj->text = new_text("", font, 1.0, &startpoint, &color_black, ALIGN_CENTER); dia_font_unref(font); } attr = object_find_attribute(obj_node, "valign"); if (attr != NULL) textobj->vert_align = data_enum(attribute_first_data(attr), ctx); else if (version == 0) { textobj->vert_align = VALIGN_FIRST_LINE; } /* default visibility must be off to keep compatibility */ textobj->fill_color = attributes_get_background(); attr = object_find_attribute(obj_node, "fill_color"); if (attr) data_color(attribute_first_data(attr), &textobj->fill_color, ctx); attr = object_find_attribute(obj_node, "show_background"); if (attr) textobj->show_background = data_boolean(attribute_first_data(attr), ctx); else textobj->show_background = FALSE; object_init(obj, 1, 0); obj->handles[0] = &textobj->text_handle; textobj->text_handle.id = HANDLE_TEXT; textobj->text_handle.type = HANDLE_MAJOR_CONTROL; textobj->text_handle.connect_type = HANDLE_CONNECTABLE; textobj->text_handle.connected_to = NULL; textobj_update_data(textobj); return &textobj->object; }
void polyconn_load(PolyConn *poly, ObjectNode obj_node, DiaContext *ctx) /* NOTE: Does object_init() */ { int i; AttributeNode attr; DataNode data; DiaObject *obj = &poly->object; object_load(obj, obj_node, ctx); attr = object_find_attribute(obj_node, "poly_points"); if (attr != NULL) poly->numpoints = attribute_num_data(attr); else poly->numpoints = 0; object_init(obj, poly->numpoints, 0); data = attribute_first_data(attr); poly->points = g_malloc(poly->numpoints*sizeof(Point)); for (i=0;i<poly->numpoints;i++) { data_point(data, &poly->points[i], ctx); data = data_next(data); } obj->handles[0] = g_malloc(sizeof(Handle)); obj->handles[0]->connect_type = HANDLE_CONNECTABLE; obj->handles[0]->connected_to = NULL; obj->handles[0]->type = HANDLE_MAJOR_CONTROL; obj->handles[0]->id = HANDLE_MOVE_STARTPOINT; obj->handles[poly->numpoints-1] = g_malloc(sizeof(Handle)); obj->handles[poly->numpoints-1]->connect_type = HANDLE_CONNECTABLE; obj->handles[poly->numpoints-1]->connected_to = NULL; obj->handles[poly->numpoints-1]->type = HANDLE_MAJOR_CONTROL; obj->handles[poly->numpoints-1]->id = HANDLE_MOVE_ENDPOINT; for (i=1;i<poly->numpoints-1;i++) { obj->handles[i] = g_malloc(sizeof(Handle)); setup_handle(obj->handles[i], PC_HANDLE_CORNER); } polyconn_update_data(poly); }
/** * * rct2: 0x006AA0C6 */ int object_read_and_load_entries(FILE *file) { object_unload_all(); int i, j; rct_object_entry *entries; // Read all the object entries entries = malloc(OBJECT_ENTRY_COUNT * sizeof(rct_object_entry)); sawyercoding_read_chunk(file, (uint8*)entries); // Load each object for (i = 0; i < OBJECT_ENTRY_COUNT; i++) { if (!check_object_entry(&entries[i])) continue; // Get entry group index int entryGroupIndex = i; for (j = 0; j < countof(object_entry_group_counts); j++) { if (entryGroupIndex < object_entry_group_counts[j]) break; entryGroupIndex -= object_entry_group_counts[j]; } // Load the obect if (!object_load(entryGroupIndex, &entries[i])) { // Failed to load the object free(entries); memcpy((char*)0x13CE952, entries[i].name, 8); object_unload_all(); return 0; } } free(entries); return 1; }
void vfs_mount(const struct volume_metadata *md, const char *path) { const char *argv[] = { "cloudfs", path, "-f", "-s", "-o", "hard_remove", NULL }; notice("Volume mounting on %s", path); misc_maybe_fork(); object_load(); vfs_fsid = unique_id(); if (fuse_main(sizearr(argv) - 1, (char**) argv, &vfs_oper, NULL) != 0) warning("FUSE failed"); notice("Volume disconnecting"); vfs_fd_clear(); vfs_node_clear(); object_unload(); }
/** * * rct2: 0x006A8B40 */ void object_list_load() { HANDLE hFindFile; WIN32_FIND_DATAA findFileData; int totalFiles = 0, totalFileSize = 0, fileDateModifiedChecksum = 0; char pluginPath[MAX_PATH]; get_plugin_path(pluginPath); // Enumerate through each object in the directory hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), &findFileData); if (hFindFile != INVALID_HANDLE_VALUE) { do { totalFiles++; totalFileSize += findFileData.nFileSizeLow; fileDateModifiedChecksum ^= findFileData.ftLastWriteTime.dwLowDateTime ^ findFileData.ftLastWriteTime.dwHighDateTime; fileDateModifiedChecksum = ror32(fileDateModifiedChecksum, 5); } while (FindNextFile(hFindFile, &findFileData)); FindClose(hFindFile); } totalFiles = ror32(totalFiles, 24); totalFiles = (totalFiles & ~0xFF) | 1; totalFiles = rol32(totalFiles, 24); // Read plugin header rct_plugin_header pluginHeader; FILE *file = fopen(pluginPath, "rb"); if (file != NULL) { if (fread(&pluginHeader, sizeof(pluginHeader), 1, file) == 1) { // Check if object repository has changed in anyway if ( totalFiles == pluginHeader.total_files && totalFileSize == pluginHeader.total_file_size && fileDateModifiedChecksum == pluginHeader.date_modified_checksum ) { // Dispose installed object list if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) { rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*)); RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) = -1; } // Read installed object list RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(pluginHeader.object_list_size); if (fread(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), pluginHeader.object_list_size, 1, file) == 1) { RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = pluginHeader.object_list_no_items; fclose(file); sub_6A9FC0(); object_list_examine(); return; } } } fclose(file); } // Reload object list RCT2_GLOBAL(0x00F42B94, uint32) = totalFiles; RCT2_GLOBAL(0x00F42B98, uint32) = totalFileSize; RCT2_GLOBAL(0x00F42B9C, uint32) = fileDateModifiedChecksum; //RCT2_CALLPROC_EBPSAFE(0x006A8D8F); int eax = 3161; if (RCT2_GLOBAL(0x9AA00D, uint8) != 0){ eax = 3160; RCT2_GLOBAL(0x9AA00D, uint8) = 0; } // File count removed and replaced by variable // RCT2_GLOBAL(0xF42BA8, uint32) = 0; uint32 file_count = 0; // Progress bar related. RCT2_GLOBAL(0xF42BD8, uint8) = 0; sub_6A9FC0(); // Dispose installed object list if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) != -1) { rct2_free(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*)); RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, sint32) = -1; } RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32) = 0; RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_malloc(4096); if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){ RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0); return; } uint32 installed_buffer_size = 0x1000; uint32 current_item_offset = 0; hFindFile = FindFirstFile(RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), &findFileData); if (hFindFile == INVALID_HANDLE_VALUE){ //6a92ea This hasn't been implemented but there isn't much point. // It would make a empty object file if no files found. return; } for (uint8 first_time = 1; first_time || FindNextFile(hFindFile, &findFileData);){ first_time = 0; RCT2_GLOBAL(0x9ABD98, HANDLE) = hFindFile; file_count++; // update progress bar. eax = (file_count << 8) / ((RCT2_GLOBAL(0xF42B94, uint32) & 0xFFFFFF) + 1); if ((eax & 0xFF) != RCT2_GLOBAL(0xF42BD8, uint8)){ RCT2_GLOBAL(0xF42BD8, uint8) = eax & 0xFF; // update progress bar } if ((installed_buffer_size - current_item_offset) <= 2842){ installed_buffer_size += 0x1000; RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*) = rct2_realloc(RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, void*), installed_buffer_size); if (RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, int) == -1){ RCT2_CALLPROC_X(0x006E3838, 0x343, 0xC5A, 0, 0, 0, 0, 0); return; } } char path[260]; subsitute_path(path, RCT2_ADDRESS(RCT2_ADDRESS_OBJECT_DATA_PATH, char), findFileData.cFileName); FILE *obj_file = fopen(path, "rb"); if (obj_file == NULL){ continue; } rct_object_entry* entry = RCT2_ADDRESS(0xF42B74, rct_object_entry); if (fread(entry, sizeof(rct_object_entry), 1, obj_file) != 1){ fclose(obj_file); continue; } fclose(obj_file); RCT2_GLOBAL(0xF42BC4, uint32) = current_item_offset; uint8* installed_entry_pointer = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset; memcpy(installed_entry_pointer, entry, sizeof(rct_object_entry)); installed_entry_pointer += sizeof(rct_object_entry); strcpy(installed_entry_pointer, findFileData.cFileName); while (*installed_entry_pointer++); *((sint32*)installed_entry_pointer) = -1; *(installed_entry_pointer + 4) = 0; *((sint32*)(installed_entry_pointer + 5)) = 0; *((uint16*)(installed_entry_pointer + 9)) = 0; *((uint32*)(installed_entry_pointer + 11)) = 0; RCT2_GLOBAL(0x9ADAF0, uint32) = 0xF26E; RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)++; // This is a variable used by object_load to decide if it should // use object_paint on the entry. RCT2_GLOBAL(0x9ADAFD, uint8) = 1; // Probably used by object paint. RCT2_GLOBAL(0x9ADAF4, uint32) = 0xF42BDB; int chunk_size; if (!object_load(-1, entry, &chunk_size)){ RCT2_GLOBAL(0x9ADAF4, sint32) = -1; RCT2_GLOBAL(0x9ADAFD, uint8) = 0; RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--; continue; } // See above note RCT2_GLOBAL(0x9ADAF4, sint32) = -1; RCT2_GLOBAL(0x9ADAFD, uint8) = 0; if ((entry->flags & 0xF0) == 0x80){ RCT2_GLOBAL(0xF42B70, uint32)++; if (RCT2_GLOBAL(0xF42B70, uint32) > 772){ RCT2_GLOBAL(0xF42B70, uint32)--; RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--; continue; } } *((sint32*)installed_entry_pointer) = chunk_size; installed_entry_pointer += 4; uint8* chunk = RCT2_GLOBAL(RCT2_ADDRESS_CURR_OBJECT_CHUNK_POINTER, uint8*); // Loaded in object_load // When made of two parts i.e Wooden Roller Coaster (Dream Woodie Cars); if ((entry->flags & 0xF) == 0 && !(*((uint32*)(chunk + 8)) & 0x1000)){ rct_string_id obj_string = chunk[12]; if (obj_string == 0xFF){ obj_string = chunk[13]; if (obj_string == 0xFF){ obj_string = chunk[14]; } } obj_string += 2; format_string(installed_entry_pointer, obj_string, 0); strcat(installed_entry_pointer, "\t ("); strcat(installed_entry_pointer, language_get_string(RCT2_GLOBAL(0xF42BBC, uint32))); strcat(installed_entry_pointer, ")"); while (*installed_entry_pointer++); } else{ strcpy(installed_entry_pointer, language_get_string(RCT2_GLOBAL(0xF42BBC, uint32))); while (*installed_entry_pointer++); } *((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0x9ADAF0, uint32) - 0xF26E; installed_entry_pointer += 4; uint8* esi = RCT2_ADDRESS(0xF42BDB, uint8); int cl = *esi++; *installed_entry_pointer++ = cl; if (cl){ memcpy(installed_entry_pointer, esi, cl*sizeof(rct_object_entry)); installed_entry_pointer += cl*sizeof(rct_object_entry); } cl = *esi++; *installed_entry_pointer++ = cl; if (cl){ memcpy(installed_entry_pointer, esi, cl*sizeof(rct_object_entry)); installed_entry_pointer += cl*sizeof(rct_object_entry); } *((uint32*)installed_entry_pointer) = RCT2_GLOBAL(0xF433DD, uint32); installed_entry_pointer += 4; int size_of_object = installed_entry_pointer - RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) - current_item_offset; object_unload(entry->flags & 0xF, (rct_object_entry_extended*)entry); // Return pointer to start of entry installed_entry_pointer -= size_of_object; uint8* copied_entry = RCT2_ADDRESS(0x140E9AC, uint8); size_of_object = object_copy(copied_entry, installed_entry_pointer); RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)--; copied_entry += sizeof(rct_object_entry); // Skip filename while (*copied_entry++); // Skip copied_entry += 4; installed_entry_pointer = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*); for (uint32 i = 0; i < RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32); ++i){ uint8* temp_installed_entry = installed_entry_pointer; temp_installed_entry += sizeof(rct_object_entry); // Skip filename while (*temp_installed_entry++); // Skip temp_installed_entry += 4; if (strcmp(temp_installed_entry, copied_entry) <= 0)break; installed_entry_pointer = (uint8*)(object_get_next((rct_object_entry*)installed_entry_pointer)); } // Difference to new location int no_bytes_to_move = RCT2_GLOBAL(RCT2_ADDRESS_INSTALLED_OBJECT_LIST, uint8*) + current_item_offset - installed_entry_pointer; uint8* curr_location = installed_entry_pointer; uint8* move_location = installed_entry_pointer + size_of_object; if (no_bytes_to_move){ memmove(move_location, curr_location, no_bytes_to_move); } copied_entry = RCT2_ADDRESS(0x140E9AC, uint8); memcpy(installed_entry_pointer, copied_entry, size_of_object); current_item_offset += size_of_object; RCT2_GLOBAL(RCT2_ADDRESS_OBJECT_LIST_NO_ITEMS, uint32)++; }
static DiaObject * compound_load (ObjectNode obj_node, int version, DiaContext *ctx) { Compound * comp; DiaObject * obj; AttributeNode attr; DataNode data; gint i, num_handles; comp = g_new0 (Compound, 1); obj = &comp->object; /* load the objects position and bounding box */ object_load (obj, obj_node, ctx); /* init the object */ obj->type = &compound_type; obj->ops = &compound_ops; /* load the object's handles and its positions */ attr = object_find_attribute (obj_node, "comp_points"); g_assert (attr != NULL); num_handles = attribute_num_data (attr); g_assert (num_handles >= 3); /* allocate space for object handles and connectionpoints point arrays */ object_init (obj, num_handles, 1); data = attribute_first_data (attr); /* init our mount_point */ setup_mount_point (&comp->mount_point, obj, NULL); data_point (data, &comp->mount_point.pos, ctx); obj->connections[0] = &comp->mount_point; /* now init the handles */ comp->num_arms = num_handles-1; comp->handles = g_new0 (Handle, num_handles); setup_handle (&comp->handles[0], HANDLE_MOUNT_POINT, HANDLE_MAJOR_CONTROL, HANDLE_NONCONNECTABLE); comp->handles[0].pos = comp->mount_point.pos; obj->handles[0] = &comp->handles[0]; data = data_next (data); for (i = 1; i < num_handles; i++) { obj->handles[i] = &comp->handles[i]; setup_handle (obj->handles[i], HANDLE_ARM, HANDLE_MINOR_CONTROL, HANDLE_CONNECTABLE_NOBREAK); data_point (data, &obj->handles[i]->pos, ctx); data = data_next (data); } /* load remainding properties */ attr = object_find_attribute (obj_node, PROP_STDTYPE_LINE_WIDTH); if (attr == NULL) comp->line_width = 0.1; else comp->line_width = data_real (attribute_first_data (attr), ctx); attr = object_find_attribute (obj_node, "line_colour"); if (attr == NULL) comp->line_color = color_black; else data_color (attribute_first_data (attr), &comp->line_color, ctx); compound_update_data (comp); compound_sanity_check (comp, "Loaded"); return &comp->object; }
int main(int argc, char * argv[]) { char * file = argv[1]; size_t arg_offset = 1; if (!strcmp(argv[1], "-e")) { arg_offset = 3; file = argv[2]; } char * trace_ld_env = getenv("LD_DEBUG"); if (trace_ld_env && (!strcmp(trace_ld_env,"1") || !strcmp(trace_ld_env,"yes"))) { __trace_ld = 1; } dumb_symbol_table = hashmap_create(10); glob_dat = hashmap_create(10); objects_map = hashmap_create(10); ld_exports_t * ex = ld_builtin_exports; while (ex->name) { hashmap_set(dumb_symbol_table, ex->name, ex->symbol); ex++; } elf_t * main_obj = open_object(file); _main_obj = main_obj; if (!main_obj) { fprintf(stderr, "%s: error: failed to open object '%s'.\n", argv[0], file); return 1; } size_t main_size = object_calculate_size(main_obj); uintptr_t end_addr = object_load(main_obj, 0x0); object_postload(main_obj); object_find_copy_relocations(main_obj); hashmap_t * libs = hashmap_create(10); list_t * ctor_libs = list_create(); list_t * init_libs = list_create(); TRACE_LD("Loading dependencies."); node_t * item; while (item = list_pop(main_obj->dependencies)) { while (end_addr & 0xFFF) { end_addr++; } char * lib_name = item->value; if (!strcmp(lib_name, "libg.so")) goto nope; elf_t * lib = open_object(lib_name); if (!lib) { fprintf(stderr, "Failed to load dependency '%s'.\n", lib_name); return 1; } hashmap_set(libs, lib_name, lib); TRACE_LD("Loading %s at 0x%x", lib_name, end_addr); end_addr = object_load(lib, end_addr); object_postload(lib); TRACE_LD("Relocating %s", lib_name); object_relocate(lib); fclose(lib->file); /* Execute constructors */ if (lib->ctors) { list_insert(ctor_libs, lib); } if (lib->init) { list_insert(init_libs, lib); } nope: free(item); } TRACE_LD("Relocating main object"); object_relocate(main_obj); TRACE_LD("Placing heap at end"); while (end_addr & 0xFFF) { end_addr++; } char * ld_no_ctors = getenv("LD_DISABLE_CTORS"); if (ld_no_ctors && (!strcmp(ld_no_ctors,"1") || !strcmp(ld_no_ctors,"yes"))) { TRACE_LD("skipping ctors because LD_DISABLE_CTORS was set"); } else { foreach(node, ctor_libs) { elf_t * lib = node->value; if (lib->ctors) { TRACE_LD("Executing ctors..."); for (size_t i = 0; i < lib->ctors_size; i += sizeof(uintptr_t)) { TRACE_LD(" 0x%x()", lib->ctors[i]); lib->ctors[i](); } } } }