mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
f811fc4753
commit
c320cb59e2
|
@ -32,7 +32,7 @@ type
|
|||
sym_out :p_elf64_sym;
|
||||
end;
|
||||
|
||||
function do_dlsym(obj:p_lib_info;symbol,modname:pchar;flags:DWORD):Pointer;
|
||||
function do_dlsym(obj:p_lib_info;symbol,libname:pchar;flags:DWORD):Pointer;
|
||||
function find_symdef(symnum:QWORD;refobj:p_lib_info;var defobj_out:p_lib_info;flags:DWORD;cache:p_SymCache):p_elf64_sym;
|
||||
|
||||
implementation
|
||||
|
@ -133,8 +133,6 @@ var
|
|||
elm:p_Objlist_Entry;
|
||||
def:p_elf64_sym;
|
||||
defobj:p_lib_info;
|
||||
lib_entry:p_Lib_Entry;
|
||||
offset:QWORD;
|
||||
str:pchar;
|
||||
begin
|
||||
Result:=0;
|
||||
|
@ -164,7 +162,7 @@ begin
|
|||
begin
|
||||
if not donelist_check(dlp,elm^.obj) then
|
||||
begin
|
||||
if (modname=nil) then
|
||||
if (modname=nil) then //any module?
|
||||
begin
|
||||
_symlook_obj:
|
||||
req1:=req^;
|
||||
|
@ -181,20 +179,10 @@ begin
|
|||
end;
|
||||
end else
|
||||
begin
|
||||
lib_entry:=TAILQ_FIRST(@elm^.obj^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
str:=get_mod_name(elm^.obj,0); //export=0
|
||||
if (StrComp(str,modname)=0) then
|
||||
begin
|
||||
if (lib_entry^.dval.id=0) then //export?
|
||||
begin
|
||||
offset:=lib_entry^.dval.name_offset;
|
||||
str:=obj_get_str(elm^.obj,offset);
|
||||
if (StrComp(str,modname)=0) then
|
||||
begin
|
||||
goto _symlook_obj;
|
||||
end;
|
||||
Break;
|
||||
end;
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
goto _symlook_obj;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -222,7 +210,6 @@ begin
|
|||
if (req^.defobj_out=nil) or
|
||||
(ELF64_ST_BIND(req^.sym_out^.st_info)=STB_WEAK) then
|
||||
begin
|
||||
|
||||
Result:=symlook_list(@req1, dynlibs_info.list_main, donelist);
|
||||
|
||||
if (Result=0) then
|
||||
|
@ -235,7 +222,6 @@ begin
|
|||
Assert(req^.defobj_out<>nil,'req->defobj_out is NULL #1');
|
||||
end;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
//Search all DAGs whose roots are RTLD_GLOBAL objects.
|
||||
|
@ -318,42 +304,23 @@ begin
|
|||
Exit(ESRCH);
|
||||
end;
|
||||
|
||||
function do_dlsym(obj:p_lib_info;symbol,modname:pchar;flags:DWORD):Pointer;
|
||||
function do_dlsym(obj:p_lib_info;symbol,libname:pchar;flags:DWORD):Pointer;
|
||||
var
|
||||
req:t_SymLook;
|
||||
lib_entry:p_Lib_Entry;
|
||||
offset:QWORD;
|
||||
base64:RawByteString;
|
||||
donelist:t_DoneList;
|
||||
err:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
if TAILQ_EMPTY(@obj^.mod_table) then
|
||||
begin
|
||||
req.modname:=nil;
|
||||
end else
|
||||
begin
|
||||
req.modname:=nil;
|
||||
lib_entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (lib_entry^.dval.id=0) then //export?
|
||||
begin
|
||||
offset:=lib_entry^.dval.name_offset;
|
||||
req.modname:=obj_get_str(obj,offset);
|
||||
Break;
|
||||
end;
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
end;
|
||||
end;
|
||||
|
||||
req:=Default(t_SymLook);
|
||||
req.modname:=get_mod_name(obj,0); //export=0
|
||||
req.flags:=flags or SYMLOOK_DLSYM;
|
||||
|
||||
if ((flags and SYMLOOK_BASE64)=0) then
|
||||
begin
|
||||
req.libname:=modname;
|
||||
if (modname=nil) then
|
||||
req.libname:=libname;
|
||||
if (libname=nil) then
|
||||
begin
|
||||
req.libname:=req.modname;
|
||||
end;
|
||||
|
@ -365,11 +332,8 @@ begin
|
|||
req.modname:=nil;
|
||||
end;
|
||||
|
||||
req.symbol :=nil;
|
||||
req.name :=symbol;
|
||||
//req.hash :=elf_hash(@req);
|
||||
req.defobj_out:=nil;
|
||||
req.sym_out :=nil;
|
||||
req.obj :=obj;
|
||||
|
||||
donelist:=Default(t_DoneList);
|
||||
|
@ -407,6 +371,7 @@ var
|
|||
defobj:p_lib_info;
|
||||
str:pchar;
|
||||
err:Integer;
|
||||
ST_BIND:Integer;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
|
@ -431,13 +396,14 @@ begin
|
|||
|
||||
str:=obj_get_str(refobj,ref^.st_name);
|
||||
|
||||
if (ELF64_ST_BIND(ref^.st_info)=STB_LOCAL) then
|
||||
ST_BIND:=ELF64_ST_BIND(ref^.st_info);
|
||||
if (ST_BIND=STB_LOCAL) then
|
||||
begin
|
||||
def :=ref;
|
||||
defobj:=refobj;
|
||||
end else
|
||||
begin
|
||||
if (ELF64_ST_TYPE(ref^.st_info)=STT_SECTION) then
|
||||
if (ST_BIND=STT_SECTION) then
|
||||
begin
|
||||
Writeln(StdErr,'find_symdef:',refobj^.lib_path,': Bogus symbol table entry ',symnum);
|
||||
end;
|
||||
|
|
|
@ -37,7 +37,7 @@ function sys_dynlib_dlsym(handle:Integer;symbol:pchar;addrp:ppointer):Integer;
|
|||
label
|
||||
_exit;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
flags:Integer;
|
||||
ptr:Pointer;
|
||||
|
||||
|
@ -56,8 +56,8 @@ begin
|
|||
|
||||
dynlibs_lock;
|
||||
|
||||
lib:=find_obj_by_handle(handle);
|
||||
if (lib=nil) then
|
||||
obj:=find_obj_by_handle(handle);
|
||||
if (obj=nil) then
|
||||
begin
|
||||
Result:=ESRCH;
|
||||
goto _exit;
|
||||
|
@ -70,7 +70,7 @@ begin
|
|||
flags:=SYMLOOK_BASE64;
|
||||
end;
|
||||
|
||||
ptr:=do_dlsym(lib,@fsym,nil,flags);
|
||||
ptr:=do_dlsym(obj,@fsym,nil,flags);
|
||||
|
||||
if (ptr=nil) then
|
||||
begin
|
||||
|
@ -119,7 +119,7 @@ var
|
|||
len:ptruint;
|
||||
fname:array[0..1024-1] of char;
|
||||
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
key:Integer;
|
||||
allocs:Boolean;
|
||||
begin
|
||||
|
@ -140,32 +140,32 @@ begin
|
|||
|
||||
dynlibs_lock;
|
||||
|
||||
lib:=nil;
|
||||
Result:=load_prx(@fname,flags or ord(budget_ptype_caller=0),lib);
|
||||
obj:=nil;
|
||||
Result:=load_prx(@fname,flags or ord(budget_ptype_caller=0),obj);
|
||||
if (Result=0) then
|
||||
begin
|
||||
allocs:=(lib^.id<=0);
|
||||
allocs:=(obj^.id<=0);
|
||||
|
||||
if (lib^.ref_count < 2) then
|
||||
if (obj^.ref_count < 2) then
|
||||
begin
|
||||
if not alloc_obj_id(lib) then
|
||||
if not alloc_obj_id(obj) then
|
||||
begin
|
||||
//unload_prx(lib);
|
||||
unload_prx(obj);
|
||||
Result:=EAGAIN;
|
||||
goto _exit;
|
||||
end;
|
||||
end;
|
||||
key:=lib^.id;
|
||||
key:=obj^.id;
|
||||
|
||||
Result:=copyout(@key,pRes,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
if allocs then
|
||||
begin
|
||||
free_obj_id(lib^.id);
|
||||
lib^.id:=0;
|
||||
free_obj_id(obj^.id);
|
||||
obj^.id:=0;
|
||||
end;
|
||||
//unload_prx(lib);
|
||||
unload_prx(obj);
|
||||
Result:=EFAULT;
|
||||
end;
|
||||
end;
|
||||
|
@ -178,7 +178,7 @@ end;
|
|||
|
||||
function sys_dynlib_load_prx(handle:Integer):Integer;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
ref,id:Integer;
|
||||
begin
|
||||
if not_dynamic then
|
||||
|
@ -189,15 +189,16 @@ begin
|
|||
|
||||
dynlibs_lock;
|
||||
|
||||
lib:=find_obj_id(handle);
|
||||
if (lib=nil) then
|
||||
obj:=find_obj_id(handle);
|
||||
if (obj=nil) then
|
||||
begin
|
||||
Result:=ESRCH;
|
||||
end else
|
||||
begin
|
||||
ref:=lib^.ref_count;
|
||||
id :=lib^.id;
|
||||
//Result:=unload_prx(lib);
|
||||
ref:=obj^.ref_count;
|
||||
id :=obj^.id;
|
||||
//
|
||||
Result:=unload_prx(obj);
|
||||
//
|
||||
if (ref=1) then
|
||||
begin
|
||||
|
|
|
@ -745,7 +745,7 @@ end;
|
|||
|
||||
function dynlib_proc_initialize_step1(imgp:p_image_params):Integer;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
text_addr:Pointer;
|
||||
eh_frame_addr:Pointer;
|
||||
eh_frame_size:QWORD;
|
||||
|
@ -766,28 +766,28 @@ begin
|
|||
dynlibs_info.tls_max :=1;
|
||||
//dynlibs_info.bits :=0;
|
||||
|
||||
lib:=obj_new();
|
||||
lib^.mainprog:=1;
|
||||
lib^.relocbase:=imgp^.reloc_base;
|
||||
obj:=obj_new();
|
||||
obj^.mainprog:=1;
|
||||
obj^.relocbase:=imgp^.reloc_base;
|
||||
|
||||
text_addr:=g_vmspace.vm_taddr;
|
||||
|
||||
lib^.map_base:=text_addr;
|
||||
obj^.map_base:=text_addr;
|
||||
|
||||
lib^.text_size:=g_vmspace.vm_tsize * PAGE_SIZE;
|
||||
lib^.data_addr:=g_vmspace.vm_daddr;
|
||||
lib^.data_size:=g_vmspace.vm_dsize * PAGE_SIZE;
|
||||
obj^.text_size:=g_vmspace.vm_tsize * PAGE_SIZE;
|
||||
obj^.data_addr:=g_vmspace.vm_daddr;
|
||||
obj^.data_size:=g_vmspace.vm_dsize * PAGE_SIZE;
|
||||
|
||||
lib^.map_size :=((QWORD(lib^.data_addr) + lib^.data_size + $3fff) and QWORD($ffffffffffffc000)) - QWORD(text_addr);
|
||||
obj^.map_size :=((QWORD(obj^.data_addr) + obj^.data_size + $3fff) and QWORD($ffffffffffffc000)) - QWORD(text_addr);
|
||||
|
||||
lib^.relro_addr:=imgp^.relro_addr;
|
||||
lib^.relro_size:=imgp^.relro_size;
|
||||
obj^.relro_addr:=imgp^.relro_addr;
|
||||
obj^.relro_size:=imgp^.relro_size;
|
||||
|
||||
lib^.tls_index :=1;
|
||||
lib^.tls_size :=imgp^.tls_size;
|
||||
lib^.tls_align :=imgp^.tls_align;
|
||||
lib^.tls_init_size:=imgp^.tls_init_size;
|
||||
lib^.tls_init_addr:=imgp^.tls_init_addr;
|
||||
obj^.tls_index :=1;
|
||||
obj^.tls_size :=imgp^.tls_size;
|
||||
obj^.tls_align :=imgp^.tls_align;
|
||||
obj^.tls_init_size:=imgp^.tls_init_size;
|
||||
obj^.tls_init_addr:=imgp^.tls_init_addr;
|
||||
|
||||
eh_frame_addr:=nil;
|
||||
eh_frame_size:=0;
|
||||
|
@ -795,7 +795,7 @@ begin
|
|||
if (elf64_get_eh_frame_info(imgp^.eh_frame_hdr_addr,
|
||||
imgp^.eh_frame_hdr_size,
|
||||
0,
|
||||
lib^.text_size + QWORD(text_addr),
|
||||
obj^.text_size + QWORD(text_addr),
|
||||
@eh_frame_addr,
|
||||
@eh_frame_size)<>0) then
|
||||
begin
|
||||
|
@ -803,31 +803,31 @@ begin
|
|||
eh_frame_size:=0;
|
||||
end;
|
||||
|
||||
lib^.eh_frame_hdr_addr:=imgp^.eh_frame_hdr_addr;
|
||||
lib^.eh_frame_hdr_size:=imgp^.eh_frame_hdr_size;
|
||||
lib^.eh_frame_addr :=eh_frame_addr;
|
||||
lib^.eh_frame_size :=eh_frame_size;
|
||||
obj^.eh_frame_hdr_addr:=imgp^.eh_frame_hdr_addr;
|
||||
obj^.eh_frame_hdr_size:=imgp^.eh_frame_hdr_size;
|
||||
obj^.eh_frame_addr :=eh_frame_addr;
|
||||
obj^.eh_frame_size :=eh_frame_size;
|
||||
|
||||
lib^.entry_addr :=imgp^.entry_addr;
|
||||
obj^.entry_addr :=imgp^.entry_addr;
|
||||
|
||||
_set_lib_path(lib,imgp^.execpath);
|
||||
obj_set_lib_path(obj,imgp^.execpath);
|
||||
|
||||
//*(byte *)&lib^.rtld_flags:=*(byte *)&lib^.rtld_flags | 1;
|
||||
//*(byte *)&obj^.rtld_flags:=*(byte *)&obj^.rtld_flags | 1;
|
||||
|
||||
lib^.loaded:=4;
|
||||
obj^.loaded:=4;
|
||||
|
||||
dynlibs_info.libprogram:=lib;
|
||||
dynlibs_info.libprogram:=obj;
|
||||
|
||||
if (imgp^.dyn_exist=0) then
|
||||
begin
|
||||
dynlibs_info.dyn_non_exist:=1;
|
||||
lib^.rel_data:=nil;
|
||||
obj^.rel_data:=nil;
|
||||
//
|
||||
end else
|
||||
begin
|
||||
dynlibs_info.dyn_non_exist:=0;
|
||||
|
||||
Result:=acquire_per_file_info_obj(imgp,lib);
|
||||
Result:=acquire_per_file_info_obj(imgp,obj);
|
||||
|
||||
if (Result<>0) then
|
||||
begin
|
||||
|
@ -838,7 +838,7 @@ end;
|
|||
|
||||
function dynlib_proc_initialize_step2(imgp:p_image_params):Integer;
|
||||
var
|
||||
lib,tail:p_lib_info;
|
||||
obj,tail:p_lib_info;
|
||||
|
||||
init_proc_addr:Pointer;
|
||||
fini_proc_addr:Pointer;
|
||||
|
@ -848,34 +848,34 @@ begin
|
|||
dynlibs_info.proc_param_addr:=imgp^.proc_param_addr;
|
||||
dynlibs_info.proc_param_size:=imgp^.proc_param_size;
|
||||
|
||||
lib:=dynlibs_info.libprogram;
|
||||
obj:=dynlibs_info.libprogram;
|
||||
|
||||
if (imgp^.dyn_exist=0) then
|
||||
begin
|
||||
dynlibs_add_obj(lib);
|
||||
dynlibs_add_obj(obj);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=digest_dynamic(lib);
|
||||
Result:=digest_dynamic(obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_proc_initialize_step2:','digest_dynamic()=',Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
init_relo_bits(lib);
|
||||
init_relo_bits(obj);
|
||||
|
||||
dynlibs_add_obj(lib);
|
||||
dynlibs_add_obj(obj);
|
||||
|
||||
dynlibs_info.sym_zero.st_info :=(STB_GLOBAL shl 4) or STT_NOTYPE;
|
||||
dynlibs_info.sym_zero.st_shndx:=SHN_UNDEF;
|
||||
dynlibs_info.sym_zero.st_value:=-Int64(lib^.relocbase);
|
||||
dynlibs_info.sym_zero.st_value:=-Int64(obj^.relocbase);
|
||||
|
||||
init_proc_addr:=lib^.init_proc_addr;
|
||||
fini_proc_addr:=lib^.fini_proc_addr;
|
||||
init_proc_addr:=obj^.init_proc_addr;
|
||||
fini_proc_addr:=obj^.fini_proc_addr;
|
||||
|
||||
lib^.fini_proc_addr:=nil;
|
||||
lib^.init_proc_addr:=nil;
|
||||
obj^.fini_proc_addr:=nil;
|
||||
obj^.init_proc_addr:=nil;
|
||||
|
||||
tail:=TAILQ_LAST(@dynlibs_info.obj_list);
|
||||
if (tail=nil) then
|
||||
|
@ -888,8 +888,8 @@ begin
|
|||
tail,
|
||||
dynlibs_info.init_proc_list);
|
||||
|
||||
lib^.init_proc_addr:=init_proc_addr;
|
||||
lib^.fini_proc_addr:=fini_proc_addr;
|
||||
obj^.init_proc_addr:=init_proc_addr;
|
||||
obj^.fini_proc_addr:=fini_proc_addr;
|
||||
|
||||
///
|
||||
end;
|
||||
|
@ -914,15 +914,14 @@ procedure dynlib_proc_initialize_step3(imgp:p_image_params);
|
|||
label
|
||||
_dyn_not_exist;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
str:RawByteString;
|
||||
err:Integer;
|
||||
key:Integer;
|
||||
flags:DWORD;
|
||||
begin
|
||||
err:=0;
|
||||
|
||||
lib:=nil;
|
||||
obj:=nil;
|
||||
|
||||
//if (td_proc->sdk_version < 0x5000000) {
|
||||
// *(byte *)&dynlibs_info->bits = *(byte *)&dynlibs_info->bits | 0x20;
|
||||
|
@ -934,35 +933,34 @@ begin
|
|||
if (budget_ptype_caller=0) then flags:=flags or $20; //vm_map_wire
|
||||
|
||||
str:='libkernel.sprx';
|
||||
lib:=preload_prx_modules(pchar(str),flags,err);
|
||||
dynlibs_info.libkernel:=lib;
|
||||
obj:=preload_prx_modules(pchar(str),flags,err);
|
||||
dynlibs_info.libkernel:=obj;
|
||||
|
||||
if (lib=nil) then
|
||||
if (obj=nil) then
|
||||
begin
|
||||
Writeln(StdErr,'preload_prx_modules:',str,' not loaded');
|
||||
end;
|
||||
|
||||
str:='libSceLibcInternal.sprx';
|
||||
lib:=preload_prx_modules(pchar(str),flags,err);
|
||||
obj:=preload_prx_modules(pchar(str),flags,err);
|
||||
|
||||
if (lib=nil) then
|
||||
if (obj=nil) then
|
||||
begin
|
||||
Writeln(StdErr,'preload_prx_modules:',str,' not loaded');
|
||||
end;
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
objlist_push_tail(dynlibs_info.list_main,lib);
|
||||
objlist_push_tail(dynlibs_info.list_main,obj);
|
||||
|
||||
Inc(lib^.ref_count);
|
||||
Inc(obj^.ref_count);
|
||||
|
||||
objlist_push_tail(lib^.dagmembers,lib);
|
||||
objlist_push_tail(lib^.dldags ,lib);
|
||||
objlist_push_tail(obj^.dagmembers,obj);
|
||||
objlist_push_tail(obj^.dldags ,obj);
|
||||
|
||||
//
|
||||
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
||||
dynlibs_info.rep_unpf:=do_dlsym(dynlibs_info.libkernel,'sceKernelReportUnpatchedFunctionCall',nil,0);
|
||||
|
@ -970,34 +968,31 @@ begin
|
|||
dynlibs_info.sysc_s00:=do_dlsym(dynlibs_info.libkernel,'sysc_s00','libkernel_sysc_se', 0);
|
||||
dynlibs_info.sysc_e00:=do_dlsym(dynlibs_info.libkernel,'sysc_e00','libkernel_sysc_se', 0);
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
dynlib_initialize_pltgot_each(lib);
|
||||
dynlib_initialize_pltgot_each(obj);
|
||||
//
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
||||
imgp^.entry_addr:=dynlibs_info.libkernel^.entry_addr;
|
||||
|
||||
_dyn_not_exist:
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
|
||||
if not alloc_obj_id(lib) then
|
||||
if not alloc_obj_id(obj) then
|
||||
begin
|
||||
Assert(False,'ID for PRX cannot be assigned.');
|
||||
end;
|
||||
|
||||
//
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
function exec_self_imgact(imgp:p_image_params):Integer;
|
||||
var
|
||||
hdr :p_elf64_hdr;
|
||||
|
|
|
@ -13,6 +13,7 @@ uses
|
|||
|
||||
function relocate_one_object(obj:p_lib_info;jmpslots:Integer):Integer;
|
||||
function check_copy_relocations(obj:p_lib_info):Integer;
|
||||
function dynlib_unlink_imported_symbols_each(root,obj:p_lib_info):Integer;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -97,7 +98,7 @@ begin
|
|||
R_X86_64_COPY:
|
||||
if (obj^.mainprog=0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','Unexpected R_X86_64_COPY relocation in shared library');
|
||||
Writeln(StdErr,'reloc_non_plt:','Unexpected R_X86_64_COPY relocation in shared library ',dynlib_basename(obj^.lib_path));
|
||||
Exit(ENOEXEC);
|
||||
end; //R_X86_64_COPY
|
||||
|
||||
|
@ -369,7 +370,7 @@ begin
|
|||
|
||||
if (ELF64_R_TYPE(entry^.r_info)<>R_X86_64_JUMP_SLOT) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_jmpslot:','R_TYPE (',ELF64_R_TYPE(entry^.r_info),') at index ',i,' is bad. (Expected: R_X86_64_JMP_SLOT) in ',obj^.lib_path);
|
||||
Writeln(StdErr,'reloc_jmpslot:','R_TYPE (',ELF64_R_TYPE(entry^.r_info),') at index ',i,' is bad. (Expected: R_X86_64_JMP_SLOT) in ',dynlib_basename(obj^.lib_path));
|
||||
Exit(3);
|
||||
end;
|
||||
|
||||
|
@ -445,7 +446,7 @@ begin
|
|||
Result:=reloc_non_plt(obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'relocate_one_object:','reloc_non_plt() failed. obj=',obj^.lib_path,' rv=',Result);
|
||||
Writeln(StdErr,'relocate_one_object:','reloc_non_plt() failed. obj=',dynlib_basename(obj^.lib_path),' rv=',Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
|
@ -454,7 +455,7 @@ begin
|
|||
Result:=reloc_jmpslots(obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'relocate_one_object:','reloc_jmplots() failed. obj=',obj^.lib_path,' rv=',Result);
|
||||
Writeln(StdErr,'relocate_one_object:','reloc_jmplots() failed. obj=',dynlib_basename(obj^.lib_path),' rv=',Result);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
@ -477,13 +478,208 @@ begin
|
|||
begin
|
||||
if (ELF64_R_TYPE(rela^.r_info)=R_X86_64_COPY) then
|
||||
begin
|
||||
Writeln(StdErr,'check_copy_relocations:','R_X86_64_COPY found in ',obj^.lib_path);
|
||||
Writeln(StdErr,'check_copy_relocations:','R_X86_64_COPY found in ',dynlib_basename(obj^.lib_path));
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
Inc(rela);
|
||||
end;
|
||||
end;
|
||||
|
||||
function dynlib_unlink_non_plt_reloc_each(root,obj:p_lib_info):Integer;
|
||||
var
|
||||
rela:p_elf64_rela;
|
||||
|
||||
where:Pointer;
|
||||
data:Pointer;
|
||||
|
||||
data32:Integer;
|
||||
r_type:Integer;
|
||||
|
||||
i,count:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
Assert(root<>nil,'Bad dynamic library is specified.');
|
||||
|
||||
rela :=obj^.rel_data^.rela_addr;
|
||||
count:=obj^.rel_data^.rela_size div SizeOf(elf64_rela);
|
||||
|
||||
if (rela<>nil) and (count<>0) then
|
||||
For i:=0 to count-1 do
|
||||
if check_relo_bits(obj,i) then
|
||||
begin
|
||||
where:=Pointer(obj^.relocbase)+rela^.r_offset;
|
||||
|
||||
r_type:=ELF64_R_TYPE(rela^.r_info);
|
||||
|
||||
case r_type of
|
||||
|
||||
R_X86_64_NONE:; //ignore
|
||||
|
||||
R_X86_64_COPY:
|
||||
if (obj^.mainprog=0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','Unexpected R_X86_64_COPY relocation in dynamic library ',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end; //R_X86_64_COPY
|
||||
|
||||
R_X86_64_64,
|
||||
R_X86_64_GLOB_DAT,
|
||||
R_X86_64_RELATIVE,
|
||||
R_X86_64_TPOFF64:
|
||||
begin
|
||||
data:=Pointer(QWORD($840000000));
|
||||
|
||||
Result:=relocate_text_or_data_segment(obj,@data,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
reset_relo_bits(obj,i);
|
||||
end; //64
|
||||
|
||||
R_X86_64_PC32,
|
||||
R_X86_64_TPOFF32:
|
||||
begin
|
||||
data32:=Integer($40000000);
|
||||
|
||||
Result:=relocate_text_or_data_segment(obj,@data32,where,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where32=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
reset_relo_bits(obj,i);
|
||||
end; //32
|
||||
|
||||
R_X86_64_DTPMOD64,
|
||||
R_X86_64_DTPOFF64:
|
||||
begin
|
||||
data:=nil;
|
||||
|
||||
Result:=copyout(@data,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
reset_relo_bits(obj,i);
|
||||
end; //64
|
||||
|
||||
R_X86_64_DTPOFF32:
|
||||
begin
|
||||
data32:=0;
|
||||
|
||||
Result:=copyout(@data32,where,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where32=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
reset_relo_bits(obj,i);
|
||||
end; //32
|
||||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','Unsupported reloc type=',r_type);
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
end;
|
||||
end; //case
|
||||
|
||||
end;
|
||||
|
||||
function dynlib_unlink_plt_reloc_each(root,obj:p_lib_info):Integer;
|
||||
var
|
||||
i,count,idofs:Integer;
|
||||
|
||||
entry:p_elf64_rela;
|
||||
|
||||
def:p_elf64_sym;
|
||||
defobj:p_lib_info;
|
||||
|
||||
where:Pointer;
|
||||
data:QWORD;
|
||||
|
||||
str:pchar;
|
||||
begin
|
||||
Result:=0;
|
||||
|
||||
count:=obj^.rel_data^.pltrela_size div SizeOf(elf64_rela);
|
||||
idofs:=obj^.rel_data^.rela_size div SizeOf(elf64_rela);
|
||||
|
||||
if (obj^.rel_data^.pltrela_addr<>nil) and (count<>0) then
|
||||
For i:=0 to count-1 do
|
||||
if check_relo_bits(obj,idofs+i) then
|
||||
begin
|
||||
entry:=obj^.rel_data^.pltrela_addr+i;
|
||||
|
||||
if (ELF64_R_TYPE(entry^.r_info)<>R_X86_64_JUMP_SLOT) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_plt_reloc_each:','R_TYPE (',ELF64_R_TYPE(entry^.r_info),') at index ',i,' is bad. (Expected: R_X86_64_JMP_SLOT) in ',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
defobj:=nil;
|
||||
def:=find_symdef(ELF64_R_SYM(entry^.r_info),obj,defobj,1,nil);
|
||||
|
||||
if (def=nil) then
|
||||
begin
|
||||
if (ELF64_R_SYM(entry^.r_info)<=(obj^.rel_data^.symtab_size div SizeOf(elf64_sym))) then
|
||||
begin
|
||||
def:=nil;
|
||||
str:='';
|
||||
end else
|
||||
begin
|
||||
def:=obj^.rel_data^.symtab_addr + ELF64_R_SYM(entry^.r_info);
|
||||
str:=obj_get_str(obj,def^.st_name);
|
||||
end;
|
||||
|
||||
Writeln(StdErr,'dynlib_unlink_plt_reloc_each:','failed to lookup symbol symp=0x',HexStr(def),' name=',str);
|
||||
Exit(-1);
|
||||
end else
|
||||
if (defobj=root) then
|
||||
begin
|
||||
where:=Pointer(obj^.relocbase) + entry^.r_offset;
|
||||
|
||||
data:=i or QWORD($effffffe00000000);
|
||||
|
||||
Result:=copyout(@data,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_plt_reloc_each:','copyout() failed. where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit(-1);
|
||||
end;
|
||||
|
||||
reset_relo_bits(obj,idofs+i);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function dynlib_unlink_imported_symbols_each(root,obj:p_lib_info):Integer;
|
||||
begin
|
||||
Result:=dynlib_unlink_non_plt_reloc_each(root,obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_imported_symbols_each:','dynlib_unlink_non_plt_reloc_each() fails ',Result);
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=dynlib_unlink_plt_reloc_each(root,obj);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'dynlib_unlink_imported_symbols_each:','dynlib_unlink_plt_reloc_each() fails ',Result);
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -216,22 +216,26 @@ procedure dynlibs_lock;
|
|||
procedure dynlibs_unlock;
|
||||
|
||||
function obj_new():p_lib_info;
|
||||
procedure obj_free(lib:p_lib_info);
|
||||
procedure obj_free(obj:p_lib_info);
|
||||
|
||||
procedure objlist_push_tail(var list:TAILQ_HEAD;obj:p_lib_info);
|
||||
function objlist_find(var list:TAILQ_HEAD;obj:p_lib_info):p_Objlist_Entry;
|
||||
procedure objlist_remove(var list:TAILQ_HEAD;obj:p_lib_info);
|
||||
|
||||
function obj_get_str(lib:p_lib_info;offset:Int64):pchar;
|
||||
procedure object_add_name(obj:p_lib_info;name:pchar);
|
||||
function obj_get_str (obj:p_lib_info;offset:Int64):pchar;
|
||||
procedure object_add_name (obj:p_lib_info;name:pchar);
|
||||
function object_match_name(obj:p_lib_info;name:pchar):Boolean;
|
||||
procedure obj_set_lib_path (obj:p_lib_info;path:PAnsiChar);
|
||||
|
||||
function Needed_new(lib:p_lib_info;str:pchar):p_Needed_Entry;
|
||||
function Lib_new(d_val:QWORD;import:Word):p_Lib_Entry;
|
||||
function Needed_new(obj:p_lib_info;str:pchar):p_Needed_Entry;
|
||||
|
||||
procedure _set_lib_path(lib:p_lib_info;path:PAnsiChar);
|
||||
function Lib_Entry_new(d_val:QWORD;import:Word):p_Lib_Entry;
|
||||
procedure Lib_Entry_free(lib:p_Lib_Entry);
|
||||
|
||||
procedure release_per_file_info_obj(lib:p_lib_info);
|
||||
function get_mod_name(obj:p_lib_info;id:Word):pchar;
|
||||
function get_lib_name(obj:p_lib_info;id:Word):pchar;
|
||||
|
||||
procedure release_per_file_info_obj(obj:p_lib_info);
|
||||
function acquire_per_file_info_obj(imgp:p_image_params;new:p_lib_info):Integer;
|
||||
|
||||
function allocate_tls_offset(obj:p_lib_info):Boolean;
|
||||
|
@ -246,13 +250,14 @@ procedure initlist_add_neededs(var fini_proc_list:TAILQ_HEAD;
|
|||
needed:p_Needed_Entry;
|
||||
var init_proc_list:TAILQ_HEAD);
|
||||
|
||||
function digest_dynamic(lib:p_lib_info):Integer;
|
||||
function digest_dynamic(obj:p_lib_info):Integer;
|
||||
|
||||
procedure dynlibs_add_obj(lib:p_lib_info);
|
||||
procedure dynlibs_add_obj(obj:p_lib_info);
|
||||
|
||||
procedure init_relo_bits (obj:p_lib_info);
|
||||
function check_relo_bits(obj:p_lib_info;i:Integer):Boolean;
|
||||
procedure set_relo_bits(obj:p_lib_info;i:Integer);
|
||||
procedure set_relo_bits (obj:p_lib_info;i:Integer);
|
||||
procedure reset_relo_bits(obj:p_lib_info;i:Integer);
|
||||
|
||||
procedure donelist_init(var dlp:t_DoneList);
|
||||
function donelist_check(var dlp:t_DoneList;obj:p_lib_info):Boolean;
|
||||
|
@ -271,13 +276,14 @@ function dynlib_initialize_pltgot_each(obj:p_lib_info):Integer;
|
|||
function do_load_object(path:pchar;flags:DWORD;var err:Integer):p_lib_info;
|
||||
procedure unload_object(root:p_lib_info);
|
||||
|
||||
function relocate_object(lib:p_lib_info):Integer;
|
||||
function relocate_object(root:p_lib_info):Integer;
|
||||
function dynlib_load_relocate():Integer;
|
||||
|
||||
function preload_prx_modules(path:pchar;flags:DWORD;var err:Integer):p_lib_info;
|
||||
function load_prx(path:pchar;flags:DWORD;var plib:p_lib_info):Integer;
|
||||
function load_prx(path:pchar;flags:DWORD;var pobj:p_lib_info):Integer;
|
||||
function unload_prx(obj:p_lib_info):Integer;
|
||||
|
||||
function alloc_obj_id(lib:p_lib_info):Boolean;
|
||||
function alloc_obj_id(obj:p_lib_info):Boolean;
|
||||
function free_obj_id (id:Integer):Boolean;
|
||||
function find_obj_id (id:Integer):p_lib_info;
|
||||
|
||||
|
@ -338,15 +344,6 @@ begin
|
|||
//*puVar1:=*puVar1 | 2;
|
||||
end;
|
||||
|
||||
procedure _set_lib_path(lib:p_lib_info;path:PAnsiChar);
|
||||
var
|
||||
size:int64;
|
||||
begin
|
||||
size:=strlen(path);
|
||||
lib^.lib_path:=AllocMem(size+1);
|
||||
Move(path^,lib^.lib_path^,size);
|
||||
end;
|
||||
|
||||
function preprocess_dt_entries(new:p_lib_info;hdr_e_type:Integer):Integer;
|
||||
label
|
||||
_unsupp;
|
||||
|
@ -629,12 +626,12 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
procedure release_per_file_info_obj(lib:p_lib_info);
|
||||
procedure release_per_file_info_obj(obj:p_lib_info);
|
||||
begin
|
||||
if (lib^.rel_data<>nil) then
|
||||
if (obj^.rel_data<>nil) then
|
||||
begin
|
||||
FreeMem(lib^.rel_data);
|
||||
lib^.rel_data:=nil;
|
||||
FreeMem(obj^.rel_data);
|
||||
obj^.rel_data:=nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -764,85 +761,84 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
procedure obj_free(lib:p_lib_info);
|
||||
procedure obj_free(obj:p_lib_info);
|
||||
var
|
||||
needed:p_Needed_Entry;
|
||||
names:p_Name_Entry;
|
||||
dag:p_Objlist_Entry;
|
||||
libs:p_Lib_Entry;
|
||||
Lib_Entry:p_Lib_Entry;
|
||||
begin
|
||||
free_tls_offset(obj);
|
||||
|
||||
free_tls_offset(lib);
|
||||
|
||||
needed:=TAILQ_FIRST(@lib^.needed);
|
||||
needed:=TAILQ_FIRST(@obj^.needed);
|
||||
while (needed<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.needed,needed,@needed^.link);
|
||||
TAILQ_REMOVE(@obj^.needed,needed,@needed^.link);
|
||||
FreeMem(needed);
|
||||
needed:=TAILQ_FIRST(@lib^.needed);
|
||||
needed:=TAILQ_FIRST(@obj^.needed);
|
||||
end;
|
||||
|
||||
names:=TAILQ_FIRST(@lib^.names);
|
||||
names:=TAILQ_FIRST(@obj^.names);
|
||||
while (names<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.names,names,@names^.link);
|
||||
TAILQ_REMOVE(@obj^.names,names,@names^.link);
|
||||
FreeMem(names);
|
||||
names:=TAILQ_FIRST(@lib^.names);
|
||||
names:=TAILQ_FIRST(@obj^.names);
|
||||
end;
|
||||
|
||||
dag:=TAILQ_FIRST(@lib^.dldags);
|
||||
dag:=TAILQ_FIRST(@obj^.dldags);
|
||||
while (dag<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.dldags,dag,@dag^.link);
|
||||
TAILQ_REMOVE(@obj^.dldags,dag,@dag^.link);
|
||||
FreeMem(dag);
|
||||
dag:=TAILQ_FIRST(@lib^.dldags);
|
||||
dag:=TAILQ_FIRST(@obj^.dldags);
|
||||
end;
|
||||
|
||||
dag:=TAILQ_FIRST(@lib^.dagmembers);
|
||||
dag:=TAILQ_FIRST(@obj^.dagmembers);
|
||||
while (dag<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.dagmembers,dag,@dag^.link);
|
||||
TAILQ_REMOVE(@obj^.dagmembers,dag,@dag^.link);
|
||||
FreeMem(dag);
|
||||
dag:=TAILQ_FIRST(@lib^.dagmembers);
|
||||
dag:=TAILQ_FIRST(@obj^.dagmembers);
|
||||
end;
|
||||
|
||||
if (lib^.lib_dirname<>nil) then
|
||||
if (obj^.lib_dirname<>nil) then
|
||||
begin
|
||||
FreeMem(lib^.lib_dirname);
|
||||
lib^.lib_dirname:=nil;
|
||||
FreeMem(obj^.lib_dirname);
|
||||
obj^.lib_dirname:=nil;
|
||||
end;
|
||||
|
||||
if (lib^.lib_path<>nil) then
|
||||
if (obj^.lib_path<>nil) then
|
||||
begin
|
||||
FreeMem(lib^.lib_path);
|
||||
lib^.lib_path:=nil;
|
||||
FreeMem(obj^.lib_path);
|
||||
obj^.lib_path:=nil;
|
||||
end;
|
||||
|
||||
if (lib^.relo_bits<>nil) then
|
||||
if (obj^.relo_bits<>nil) then
|
||||
begin
|
||||
FreeMem(lib^.relo_bits);
|
||||
lib^.relo_bits:=nil
|
||||
FreeMem(obj^.relo_bits);
|
||||
obj^.relo_bits:=nil
|
||||
end;
|
||||
|
||||
libs:=TAILQ_FIRST(@lib^.lib_table);
|
||||
while (libs<>nil) do
|
||||
Lib_Entry:=TAILQ_FIRST(@obj^.lib_table);
|
||||
while (Lib_Entry<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.lib_table,libs,@libs^.link);
|
||||
FreeMem(libs);
|
||||
libs:=TAILQ_FIRST(@lib^.lib_table);
|
||||
TAILQ_REMOVE(@obj^.lib_table,Lib_Entry,@Lib_Entry^.link);
|
||||
Lib_Entry_free(Lib_Entry);
|
||||
Lib_Entry:=TAILQ_FIRST(@obj^.lib_table);
|
||||
end;
|
||||
|
||||
libs:=TAILQ_FIRST(@lib^.mod_table);
|
||||
while (libs<>nil) do
|
||||
Lib_Entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
while (Lib_Entry<>nil) do
|
||||
begin
|
||||
TAILQ_REMOVE(@lib^.mod_table,libs,@libs^.link);
|
||||
FreeMem(libs);
|
||||
libs:=TAILQ_FIRST(@lib^.mod_table);
|
||||
TAILQ_REMOVE(@obj^.mod_table,Lib_Entry,@Lib_Entry^.link);
|
||||
Lib_Entry_free(Lib_Entry);
|
||||
Lib_Entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
end;
|
||||
|
||||
release_per_file_info_obj(lib);
|
||||
release_per_file_info_obj(obj);
|
||||
|
||||
FreeMem(lib);
|
||||
FreeMem(obj);
|
||||
end;
|
||||
|
||||
procedure objlist_push_tail(var list:TAILQ_HEAD;obj:p_lib_info);
|
||||
|
@ -881,15 +877,15 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function obj_get_str(lib:p_lib_info;offset:Int64):pchar;
|
||||
function obj_get_str(obj:p_lib_info;offset:Int64):pchar;
|
||||
begin
|
||||
if (lib^.rel_data^.strtab_size<=offset) then
|
||||
if (obj^.rel_data^.strtab_size<=offset) then
|
||||
begin
|
||||
Writeln(StdErr,'obj_get_str:','offset=0x',HexStr(offset,8),' is out of range of string table of ',lib^.lib_path);
|
||||
Writeln(StdErr,'obj_get_str:','offset=0x',HexStr(offset,8),' is out of range of string table of ',obj^.lib_path);
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
Result:=lib^.rel_data^.strtab_addr+offset;
|
||||
Result:=obj^.rel_data^.strtab_addr+offset;
|
||||
end;
|
||||
|
||||
procedure object_add_name(obj:p_lib_info;name:pchar);
|
||||
|
@ -920,23 +916,76 @@ begin
|
|||
Result:=False;
|
||||
end;
|
||||
|
||||
function Needed_new(lib:p_lib_info;str:pchar):p_Needed_Entry;
|
||||
procedure obj_set_lib_path(obj:p_lib_info;path:PAnsiChar);
|
||||
var
|
||||
size:int64;
|
||||
begin
|
||||
size:=strlen(path);
|
||||
obj^.lib_path:=AllocMem(size+1);
|
||||
Move(path^,obj^.lib_path^,size);
|
||||
end;
|
||||
|
||||
function Needed_new(obj:p_lib_info;str:pchar):p_Needed_Entry;
|
||||
var
|
||||
len:Integer;
|
||||
begin
|
||||
len:=strlen(str);
|
||||
Result:=AllocMem(SizeOf(Needed_Entry)+len);
|
||||
Result^.obj :=lib;
|
||||
Result^.obj :=obj;
|
||||
Move(str^,Result^.name,len);
|
||||
end;
|
||||
|
||||
function Lib_new(d_val:QWORD;import:Word):p_Lib_Entry;
|
||||
function Lib_Entry_new(d_val:QWORD;import:Word):p_Lib_Entry;
|
||||
begin
|
||||
Result:=AllocMem(SizeOf(Lib_Entry));
|
||||
QWORD(Result^.dval):=d_val;
|
||||
Result^.import:=import;
|
||||
end;
|
||||
|
||||
procedure Lib_Entry_free(lib:p_Lib_Entry);
|
||||
begin
|
||||
//
|
||||
FreeMem(lib);
|
||||
end;
|
||||
|
||||
function get_mod_name(obj:p_lib_info;id:Word):pchar;
|
||||
var
|
||||
lib_entry:p_Lib_Entry;
|
||||
offset:QWORD;
|
||||
begin
|
||||
Result:=nil;
|
||||
lib_entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (lib_entry^.dval.id=id) then
|
||||
begin
|
||||
offset:=lib_entry^.dval.name_offset;
|
||||
Result:=obj_get_str(obj,offset);
|
||||
Exit;
|
||||
end;
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
end;
|
||||
end;
|
||||
|
||||
function get_lib_name(obj:p_lib_info;id:Word):pchar;
|
||||
var
|
||||
lib_entry:p_Lib_Entry;
|
||||
offset:QWORD;
|
||||
begin
|
||||
Result:=nil;
|
||||
lib_entry:=TAILQ_FIRST(@obj^.lib_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (lib_entry^.dval.id=id) then
|
||||
begin
|
||||
offset:=lib_entry^.dval.name_offset;
|
||||
Result:=obj_get_str(obj,offset);
|
||||
Exit;
|
||||
end;
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure initlist_add_objects(var fini_proc_list:TAILQ_HEAD;
|
||||
obj :p_lib_info;
|
||||
tail:p_lib_info;
|
||||
|
@ -986,8 +1035,7 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
|
||||
function digest_dynamic(lib:p_lib_info):Integer;
|
||||
function digest_dynamic(obj:p_lib_info):Integer;
|
||||
var
|
||||
dt_ent:p_elf64_dyn;
|
||||
i,count:Integer;
|
||||
|
@ -1008,10 +1056,10 @@ begin
|
|||
dyn_soname:=nil;
|
||||
dt_fingerprint:=-1;
|
||||
|
||||
if (lib^.rel_data<>nil) then
|
||||
if (obj^.rel_data<>nil) then
|
||||
begin
|
||||
dt_ent:=lib^.rel_data^.dynamic_addr;
|
||||
count :=lib^.rel_data^.dynamic_size div sizeof(elf64_dyn);
|
||||
dt_ent:=obj^.rel_data^.dynamic_addr;
|
||||
count :=obj^.rel_data^.dynamic_size div sizeof(elf64_dyn);
|
||||
|
||||
if (count<>0) then
|
||||
For i:=0 to count-1 do
|
||||
|
@ -1065,7 +1113,7 @@ begin
|
|||
|
||||
DT_NEEDED:
|
||||
begin
|
||||
str:=obj_get_str(lib,dt_ent^.d_un.d_val);
|
||||
str:=obj_get_str(obj,dt_ent^.d_un.d_val);
|
||||
|
||||
if (str=nil) then
|
||||
begin
|
||||
|
@ -1073,16 +1121,16 @@ begin
|
|||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
needed:=Needed_new(lib,str);
|
||||
TAILQ_INSERT_TAIL(@lib^.needed,needed,@Needed^.link);
|
||||
needed:=Needed_new(obj,str);
|
||||
TAILQ_INSERT_TAIL(@obj^.needed,needed,@Needed^.link);
|
||||
end;
|
||||
|
||||
DT_INIT:
|
||||
begin
|
||||
addr:=lib^.relocbase+dt_ent^.d_un.d_val;
|
||||
lib^.init_proc_addr:=addr;
|
||||
addr:=obj^.relocbase+dt_ent^.d_un.d_val;
|
||||
obj^.init_proc_addr:=addr;
|
||||
|
||||
if (lib^.map_base>addr) or ((addr+8)>(lib^.map_base+lib^.text_size)) then
|
||||
if (obj^.map_base>addr) or ((addr+8)>(obj^.map_base+obj^.text_size)) then
|
||||
begin
|
||||
Writeln(StdErr,'digest_dynamic:',{$INCLUDE %LINE%});
|
||||
Exit(ENOEXEC);
|
||||
|
@ -1091,10 +1139,10 @@ begin
|
|||
|
||||
DT_FINI:
|
||||
begin
|
||||
addr:=lib^.relocbase+dt_ent^.d_un.d_val;
|
||||
lib^.fini_proc_addr:=addr;
|
||||
addr:=obj^.relocbase+dt_ent^.d_un.d_val;
|
||||
obj^.fini_proc_addr:=addr;
|
||||
|
||||
if (lib^.map_base>addr) or ((addr+8)>(lib^.map_base+lib^.text_size)) then
|
||||
if (obj^.map_base>addr) or ((addr+8)>(obj^.map_base+obj^.text_size)) then
|
||||
begin
|
||||
Writeln(StdErr,'digest_dynamic:',{$INCLUDE %LINE%});
|
||||
Exit(ENOEXEC);
|
||||
|
@ -1109,7 +1157,7 @@ begin
|
|||
|
||||
DT_TEXTREL:
|
||||
begin
|
||||
lib^.textrel:=1;
|
||||
obj^.textrel:=1;
|
||||
end;
|
||||
|
||||
DT_FLAGS:
|
||||
|
@ -1130,7 +1178,7 @@ begin
|
|||
|
||||
if ((dval and DF_TEXTREL)<>0) then
|
||||
begin
|
||||
lib^.textrel:=1;
|
||||
obj^.textrel:=1;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1138,8 +1186,8 @@ begin
|
|||
begin
|
||||
dt_fingerprint:=dt_ent^.d_un.d_val;
|
||||
|
||||
if (lib^.rel_data=nil) or
|
||||
((dt_fingerprint + 20)>lib^.rel_data^.sce_dynlib_size) then
|
||||
if (obj^.rel_data=nil) or
|
||||
((dt_fingerprint + 20)>obj^.rel_data^.sce_dynlib_size) then
|
||||
begin
|
||||
Writeln(StdErr,'digest_dynamic:',{$INCLUDE %LINE%});
|
||||
Exit(ENOEXEC);
|
||||
|
@ -1148,7 +1196,7 @@ begin
|
|||
|
||||
DT_SCE_ORIGINAL_FILENAME:
|
||||
begin
|
||||
str:=obj_get_str(lib,dt_ent^.d_un.d_val);
|
||||
str:=obj_get_str(obj,dt_ent^.d_un.d_val);
|
||||
|
||||
if (str=nil) then
|
||||
begin
|
||||
|
@ -1156,21 +1204,21 @@ begin
|
|||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
lib^.rel_data^.original_filename:=str;
|
||||
obj^.rel_data^.original_filename:=str;
|
||||
end;
|
||||
|
||||
DT_SCE_MODULE_INFO,
|
||||
DT_SCE_NEEDED_MODULE:
|
||||
begin
|
||||
lib_entry:=Lib_new(dt_ent^.d_un.d_val,ord(dt_ent^.d_tag=DT_SCE_NEEDED_MODULE));
|
||||
TAILQ_INSERT_TAIL(@lib^.mod_table,lib_entry,@lib_entry^.link);
|
||||
lib_entry:=Lib_Entry_new(dt_ent^.d_un.d_val,ord(dt_ent^.d_tag=DT_SCE_NEEDED_MODULE));
|
||||
TAILQ_INSERT_TAIL(@obj^.mod_table,lib_entry,@lib_entry^.link);
|
||||
end;
|
||||
|
||||
DT_SCE_MODULE_ATTR:
|
||||
begin
|
||||
dval:=dt_ent^.d_un.d_val;
|
||||
|
||||
lib_entry:=TAILQ_FIRST(@lib^.mod_table);
|
||||
lib_entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (TLibraryAttr(dval).id=lib_entry^.dval.id) then
|
||||
|
@ -1192,8 +1240,8 @@ begin
|
|||
DT_SCE_EXPORT_LIB,
|
||||
DT_SCE_IMPORT_LIB:
|
||||
begin
|
||||
lib_entry:=Lib_new(dt_ent^.d_un.d_val,ord(dt_ent^.d_tag=DT_SCE_IMPORT_LIB));
|
||||
TAILQ_INSERT_TAIL(@lib^.lib_table,lib_entry,@lib_entry^.link);
|
||||
lib_entry:=Lib_Entry_new(dt_ent^.d_un.d_val,ord(dt_ent^.d_tag=DT_SCE_IMPORT_LIB));
|
||||
TAILQ_INSERT_TAIL(@obj^.lib_table,lib_entry,@lib_entry^.link);
|
||||
end;
|
||||
|
||||
DT_SCE_EXPORT_LIB_ATTR,
|
||||
|
@ -1201,7 +1249,7 @@ begin
|
|||
begin
|
||||
dval:=dt_ent^.d_un.d_val;
|
||||
|
||||
lib_entry:=TAILQ_FIRST(@lib^.lib_table);
|
||||
lib_entry:=TAILQ_FIRST(@obj^.lib_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (TLibraryAttr(dval).id=lib_entry^.dval.id) then
|
||||
|
@ -1251,7 +1299,7 @@ begin
|
|||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'digest_dynamic:','Unsupported DT tag 0x',HexStr(dt_ent^.d_tag,8),' found in ',lib^.lib_path);
|
||||
Writeln(StdErr,'digest_dynamic:','Unsupported DT tag 0x',HexStr(dt_ent^.d_tag,8),' found in ',obj^.lib_path);
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
|
@ -1262,27 +1310,27 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
addr:=lib^.rel_data^.sce_dynlib_addr;
|
||||
addr:=obj^.rel_data^.sce_dynlib_addr;
|
||||
|
||||
if (dt_fingerprint=-1) then
|
||||
begin
|
||||
if (addr<>nil) then
|
||||
begin
|
||||
Move(addr^,lib^.fingerprint,20);
|
||||
Move(addr^,obj^.fingerprint,20);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
if (addr<>nil) then
|
||||
begin
|
||||
Move((addr+dt_fingerprint)^,lib^.fingerprint,20);
|
||||
Move((addr+dt_fingerprint)^,obj^.fingerprint,20);
|
||||
end;
|
||||
end;
|
||||
|
||||
if (lib^.lib_path<>nil) then
|
||||
if (obj^.lib_path<>nil) then
|
||||
begin
|
||||
lib^.lib_dirname:=AllocMem(strlen(lib^.lib_path)+1);
|
||||
obj^.lib_dirname:=AllocMem(strlen(obj^.lib_path)+1);
|
||||
//
|
||||
Result:=rtld_dirname(lib^.lib_path,lib^.lib_dirname);
|
||||
Result:=rtld_dirname(obj^.lib_path,obj^.lib_dirname);
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Exit(EINVAL);
|
||||
|
@ -1291,7 +1339,7 @@ begin
|
|||
|
||||
if (dyn_soname<>nil) then
|
||||
begin
|
||||
str:=obj_get_str(lib,dyn_soname^.d_un.d_val);
|
||||
str:=obj_get_str(obj,dyn_soname^.d_un.d_val);
|
||||
|
||||
if (str=nil) then
|
||||
begin
|
||||
|
@ -1299,14 +1347,14 @@ begin
|
|||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
object_add_name(lib,str);
|
||||
object_add_name(obj,str);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
procedure dynlibs_add_obj(lib:p_lib_info);
|
||||
procedure dynlibs_add_obj(obj:p_lib_info);
|
||||
begin
|
||||
TAILQ_INSERT_TAIL(@dynlibs_info.obj_list,lib,@lib^.link);
|
||||
TAILQ_INSERT_TAIL(@dynlibs_info.obj_list,obj,@obj^.link);
|
||||
Inc(dynlibs_info.obj_count);
|
||||
end;
|
||||
|
||||
|
@ -1346,6 +1394,13 @@ begin
|
|||
obj^.relo_bits[i shr 3]:=obj^.relo_bits[i shr 3] or (1 shl (i and 7))
|
||||
end;
|
||||
|
||||
procedure reset_relo_bits(obj:p_lib_info;i:Integer);
|
||||
begin
|
||||
if (obj^.relo_bits=nil) then Exit;
|
||||
|
||||
obj^.relo_bits[i shr 3]:=obj^.relo_bits[i shr 3] and (not (1 shl (i and 7)))
|
||||
end;
|
||||
|
||||
function dynlib_load_sections(imgp:p_image_params;new:p_lib_info;phdr:p_elf64_phdr;count:Integer;delta:QWORD):Integer;
|
||||
var
|
||||
i:Integer;
|
||||
|
@ -1751,16 +1806,16 @@ end;
|
|||
|
||||
function change_relro_protection_all(prot:Integer):Integer;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
begin
|
||||
Result:=0;
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
Result:=change_relro_protection(lib,prot);
|
||||
Result:=change_relro_protection(obj,prot);
|
||||
if (Result<>0) then Exit;
|
||||
//
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1967,7 +2022,7 @@ label
|
|||
var
|
||||
fname:RawByteString;
|
||||
new:p_lib_info;
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
i:Integer;
|
||||
tls_max:Integer;
|
||||
begin
|
||||
|
@ -1984,7 +2039,7 @@ begin
|
|||
fname:=ExtractFileName(path);
|
||||
object_add_name(new,pchar(fname));
|
||||
|
||||
_set_lib_path(new,path);
|
||||
obj_set_lib_path(new,path);
|
||||
|
||||
if (new^.tls_size=0) then
|
||||
begin
|
||||
|
@ -2002,19 +2057,19 @@ begin
|
|||
end else
|
||||
begin
|
||||
i:=1;
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
while (lib^.tls_index=i) do
|
||||
while (obj^.tls_index=i) do
|
||||
begin
|
||||
i:=i+1;
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
if (tls_max < i) then
|
||||
begin
|
||||
goto _inc_max;
|
||||
end;
|
||||
end;
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
@ -2042,7 +2097,7 @@ begin
|
|||
goto _error;
|
||||
end;
|
||||
|
||||
init_relo_bits(lib);
|
||||
init_relo_bits(obj);
|
||||
dynlibs_add_obj(new);
|
||||
new^.loaded:=1;
|
||||
Exit(new);
|
||||
|
@ -2119,7 +2174,7 @@ function preload_prx_modules(path:pchar;flags:DWORD;var err:Integer):p_lib_info;
|
|||
label
|
||||
_do_load;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
fname:RawByteString;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
@ -2127,14 +2182,14 @@ begin
|
|||
|
||||
fname:=ExtractFileName(path);
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if object_match_name(lib,pchar(fname)) then
|
||||
if object_match_name(obj,pchar(fname)) then
|
||||
begin
|
||||
Exit(lib);
|
||||
Exit(obj);
|
||||
end;
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
||||
fname:=path;
|
||||
|
@ -2172,14 +2227,14 @@ begin
|
|||
Result:=do_load_object(pchar(fname),flags,err);
|
||||
end;
|
||||
|
||||
function relocate_object(lib:p_lib_info):Integer;
|
||||
function relocate_object(root:p_lib_info):Integer;
|
||||
var
|
||||
obj:p_lib_info;
|
||||
begin
|
||||
Result:=change_relro_protection_all(VM_PROT_RW);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=relocate_one_object(lib,ord(lib^.jmpslots_done=0));
|
||||
Result:=relocate_one_object(root,ord(root^.jmpslots_done=0));
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
|
@ -2187,9 +2242,9 @@ begin
|
|||
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if (obj<>lib) then
|
||||
if (obj<>root) then
|
||||
begin
|
||||
Result:=relocate_one_object(obj,ord(lib^.jmpslots_done=0));
|
||||
Result:=relocate_one_object(obj,ord(root^.jmpslots_done=0));
|
||||
end;
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
@ -2213,95 +2268,110 @@ begin
|
|||
Result:=relocate_object(dynlibs_info.libprogram);
|
||||
end;
|
||||
|
||||
function load_prx(path:pchar;flags:DWORD;var plib:p_lib_info):Integer;
|
||||
function load_prx(path:pchar;flags:DWORD;var pobj:p_lib_info):Integer;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
err,pflags:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
err:=0;
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if (StrLComp(lib^.lib_path,path,$400)=0) then
|
||||
if (StrLComp(obj^.lib_path,path,$400)=0) then
|
||||
begin
|
||||
Exit(0);
|
||||
end;
|
||||
//
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
|
||||
pflags:=2;
|
||||
if ((flags and $00001)<>0) then pflags:=pflags or $20; //vm_map_wire
|
||||
if ((flags and $10000)<>0) then pflags:=pflags or $40; //priv libs?
|
||||
|
||||
lib:=preload_prx_modules(path,pflags,err);
|
||||
if (lib=nil) then Exit(err);
|
||||
obj:=preload_prx_modules(path,pflags,err);
|
||||
if (obj=nil) then Exit(err);
|
||||
|
||||
if (objlist_find(dynlibs_info.list_global,lib)=nil) then
|
||||
if (objlist_find(dynlibs_info.list_global,obj)=nil) then
|
||||
begin
|
||||
objlist_push_tail(dynlibs_info.list_global,lib);
|
||||
objlist_push_tail(dynlibs_info.list_global,obj);
|
||||
end;
|
||||
|
||||
if (lib^.ref_count=0) then
|
||||
if (obj^.ref_count=0) then
|
||||
begin
|
||||
if ((flags and $20000)<>0) then //reset jmpslots_done?
|
||||
begin
|
||||
lib^.jmpslots_done:=0;
|
||||
obj^.jmpslots_done:=0;
|
||||
end;
|
||||
|
||||
if ((flags and $40000)<>0) then //reset on_fini_list?
|
||||
begin
|
||||
lib^.on_fini_list:=0;
|
||||
obj^.on_fini_list:=0;
|
||||
end;
|
||||
|
||||
init_dag(lib);
|
||||
ref_dag(lib);
|
||||
init_dag(obj);
|
||||
ref_dag(obj);
|
||||
|
||||
err:=relocate_object(lib);
|
||||
err:=relocate_object(obj);
|
||||
if (err<>0) then
|
||||
begin
|
||||
unref_dag(lib);
|
||||
if (lib^.ref_count=0) then
|
||||
unref_dag(obj);
|
||||
if (obj^.ref_count=0) then
|
||||
begin
|
||||
unload_object(lib);
|
||||
unload_object(obj);
|
||||
end;
|
||||
Writeln(StdErr,'load_prx:','Fail to relocate ',path);
|
||||
Exit(err);
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
ref_dag(lib);
|
||||
ref_dag(obj);
|
||||
end;
|
||||
|
||||
plib:=lib;
|
||||
pobj:=obj;
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function dynlib_unlink_imported_symbols_each(root,obj:p_lib_info):Integer;
|
||||
begin
|
||||
////////
|
||||
end;
|
||||
|
||||
function dynlib_unlink_imported_symbols(root:p_lib_info;libname:pchar):Integer;
|
||||
function dynlib_unlink_imported_symbols(root:p_lib_info;modname:pchar):Integer;
|
||||
var
|
||||
obj:p_lib_info;
|
||||
lib_entry:p_Lib_Entry;
|
||||
offset:QWORD;
|
||||
str:pchar;
|
||||
begin
|
||||
Result:=change_relro_protection_all(VM_PROT_RW);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
if (Result=0) then
|
||||
begin
|
||||
obj:=dynlibs_info.libprogram;
|
||||
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
//dynlib_unlink_imported_symbols_each(root,obj:p_lib_info):Integer;
|
||||
|
||||
|
||||
|
||||
|
||||
if (obj<>root) then
|
||||
begin
|
||||
lib_entry:=TAILQ_FIRST(@obj^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
begin
|
||||
if (lib_entry^.dval.id<>0) then //import
|
||||
begin
|
||||
offset:=lib_entry^.dval.name_offset;
|
||||
str:=obj_get_str(obj,offset);
|
||||
//
|
||||
if (modname<>nil) then
|
||||
if (StrComp(str,modname)=0) then //used module
|
||||
begin
|
||||
Result:=dynlib_unlink_imported_symbols_each(root,obj);
|
||||
//ended
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
//
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
end;
|
||||
end;
|
||||
//
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
end;
|
||||
|
@ -2309,58 +2379,51 @@ begin
|
|||
change_relro_protection_all(VM_PROT_READ);
|
||||
end;
|
||||
|
||||
|
||||
function unload_prx(lib:p_lib_info):Integer;
|
||||
function unload_prx(obj:p_lib_info):Integer;
|
||||
var
|
||||
lib_entry:p_Lib_Entry;
|
||||
str:pchar;
|
||||
modname:pchar;
|
||||
begin
|
||||
if (lib^.ref_count=0) then
|
||||
if (obj^.ref_count=0) then
|
||||
begin
|
||||
Assert(False,'Invalid shared object handle');
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
unref_dag(lib);
|
||||
|
||||
lib_entry:=TAILQ_FIRST(@lib^.mod_table);
|
||||
while (lib_entry<>nil) do
|
||||
unref_dag(obj);
|
||||
|
||||
if (obj^.ref_count<>1) then
|
||||
begin
|
||||
if (lib_entry^.dval.id=0) then
|
||||
begin
|
||||
str:=obj_get_str(lib,lib_entry^.dval.name_offset);
|
||||
|
||||
if (str<>nil) then
|
||||
begin
|
||||
Result:=dynlib_unlink_imported_symbols(lib,str);
|
||||
end;
|
||||
|
||||
|
||||
|
||||
////
|
||||
end;
|
||||
|
||||
|
||||
lib_entry:=TAILQ_NEXT(lib_entry,@lib_entry^.link)
|
||||
Exit(0);
|
||||
end;
|
||||
|
||||
modname:=get_mod_name(obj,0); //export=0
|
||||
|
||||
if (modname<>nil) then
|
||||
begin
|
||||
Result:=dynlib_unlink_imported_symbols(obj,modname);
|
||||
end;
|
||||
|
||||
unload_object(obj);
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function alloc_obj_id(lib:p_lib_info):Boolean;
|
||||
function alloc_obj_id(obj:p_lib_info):Boolean;
|
||||
var
|
||||
key:Integer;
|
||||
begin
|
||||
Result:=False;
|
||||
if (lib^.id>0) then Exit(True);
|
||||
if (obj^.id>0) then Exit(True);
|
||||
|
||||
lib^.desc.free:=nil;
|
||||
lib^.objt:=NAMED_DYNL;
|
||||
lib^.name:='';
|
||||
obj^.desc.free:=nil;
|
||||
obj^.objt:=NAMED_DYNL;
|
||||
obj^.name:='';
|
||||
|
||||
key:=-1;
|
||||
if id_name_new(@named_table,lib,@key) then
|
||||
if id_name_new(@named_table,obj,@key) then
|
||||
begin
|
||||
lib^.id:=(key+1);
|
||||
id_release(lib);
|
||||
obj^.id:=(key+1);
|
||||
id_release(obj);
|
||||
Result:=True;
|
||||
end;
|
||||
end;
|
||||
|
@ -2389,19 +2452,19 @@ end;
|
|||
|
||||
function find_obj_by_handle(id:Integer):p_lib_info;
|
||||
var
|
||||
lib:p_lib_info;
|
||||
obj:p_lib_info;
|
||||
begin
|
||||
Result:=nil;
|
||||
|
||||
lib:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (lib<>nil) do
|
||||
obj:=TAILQ_FIRST(@dynlibs_info.obj_list);
|
||||
while (obj<>nil) do
|
||||
begin
|
||||
if (lib^.id=id) then
|
||||
if (obj^.id=id) then
|
||||
begin
|
||||
Exit(lib);
|
||||
Exit(obj);
|
||||
end;
|
||||
//
|
||||
lib:=TAILQ_NEXT(lib,@lib^.link);
|
||||
obj:=TAILQ_NEXT(obj,@obj^.link);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
|
Loading…
Reference in New Issue