diff --git a/Pal/src/db_rtld.c b/Pal/src/db_rtld.c index 32914c55..da70f10f 100644 --- a/Pal/src/db_rtld.c +++ b/Pal/src/db_rtld.c @@ -548,242 +548,12 @@ int add_elf_object(void * addr, PAL_HANDLE handle, int type) static int relocate_elf_object (struct link_map *l); -#if CACHE_LOADED_BINARIES == 1 - -#define MAX_CACHED_LOADCMDS 32 -struct cached_elf_object { - PAL_NUM instance_id; - void * loader_addr; /* get the address of DkStreamOpen */ - struct link_map map; - char map_name[80]; - - struct cached_loadcmd { - void * mapstart; - unsigned long mapsize; - unsigned long mapoff; - int mapprot; - } loadcmds[MAX_CACHED_LOADCMDS]; - int nloadcmds; - - ElfW(Dyn) dyn[]; -}; - -void cache_elf_object (PAL_HANDLE handle, struct link_map * map) -{ - char uri[URI_MAX]; - unsigned long cached_size = 0; - - int ret = _DkStreamGetName(handle, uri, URI_MAX); - if (ret < 0) - return; - - strcpy_static(uri + ret, ".cached", URI_MAX - ret); - PAL_HANDLE cached_file; - - while (1) { - ret = _DkStreamOpen(&cached_file, uri, - PAL_ACCESS_RDWR, - PAL_SHARE_OWNER_W|PAL_SHARE_OWNER_R, - PAL_CREATE_TRY|PAL_CREATE_ALWAYS, 0); - - if (ret != -PAL_ERROR_STREAMEXIST) - break; - - if (_DkStreamOpen(&cached_file, uri, PAL_ACCESS_RDWR, 0, 0, 0) < 0) - return; - - ret = _DkStreamDelete(cached_file, 0); - _DkObjectClose(cached_file); - if (ret < 0) - return; - } - - if (ret < 0) - return; - - struct cached_elf_object * obj = NULL; - unsigned long obj_size = sizeof(struct cached_elf_object); - if (map->l_ld != map->l_real_ld) - obj_size += sizeof(ElfW(Dyn)) * map->l_ldnum; - obj_size = ALLOC_ALIGN_UP(obj_size); - - cached_size = obj_size; - ret = _DkStreamSetLength(cached_file, obj_size); - if (ret < 0) - goto out; - - ret = _DkStreamMap(cached_file, (void **) &obj, - PAL_PROT_READ|PAL_PROT_WRITE, 0, obj_size); - if (ret < 0) - goto out; - - obj->instance_id = pal_state.instance_id; - obj->loader_addr = (void *) DkStreamOpen; - memcpy(&obj->map, map, sizeof(struct link_map)); - if (map->l_ld != map->l_real_ld) { - obj->map.l_ld = NULL; - memcpy(obj->dyn, map->l_ld, sizeof(ElfW(Dyn)) * map->l_ldnum); - for (int i = 0; i < ARRAY_SIZE(obj->map.l_info); i++) - if (obj->map.l_info[i]) - obj->map.l_info[i] = (void *)obj->map.l_info[i] - (unsigned long)map->l_ld; - } - obj->map.l_name = NULL; - memcpy(obj->map_name, map->l_name, sizeof(obj->map_name)); - obj->nloadcmds = 0; - - const ElfW(Ehdr) * header = (void *) map->l_map_start; - const ElfW(Phdr) * phdr = (void *) header + header->e_phoff, * ph; - - for (ph = phdr ; ph < &phdr[header->e_phnum] ; ph++) - if (ph->p_type == PT_LOAD) { - assert(obj->nloadcmds < MAX_CACHED_LOADCMDS); - - void* mapstart = (void*)ALLOC_ALIGN_DOWN(map->l_addr + ph->p_vaddr); - void* mapend = (void*)ALLOC_ALIGN_UP(map->l_addr + ph->p_vaddr + ph->p_memsz); - unsigned long mapsize = mapend - mapstart; - int mapprot = 0; - void * cache_addr = NULL; - - if (ph->p_flags & PF_R) - mapprot |= PAL_PROT_READ; - if (ph->p_flags & PF_W) - mapprot |= PAL_PROT_WRITE; - if (ph->p_flags & PF_X) - mapprot |= PAL_PROT_EXEC; - - ret = _DkStreamSetLength(cached_file, cached_size + mapsize); - if (ret < 0) - goto out_mapped; - - ret = _DkStreamMap(cached_file, &cache_addr, - PAL_PROT_READ|PAL_PROT_WRITE, cached_size, - mapsize); - if (ret < 0) - goto out_mapped; - - obj->loadcmds[obj->nloadcmds].mapstart = mapstart; - obj->loadcmds[obj->nloadcmds].mapsize = mapsize; - obj->loadcmds[obj->nloadcmds].mapprot = mapprot; - obj->loadcmds[obj->nloadcmds].mapoff = cached_size; - obj->nloadcmds++; - cached_size += mapsize; - - memcpy(cache_addr, mapstart, mapsize); - - ret = _DkStreamUnmap(cache_addr, mapsize); - if (ret < 0) - goto out_mapped; - } - - ret = _DkStreamUnmap(obj, obj_size); - if (ret < 0) - return; - - _DkObjectClose(cached_file); - return; - -out_mapped: - _DkStreamUnmap(obj, obj_size); -out: - _DkStreamDelete(cached_file, 0); - _DkObjectClose(cached_file); -} - -struct link_map * check_cached_elf_object (PAL_HANDLE handle) -{ - char uri[URI_MAX]; - int ret = _DkStreamGetName(handle, uri, URI_MAX); - if (ret < 0) - return NULL; - - strcpy_static(uri + ret, ".cached", URI_MAX - ret); - PAL_HANDLE cached_file; - ret = _DkStreamOpen(&cached_file, uri, PAL_ACCESS_RDWR, 0, 0, 0); - if (ret < 0) - return NULL; - - struct cached_elf_object * obj = NULL; - unsigned long obj_size = ALLOC_ALIGN_UP(sizeof(struct cached_elf_object)); - - ret = _DkStreamMap(cached_file, (void **) &obj, - PAL_PROT_READ|PAL_PROT_WRITE|PAL_PROT_WRITECOPY, - 0, obj_size); - if (ret < 0) - goto out; - - /* we want to check if there is a previously cached one, but if the - * process is the first one, force to update the cached binary. */ - if (pal_state.instance_id != obj->instance_id) - goto out_mapped; - - if (!obj->map.l_ld) { - obj->map.l_ld = obj->dyn; - for (int i = 0; i < ARRAY_SIZE(obj->map.l_info); i++) - if (obj->map.l_info[i]) - obj->map.l_info[i] = (void*)obj->map.l_info[i] + (unsigned long)obj->map.l_ld; - } - - struct cached_loadcmd * l = obj->loadcmds; - struct cached_loadcmd * last = &obj->loadcmds[obj->nloadcmds - 1]; - - if (l < last) { - ret = _DkStreamMap(cached_file, &l->mapstart, - l->mapprot|PAL_PROT_WRITECOPY, - l->mapoff, - last->mapstart + last->mapsize - l->mapstart); - if (ret < 0) - goto out_more_mapped; - - ret = _DkVirtualMemoryProtect(l->mapstart + l->mapsize, - last->mapstart - (l->mapstart + l->mapsize), - PAL_PROT_NONE); - if (ret < 0) - goto out_more_mapped; - - l++; - } - - for ( ; l <= last ; l++) { - ret = _DkStreamMap(cached_file, &l->mapstart, - l->mapprot|PAL_PROT_WRITECOPY, - l->mapoff, - l->mapsize); - if (ret < 0) - goto out_more_mapped; - } - - if ((void *) DkStreamOpen != obj->loader_addr) { - for (int i = 0 ; i < obj->map.nrelocs ; i++) - *obj->map.relocs[i] += (void *) DkStreamOpen - obj->loader_addr; - } - - obj->map.l_name = obj->map_name; - _DkObjectClose(cached_file); - return &obj->map; - -out_more_mapped: - _DkStreamUnmap(obj->loadcmds[0].mapstart, - last->mapstart + last->mapsize - obj->loadcmds[0].mapstart); -out_mapped: - _DkStreamUnmap(obj, obj_size); -out: - _DkObjectClose(cached_file); - return NULL; -} -#endif /* CACHE_LOADED_BINARIES == 1 */ - int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type) { struct link_map * map = NULL; char fb[FILEBUF_SIZE], * errstring; int ret = 0; -#if CACHE_LOADED_BINARIES == 1 - map = check_cached_elf_object(handle); - if (map) - goto done; -#endif - /* Now we will start verify the file as a ELF header. This part of code is borrow from open_verify() */ ElfW(Ehdr) * ehdr = (ElfW(Ehdr) *) &fb; @@ -857,11 +627,6 @@ int load_elf_object_by_handle (PAL_HANDLE handle, enum object_type type) relocate_elf_object(map); -#if CACHE_LOADED_BINARIES == 1 - cache_elf_object(handle, map); -done: -#endif - /* append to list (to preserve order of libs specified in * manifest, e.g., loader.preload) */ diff --git a/Pal/src/dl-machine-x86_64.h b/Pal/src/dl-machine-x86_64.h index afd5ebaa..1fc1df0f 100644 --- a/Pal/src/dl-machine-x86_64.h +++ b/Pal/src/dl-machine-x86_64.h @@ -93,13 +93,6 @@ static void elf_machine_rela(struct link_map* l, Elf64_Rela* reloc, Elf64_Sym* s assert(sym); value = sym_map->l_addr + sym->st_value; } - -#if CACHE_LOADED_BINARIES == 1 - if (!sym_map || sym_map->l_type == OBJECT_RTLD) { - assert(l->nrelocs < NRELOCS); - l->relocs[l->nrelocs++] = reloc_addr; - } -#endif } #endif diff --git a/Pal/src/pal_defs.h b/Pal/src/pal_defs.h index da41c7fd..683f05a4 100644 --- a/Pal/src/pal_defs.h +++ b/Pal/src/pal_defs.h @@ -1,10 +1,6 @@ #ifndef PAL_DEFS_H #define PAL_DEFS_H -/* (Linux-only) enable caching loaded binaries for optimizing process creation - */ -#define CACHE_LOADED_BINARIES 0 /* default: disabled */ - /* statically allocate slab manager */ #define STATIC_SLAB 1 diff --git a/Pal/src/pal_rtld.h b/Pal/src/pal_rtld.h index 68bc7c36..a7a9c61a 100644 --- a/Pal/src/pal_rtld.h +++ b/Pal/src/pal_rtld.h @@ -87,12 +87,6 @@ struct link_map { const ElfW(Addr) * l_gnu_bitmask; const Elf32_Word * l_gnu_buckets; const Elf32_Word * l_gnu_chain_zero; - -#if CACHE_LOADED_BINARIES == 1 -#define NRELOCS 64 - ElfW(Addr) * relocs[NRELOCS]; - int nrelocs; -#endif }; struct link_gdb_map {