mirror of https://github.com/red-prig/fpPS4.git
This commit is contained in:
parent
55b69eaa8e
commit
8740fedec5
|
@ -636,7 +636,7 @@ function SELF_WINDOW(i:Int64):Integer; inline;
|
|||
function SELF_BLOCK_SIZE(i:Int64):Int64; inline;
|
||||
function SELF_SEGMENT_INDEX(i:Int64):Integer; inline;
|
||||
|
||||
function ELF64_R_SYM(i:QWORD):DWORD; inline;
|
||||
function ELF64_R_SYM (i:QWORD):DWORD; inline;
|
||||
function ELF64_R_TYPE(i:QWORD):DWORD; inline;
|
||||
function ELF64_ST_BIND(i:Byte):Byte; inline;
|
||||
function ELF64_ST_TYPE(i:Byte):Byte; inline;
|
||||
|
|
|
@ -760,15 +760,16 @@ begin
|
|||
TAILQ_INIT(@dynlibs_info.fini_list);
|
||||
TAILQ_INIT(@dynlibs_info.obj_list);
|
||||
|
||||
dynlibs_info.obj_count :=0;
|
||||
dynlibs_info.tls_last_offset:=0;
|
||||
dynlibs_info.tls_last_size :=0;
|
||||
dynlibs_info.d_tls_count :=0;
|
||||
dynlibs_info.tls_count :=1;
|
||||
dynlibs_info.tls_max :=1;
|
||||
//dynlibs_info.bits :=0;
|
||||
dynlibs_info.obj_count :=0;
|
||||
dynlibs_info.tls_last_offset :=0;
|
||||
dynlibs_info.tls_last_size :=0;
|
||||
dynlibs_info.tls_static_space:=0;
|
||||
dynlibs_info.tls_count :=1;
|
||||
dynlibs_info.tls_max :=1;
|
||||
//dynlibs_info.bits :=0;
|
||||
|
||||
lib:=obj_new();
|
||||
lib^.mainprog:=1;
|
||||
lib^.relocbase:=imgp^.reloc_base;
|
||||
|
||||
text_addr:=g_vmspace.vm_taddr;
|
||||
|
@ -864,7 +865,7 @@ begin
|
|||
Exit;
|
||||
end;
|
||||
|
||||
init_relo_bits_process(lib);
|
||||
init_relo_bits(lib);
|
||||
|
||||
dynlibs_add_obj(lib);
|
||||
|
||||
|
@ -1026,7 +1027,7 @@ begin
|
|||
ET_SCE_DYNEXEC :
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'exec_self_imgact:',imgp^.execpath,' unspported e_type:',HexStr(hdr^.e_type,4));
|
||||
Writeln(StdErr,'exec_self_imgact:',imgp^.execpath,' unspported e_type:0x',HexStr(hdr^.e_type,4));
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
end;
|
||||
|
|
|
@ -6,6 +6,7 @@ unit kern_reloc;
|
|||
interface
|
||||
|
||||
uses
|
||||
sysutils,
|
||||
mqueue,
|
||||
elf64,
|
||||
kern_thr,
|
||||
|
@ -16,12 +17,333 @@ function relocate_one_object(obj:p_lib_info;jmpslots:Integer):Integer;
|
|||
|
||||
implementation
|
||||
|
||||
uses
|
||||
errno,
|
||||
systm,
|
||||
kern_dlsym;
|
||||
|
||||
function check_addr(obj:p_lib_info;where:Pointer;size:Integer):Integer;
|
||||
var
|
||||
map_base:Pointer;
|
||||
relro_addr:Pointer;
|
||||
begin
|
||||
map_base:=obj^.map_base;
|
||||
relro_addr:=obj^.relro_addr;
|
||||
|
||||
if ( (map_base > where) or
|
||||
((map_base + obj^.text_size) < (where + size))
|
||||
) and
|
||||
|
||||
( (obj^.data_addr > where) or
|
||||
((obj^.data_addr + obj^.data_size) < (where + size))
|
||||
|
||||
) and
|
||||
( (relro_addr=nil) or
|
||||
(relro_addr > where) or
|
||||
(obj^.relro_size=0) or
|
||||
((relro_addr + obj^.relro_size) < (where + size))
|
||||
) then
|
||||
begin
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
Result:=0;
|
||||
end;
|
||||
|
||||
function reloc_non_plt(obj:p_lib_info):Integer;
|
||||
label
|
||||
_next,
|
||||
_move64;
|
||||
var
|
||||
rela:p_elf64_rela;
|
||||
sym_zero:p_elf64_sym;
|
||||
|
||||
where:Pointer;
|
||||
data:Pointer;
|
||||
|
||||
data32:Integer;
|
||||
r_type:Integer;
|
||||
|
||||
def:p_elf64_sym;
|
||||
defobj:p_lib_info;
|
||||
|
||||
cache:array of t_SymCache;
|
||||
|
||||
i,count:Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
//////
|
||||
|
||||
cache:=nil;
|
||||
SetLength(cache,obj^.rel_data^.dynsymcount);
|
||||
|
||||
sym_zero:=@dynlibs_info.sym_zero;
|
||||
|
||||
rela :=obj^.rel_data^.rela_addr;
|
||||
count:=obj^.rel_data^.rela_size div SizeOf(elf64_rela);
|
||||
|
||||
defobj:=nil;
|
||||
|
||||
if (rela<>nil) and (count<>0) then
|
||||
For i:=0 to count-1 do
|
||||
if not 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,'reloc_non_plt:','Unexpected R_X86_64_COPY relocation in shared library');
|
||||
Exit(ENOEXEC);
|
||||
end; //R_X86_64_COPY
|
||||
|
||||
R_X86_64_RELATIVE:
|
||||
begin
|
||||
Result:=check_addr(obj,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','idx=',i,' where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
data:=(obj^.relocbase + rela^.r_addend);
|
||||
|
||||
defobj:=obj;
|
||||
goto _move64;
|
||||
end; //R_X86_64_RELATIVE
|
||||
|
||||
R_X86_64_64,
|
||||
R_X86_64_GLOB_DAT,
|
||||
R_X86_64_DTPMOD64,
|
||||
R_X86_64_DTPOFF64,
|
||||
R_X86_64_TPOFF64: //64
|
||||
begin
|
||||
Result:=check_addr(obj,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','idx=',i,' where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
def:=find_symdef(ELF64_R_SYM(rela^.r_info),obj,defobj,0,@cache[0]);
|
||||
|
||||
if (def<>nil) then
|
||||
case r_type of
|
||||
R_X86_64_64:
|
||||
begin
|
||||
data:=(defobj^.relocbase + rela^.r_addend + def^.st_value);
|
||||
|
||||
if (def<>sym_zero) then
|
||||
begin
|
||||
goto _move64;
|
||||
end;
|
||||
end; //R_X86_64_64
|
||||
|
||||
R_X86_64_GLOB_DAT:
|
||||
begin
|
||||
data:=(defobj^.relocbase + def^.st_value);
|
||||
|
||||
if (def<>sym_zero) then
|
||||
begin
|
||||
goto _move64;
|
||||
end;
|
||||
end; //R_X86_64_GLOB_DAT
|
||||
|
||||
R_X86_64_DTPMOD64:
|
||||
begin
|
||||
Result:=copyin(where,@data,SizeOf(Pointer)); //data:=where^
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyin() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
data:=(data + defobj^.tls_index);
|
||||
|
||||
Result:=copyout(@data,where,8); //where^:=data
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_DTPMOD64
|
||||
|
||||
R_X86_64_DTPOFF64:
|
||||
begin
|
||||
Result:=copyin(where,@data,SizeOf(Pointer)); //data:=where^
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyin() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
data:=(data + rela^.r_addend + def^.st_value);
|
||||
|
||||
Result:=copyout(@data,where,8); //where^:=data
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_DTPOFF64
|
||||
|
||||
R_X86_64_TPOFF64:
|
||||
begin
|
||||
if not allocate_tls_offset(defobj) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','No space available for static Thread Local Storage');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
data:=Pointer(def^.st_value - defobj^.tls_offset + rela^.r_addend);
|
||||
|
||||
Result:=copyout(@data,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_TPOFF64
|
||||
|
||||
else;
|
||||
end; //case
|
||||
|
||||
end; //R_X86_64_*64
|
||||
|
||||
R_X86_64_PC32,
|
||||
R_X86_64_DTPOFF32,
|
||||
R_X86_64_TPOFF32: //32
|
||||
begin
|
||||
Result:=check_addr(obj,where,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','idx=',i,' where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
def:=find_symdef(ELF64_R_SYM(rela^.r_info),obj,defobj,0,@cache[0]);
|
||||
|
||||
if (def<>nil) then
|
||||
case r_type of
|
||||
|
||||
R_X86_64_PC32:
|
||||
begin
|
||||
data32:=(Integer(QWORD(defobj^.relocbase)) - Integer(QWORD(where))) + Integer(def^.st_value) + Integer(rela^.r_addend);
|
||||
|
||||
if (def<>sym_zero) then
|
||||
begin
|
||||
data:=Pointer(QWORD(data32));
|
||||
Result:=check_addr(defobj,data,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','idx=',i,' where32=0x',HexStr(data32,8),' ref=',dynlib_basename(defobj^.lib_path));
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:=relocate_text_or_data_segment(obj,@data32,where,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where32=0x',HexStr(data32,8),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_PC32
|
||||
|
||||
R_X86_64_DTPOFF32:
|
||||
begin
|
||||
Result:=copyin(where,@data,SizeOf(Pointer)); //data:=where^
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyin() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
data:=(data + rela^.r_addend + def^.st_value);
|
||||
|
||||
Result:=copyout(@data,where,8); //where^:=data
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_DTPOFF32
|
||||
|
||||
|
||||
R_X86_64_TPOFF32:
|
||||
begin
|
||||
if not allocate_tls_offset(defobj) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','No space available for static Thread Local Storage');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
data32:=Integer(def^.st_value) - Integer(defobj^.tls_offset) + Integer(rela^.r_addend);
|
||||
|
||||
Result:=copyout(@data32,where,SizeOf(Integer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
end; //R_X86_64_TPOFF32
|
||||
|
||||
else;
|
||||
end; //case
|
||||
|
||||
end; //R_X86_64_*32
|
||||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','Unsupported reloc type=',r_type);
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
end; //case
|
||||
|
||||
//
|
||||
_next:
|
||||
Inc(rela);
|
||||
end;
|
||||
|
||||
Exit(0);
|
||||
_move64:
|
||||
|
||||
Result:=check_addr(defobj,data,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','idx=',i,' where=0x',HexStr(data),' ref=',dynlib_basename(defobj^.lib_path));
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:=relocate_text_or_data_segment(obj,@data,where,SizeOf(Pointer));
|
||||
if (Result<>0) then
|
||||
begin
|
||||
Writeln(StdErr,'reloc_non_plt:','copyout() failed. where=0x',HexStr(data),' [',r_type,']');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
set_relo_bits(obj,i);
|
||||
|
||||
goto _next;
|
||||
end;
|
||||
|
||||
|
||||
function reloc_jmplots(obj:p_lib_info):Integer;
|
||||
begin
|
||||
Result:=0;
|
||||
|
|
|
@ -208,6 +208,7 @@ function self_load_section(imgp:p_image_params;
|
|||
|
||||
function is_system_path(path:pchar):Boolean;
|
||||
function is_libc_or_fios(path:pchar):Boolean;
|
||||
function dynlib_basename(path:pchar):pchar;
|
||||
|
||||
implementation
|
||||
|
||||
|
@ -472,10 +473,18 @@ begin
|
|||
if (imgp=nil) then Exit;
|
||||
|
||||
imgp^.authinfo:=Default(t_authinfo);
|
||||
imgp^.authinfo.app_type_id:=QWORD($3100000000000001);
|
||||
|
||||
if (imgp^.image_header=nil) then Exit;
|
||||
if (imgp^.image_self =nil) then Exit;
|
||||
if (imgp^.image_header=nil) or
|
||||
(imgp^.image_self =nil) then
|
||||
begin
|
||||
case ExtractFileExt(imgp^.execpath) of
|
||||
'.sprx','.prx' :imgp^.authinfo.app_type_id:=QWORD($3900000000000002);
|
||||
'.sdll','.sexe':imgp^.authinfo.app_type_id:=QWORD($3901000000000001);
|
||||
else
|
||||
imgp^.authinfo.app_type_id:=QWORD($3100000000000001);
|
||||
end;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
hdr:=imgp^.image_header;
|
||||
s:=SizeOf(t_self_header);
|
||||
|
@ -1181,5 +1190,19 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function dynlib_basename(path:pchar):pchar;
|
||||
var
|
||||
idx:pchar;
|
||||
begin
|
||||
idx:=strrscan(path,'/');
|
||||
if (idx=nil) then
|
||||
begin
|
||||
Result:=path;
|
||||
end else
|
||||
begin
|
||||
Result:=idx+1;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
|
|
@ -113,10 +113,11 @@ type
|
|||
|
||||
//t_rtld_bits rtld_flags;
|
||||
|
||||
mainprog :Integer;
|
||||
tls_done :Integer;
|
||||
init_scanned :Integer;
|
||||
init_done :Integer;
|
||||
init_fini :Integer;
|
||||
on_fini_list :Integer;
|
||||
textrel :Integer;
|
||||
init_plt :Integer;
|
||||
is_system :Integer;
|
||||
|
@ -126,7 +127,7 @@ type
|
|||
dldags :TAILQ_HEAD; //Objlist_Entry
|
||||
dagmembers:TAILQ_HEAD; //Objlist_Entry
|
||||
|
||||
relo_bits_process:PByte;
|
||||
relo_bits:PByte;
|
||||
|
||||
rel_data:p_rel_data;
|
||||
|
||||
|
@ -188,9 +189,9 @@ type
|
|||
init_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
||||
fini_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
||||
|
||||
tls_last_offset:QWORD;
|
||||
tls_last_size :QWORD;
|
||||
d_tls_count :QWORD;
|
||||
tls_last_offset :QWORD;
|
||||
tls_last_size :QWORD;
|
||||
tls_static_space:QWORD;
|
||||
|
||||
tls_count :Integer;
|
||||
tls_max :Integer;
|
||||
|
@ -228,6 +229,9 @@ procedure _set_lib_path(lib:p_lib_info;path:PAnsiChar);
|
|||
procedure release_per_file_info_obj(lib: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;
|
||||
procedure free_tls_offset(obj:p_lib_info);
|
||||
|
||||
procedure initlist_add_objects(var fini_proc_list:TAILQ_HEAD;
|
||||
obj :p_lib_info;
|
||||
tail:p_lib_info;
|
||||
|
@ -241,7 +245,9 @@ function digest_dynamic(lib:p_lib_info):Integer;
|
|||
|
||||
procedure dynlibs_add_obj(lib:p_lib_info);
|
||||
|
||||
procedure init_relo_bits_process(lib: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 donelist_init(var dlp:t_DoneList); inline;
|
||||
function donelist_check(var dlp:t_DoneList;obj:p_lib_info):Boolean; inline;
|
||||
|
@ -249,6 +255,8 @@ function donelist_check(var dlp:t_DoneList;obj:p_lib_info):Boolean; inline;
|
|||
function change_relro_protection(obj:p_lib_info;prot:Integer):Integer;
|
||||
function change_relro_protection_all(prot:Integer):Integer;
|
||||
|
||||
function relocate_text_or_data_segment(obj:p_lib_info;src,dst:Pointer;size:QWORD):Integer;
|
||||
|
||||
procedure init_dag (root:p_lib_info);
|
||||
procedure ref_dag (root:p_lib_info);
|
||||
procedure unref_dag(root:p_lib_info);
|
||||
|
@ -548,7 +556,7 @@ begin
|
|||
$6100003e:
|
||||
begin
|
||||
_unsupp:
|
||||
Writeln(StdErr,'preprocess_dt_entries:','Unsupported DT tag ',HexStr(dt_ent^.d_tag,8),' found in ',new^.lib_path);
|
||||
Writeln(StdErr,'preprocess_dt_entries:','Unsupported DT tag 0x',HexStr(dt_ent^.d_tag,8),' found in ',new^.lib_path);
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
|
@ -558,7 +566,7 @@ begin
|
|||
DT_RELA,
|
||||
DT_JMPREL:
|
||||
begin
|
||||
Writeln(StdErr,'preprocess_dt_entries:','ORBIS object file does not support DT tag ',HexStr(dt_ent^.d_tag,8),' found in ',new^.lib_path);
|
||||
Writeln(StdErr,'preprocess_dt_entries:','ORBIS object file does not support DT tag 0x',HexStr(dt_ent^.d_tag,8),' found in ',new^.lib_path);
|
||||
Exit(EINVAL);
|
||||
end;
|
||||
|
||||
|
@ -684,11 +692,50 @@ begin
|
|||
|
||||
end;
|
||||
|
||||
procedure free_tls_offset(lib:p_lib_info);
|
||||
function allocate_tls_offset(obj:p_lib_info):Boolean;
|
||||
var
|
||||
off:Int64;
|
||||
begin
|
||||
if (lib^.tls_done<>0) and (lib^.tls_offset=dynlibs_info.tls_last_offset) then
|
||||
if (obj^.tls_done<>0) then
|
||||
begin
|
||||
dynlibs_info.tls_last_offset:=lib^.tls_offset - lib^.tls_size;
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
off:=obj^.tls_size;
|
||||
if (off=0) then
|
||||
begin
|
||||
obj^.tls_done:=1;
|
||||
Exit(True);
|
||||
end;
|
||||
|
||||
if (obj^.tls_index=1) then
|
||||
begin
|
||||
off:=off + -1;
|
||||
end else
|
||||
begin
|
||||
off:=off + -1 + dynlibs_info.tls_last_offset;
|
||||
end;
|
||||
|
||||
off:=(off + obj^.tls_align) and (-obj^.tls_align);
|
||||
|
||||
if ((dynlibs_info.tls_static_space<>0) and (dynlibs_info.tls_static_space < off)) then
|
||||
begin
|
||||
Exit(False);
|
||||
end;
|
||||
|
||||
obj^.tls_offset:=off;
|
||||
|
||||
dynlibs_info.tls_last_offset:=off;
|
||||
dynlibs_info.tls_last_size :=obj^.tls_size;
|
||||
|
||||
Result:=True;
|
||||
end;
|
||||
|
||||
procedure free_tls_offset(obj:p_lib_info);
|
||||
begin
|
||||
if (obj^.tls_done<>0) and (obj^.tls_offset=dynlibs_info.tls_last_offset) then
|
||||
begin
|
||||
dynlibs_info.tls_last_offset:=obj^.tls_offset - obj^.tls_size;
|
||||
dynlibs_info.tls_last_size :=0;
|
||||
end;
|
||||
end;
|
||||
|
@ -747,10 +794,10 @@ begin
|
|||
lib^.lib_path:=nil;
|
||||
end;
|
||||
|
||||
if (lib^.relo_bits_process<>nil) then
|
||||
if (lib^.relo_bits<>nil) then
|
||||
begin
|
||||
FreeMem(lib^.relo_bits_process);
|
||||
lib^.relo_bits_process:=nil
|
||||
FreeMem(lib^.relo_bits);
|
||||
lib^.relo_bits:=nil
|
||||
end;
|
||||
|
||||
libs:=TAILQ_FIRST(@lib^.lib_table);
|
||||
|
@ -806,7 +853,7 @@ function obj_get_str(lib:p_lib_info;offset:Int64):pchar;
|
|||
begin
|
||||
if (lib^.rel_data^.strtab_size<=offset) then
|
||||
begin
|
||||
Writeln(StdErr,'obj_get_str:','offset=',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 ',lib^.lib_path);
|
||||
Exit(nil);
|
||||
end;
|
||||
|
||||
|
@ -881,11 +928,11 @@ begin
|
|||
objlist_push_tail(init_proc_list,obj);
|
||||
end;
|
||||
|
||||
if (obj^.fini_proc_addr<>nil) and (obj^.init_fini=0) then
|
||||
if (obj^.fini_proc_addr<>nil) and (obj^.on_fini_list=0) then
|
||||
begin
|
||||
objlist_push_tail(fini_proc_list,obj);
|
||||
|
||||
obj^.init_fini:=1;
|
||||
obj^.on_fini_list:=1;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
@ -1153,7 +1200,7 @@ begin
|
|||
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'digest_dynamic:','Unsupported DT tag ',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 ',lib^.lib_path);
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
|
||||
|
@ -1212,19 +1259,40 @@ begin
|
|||
Inc(dynlibs_info.obj_count);
|
||||
end;
|
||||
|
||||
procedure init_relo_bits_process(lib:p_lib_info);
|
||||
procedure init_relo_bits(obj:p_lib_info);
|
||||
var
|
||||
count:Integer;
|
||||
begin
|
||||
if (lib^.rel_data=nil) then
|
||||
if (obj^.rel_data=nil) then
|
||||
begin
|
||||
count:=0;
|
||||
end else
|
||||
begin
|
||||
count:=(lib^.rel_data^.pltrela_size div sizeof(elf64_rela))+(lib^.rel_data^.rela_size div sizeof(elf64_rela));
|
||||
count:=(obj^.rel_data^.pltrela_size div sizeof(elf64_rela))+(obj^.rel_data^.rela_size div sizeof(elf64_rela));
|
||||
end;
|
||||
|
||||
lib^.relo_bits_process:=AllocMem((count+7) div 8);
|
||||
if (count=0) then
|
||||
begin
|
||||
obj^.relo_bits:=nil;
|
||||
end else
|
||||
begin
|
||||
obj^.relo_bits:=AllocMem((count+7) div 8);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
function check_relo_bits(obj:p_lib_info;i:Integer):Boolean;
|
||||
begin
|
||||
if (obj^.relo_bits=nil) then Exit(False);
|
||||
|
||||
Result:=((obj^.relo_bits[i shr 3] shr (i and 7)) and 1)<>0;
|
||||
end;
|
||||
|
||||
procedure set_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] or (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;
|
||||
|
@ -1513,7 +1581,7 @@ begin
|
|||
ET_SCE_DYNAMIC:
|
||||
else
|
||||
begin
|
||||
Writeln(StdErr,'self_load_shared_object:',imgp^.execpath,' Unsupported ELF e_type:',HexStr(hdr^.e_type,4));
|
||||
Writeln(StdErr,'self_load_shared_object:',imgp^.execpath,' Unsupported ELF e_type:0x',HexStr(hdr^.e_type,4));
|
||||
error:=ENOEXEC;
|
||||
goto _fail_dealloc;
|
||||
end;
|
||||
|
@ -1645,6 +1713,37 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function relocate_text_or_data_segment(obj:p_lib_info;src,dst:Pointer;size:QWORD):Integer;
|
||||
var
|
||||
map:vm_map_t;
|
||||
begin
|
||||
if (obj^.textrel=0) or
|
||||
(obj^.map_base > dst) or
|
||||
((obj^.map_base + obj^.text_size) < (dst + size)) then
|
||||
begin
|
||||
Result:=copyout(src,dst,size);
|
||||
end else
|
||||
if (p_proc.p_sdk_version < $1700000) then
|
||||
begin
|
||||
map:=@g_vmspace.vm_map;
|
||||
//
|
||||
vm_map_lock(map);
|
||||
//
|
||||
Result:=change_relro_protection(obj,VM_PROT_RW);
|
||||
if (Result<>0) then Exit;
|
||||
|
||||
Result:=copyout(src,dst,size);
|
||||
|
||||
change_relro_protection(obj,VM_PROT_READ);
|
||||
//
|
||||
vm_map_unlock(map);
|
||||
end else
|
||||
begin
|
||||
Writeln(StdErr,'relocate_text_or_data_segment:','text relocation is prohibited.');
|
||||
Exit(ENOEXEC);
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure donelist_init(var dlp:t_DoneList); inline;
|
||||
begin
|
||||
SetLength(dlp.objs,dynlibs_info.obj_count);
|
||||
|
@ -1892,7 +1991,7 @@ begin
|
|||
goto _error;
|
||||
end;
|
||||
|
||||
init_relo_bits_process(lib);
|
||||
init_relo_bits(lib);
|
||||
dynlibs_add_obj(new);
|
||||
new^.loaded:=1;
|
||||
Exit(new);
|
||||
|
|
Loading…
Reference in New Issue