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_BLOCK_SIZE(i:Int64):Int64; inline;
|
||||||
function SELF_SEGMENT_INDEX(i:Int64):Integer; 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_R_TYPE(i:QWORD):DWORD; inline;
|
||||||
function ELF64_ST_BIND(i:Byte):Byte; inline;
|
function ELF64_ST_BIND(i:Byte):Byte; inline;
|
||||||
function ELF64_ST_TYPE(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.fini_list);
|
||||||
TAILQ_INIT(@dynlibs_info.obj_list);
|
TAILQ_INIT(@dynlibs_info.obj_list);
|
||||||
|
|
||||||
dynlibs_info.obj_count :=0;
|
dynlibs_info.obj_count :=0;
|
||||||
dynlibs_info.tls_last_offset:=0;
|
dynlibs_info.tls_last_offset :=0;
|
||||||
dynlibs_info.tls_last_size :=0;
|
dynlibs_info.tls_last_size :=0;
|
||||||
dynlibs_info.d_tls_count :=0;
|
dynlibs_info.tls_static_space:=0;
|
||||||
dynlibs_info.tls_count :=1;
|
dynlibs_info.tls_count :=1;
|
||||||
dynlibs_info.tls_max :=1;
|
dynlibs_info.tls_max :=1;
|
||||||
//dynlibs_info.bits :=0;
|
//dynlibs_info.bits :=0;
|
||||||
|
|
||||||
lib:=obj_new();
|
lib:=obj_new();
|
||||||
|
lib^.mainprog:=1;
|
||||||
lib^.relocbase:=imgp^.reloc_base;
|
lib^.relocbase:=imgp^.reloc_base;
|
||||||
|
|
||||||
text_addr:=g_vmspace.vm_taddr;
|
text_addr:=g_vmspace.vm_taddr;
|
||||||
|
@ -864,7 +865,7 @@ begin
|
||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
init_relo_bits_process(lib);
|
init_relo_bits(lib);
|
||||||
|
|
||||||
dynlibs_add_obj(lib);
|
dynlibs_add_obj(lib);
|
||||||
|
|
||||||
|
@ -1026,7 +1027,7 @@ begin
|
||||||
ET_SCE_DYNEXEC :
|
ET_SCE_DYNEXEC :
|
||||||
else
|
else
|
||||||
begin
|
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);
|
Exit(ENOEXEC);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
|
@ -6,6 +6,7 @@ unit kern_reloc;
|
||||||
interface
|
interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
|
sysutils,
|
||||||
mqueue,
|
mqueue,
|
||||||
elf64,
|
elf64,
|
||||||
kern_thr,
|
kern_thr,
|
||||||
|
@ -16,12 +17,333 @@ function relocate_one_object(obj:p_lib_info;jmpslots:Integer):Integer;
|
||||||
|
|
||||||
implementation
|
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;
|
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
|
begin
|
||||||
Result:=0;
|
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;
|
end;
|
||||||
|
|
||||||
|
|
||||||
function reloc_jmplots(obj:p_lib_info):Integer;
|
function reloc_jmplots(obj:p_lib_info):Integer;
|
||||||
begin
|
begin
|
||||||
Result:=0;
|
Result:=0;
|
||||||
|
|
|
@ -208,6 +208,7 @@ function self_load_section(imgp:p_image_params;
|
||||||
|
|
||||||
function is_system_path(path:pchar):Boolean;
|
function is_system_path(path:pchar):Boolean;
|
||||||
function is_libc_or_fios(path:pchar):Boolean;
|
function is_libc_or_fios(path:pchar):Boolean;
|
||||||
|
function dynlib_basename(path:pchar):pchar;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
@ -472,10 +473,18 @@ begin
|
||||||
if (imgp=nil) then Exit;
|
if (imgp=nil) then Exit;
|
||||||
|
|
||||||
imgp^.authinfo:=Default(t_authinfo);
|
imgp^.authinfo:=Default(t_authinfo);
|
||||||
imgp^.authinfo.app_type_id:=QWORD($3100000000000001);
|
|
||||||
|
|
||||||
if (imgp^.image_header=nil) then Exit;
|
if (imgp^.image_header=nil) or
|
||||||
if (imgp^.image_self =nil) then Exit;
|
(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;
|
hdr:=imgp^.image_header;
|
||||||
s:=SizeOf(t_self_header);
|
s:=SizeOf(t_self_header);
|
||||||
|
@ -1181,5 +1190,19 @@ begin
|
||||||
end;
|
end;
|
||||||
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.
|
end.
|
||||||
|
|
||||||
|
|
|
@ -113,10 +113,11 @@ type
|
||||||
|
|
||||||
//t_rtld_bits rtld_flags;
|
//t_rtld_bits rtld_flags;
|
||||||
|
|
||||||
|
mainprog :Integer;
|
||||||
tls_done :Integer;
|
tls_done :Integer;
|
||||||
init_scanned :Integer;
|
init_scanned :Integer;
|
||||||
init_done :Integer;
|
init_done :Integer;
|
||||||
init_fini :Integer;
|
on_fini_list :Integer;
|
||||||
textrel :Integer;
|
textrel :Integer;
|
||||||
init_plt :Integer;
|
init_plt :Integer;
|
||||||
is_system :Integer;
|
is_system :Integer;
|
||||||
|
@ -126,7 +127,7 @@ type
|
||||||
dldags :TAILQ_HEAD; //Objlist_Entry
|
dldags :TAILQ_HEAD; //Objlist_Entry
|
||||||
dagmembers:TAILQ_HEAD; //Objlist_Entry
|
dagmembers:TAILQ_HEAD; //Objlist_Entry
|
||||||
|
|
||||||
relo_bits_process:PByte;
|
relo_bits:PByte;
|
||||||
|
|
||||||
rel_data:p_rel_data;
|
rel_data:p_rel_data;
|
||||||
|
|
||||||
|
@ -188,9 +189,9 @@ type
|
||||||
init_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
init_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
||||||
fini_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
fini_proc_list:TAILQ_HEAD; //p_Objlist_Entry
|
||||||
|
|
||||||
tls_last_offset:QWORD;
|
tls_last_offset :QWORD;
|
||||||
tls_last_size :QWORD;
|
tls_last_size :QWORD;
|
||||||
d_tls_count :QWORD;
|
tls_static_space:QWORD;
|
||||||
|
|
||||||
tls_count :Integer;
|
tls_count :Integer;
|
||||||
tls_max :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);
|
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 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;
|
procedure initlist_add_objects(var fini_proc_list:TAILQ_HEAD;
|
||||||
obj :p_lib_info;
|
obj :p_lib_info;
|
||||||
tail: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 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;
|
procedure donelist_init(var dlp:t_DoneList); inline;
|
||||||
function donelist_check(var dlp:t_DoneList;obj:p_lib_info):Boolean; 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(obj:p_lib_info;prot:Integer):Integer;
|
||||||
function change_relro_protection_all(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 init_dag (root:p_lib_info);
|
||||||
procedure ref_dag (root:p_lib_info);
|
procedure ref_dag (root:p_lib_info);
|
||||||
procedure unref_dag(root:p_lib_info);
|
procedure unref_dag(root:p_lib_info);
|
||||||
|
@ -548,7 +556,7 @@ begin
|
||||||
$6100003e:
|
$6100003e:
|
||||||
begin
|
begin
|
||||||
_unsupp:
|
_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);
|
Exit(ENOEXEC);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -558,7 +566,7 @@ begin
|
||||||
DT_RELA,
|
DT_RELA,
|
||||||
DT_JMPREL:
|
DT_JMPREL:
|
||||||
begin
|
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);
|
Exit(EINVAL);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -684,11 +692,50 @@ begin
|
||||||
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure free_tls_offset(lib:p_lib_info);
|
function allocate_tls_offset(obj:p_lib_info):Boolean;
|
||||||
|
var
|
||||||
|
off:Int64;
|
||||||
begin
|
begin
|
||||||
if (lib^.tls_done<>0) and (lib^.tls_offset=dynlibs_info.tls_last_offset) then
|
if (obj^.tls_done<>0) then
|
||||||
begin
|
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;
|
dynlibs_info.tls_last_size :=0;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
@ -747,10 +794,10 @@ begin
|
||||||
lib^.lib_path:=nil;
|
lib^.lib_path:=nil;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if (lib^.relo_bits_process<>nil) then
|
if (lib^.relo_bits<>nil) then
|
||||||
begin
|
begin
|
||||||
FreeMem(lib^.relo_bits_process);
|
FreeMem(lib^.relo_bits);
|
||||||
lib^.relo_bits_process:=nil
|
lib^.relo_bits:=nil
|
||||||
end;
|
end;
|
||||||
|
|
||||||
libs:=TAILQ_FIRST(@lib^.lib_table);
|
libs:=TAILQ_FIRST(@lib^.lib_table);
|
||||||
|
@ -806,7 +853,7 @@ function obj_get_str(lib:p_lib_info;offset:Int64):pchar;
|
||||||
begin
|
begin
|
||||||
if (lib^.rel_data^.strtab_size<=offset) then
|
if (lib^.rel_data^.strtab_size<=offset) then
|
||||||
begin
|
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);
|
Exit(nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -881,11 +928,11 @@ begin
|
||||||
objlist_push_tail(init_proc_list,obj);
|
objlist_push_tail(init_proc_list,obj);
|
||||||
end;
|
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
|
begin
|
||||||
objlist_push_tail(fini_proc_list,obj);
|
objlist_push_tail(fini_proc_list,obj);
|
||||||
|
|
||||||
obj^.init_fini:=1;
|
obj^.on_fini_list:=1;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1153,7 +1200,7 @@ begin
|
||||||
|
|
||||||
else
|
else
|
||||||
begin
|
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);
|
Exit(ENOEXEC);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
@ -1212,19 +1259,40 @@ begin
|
||||||
Inc(dynlibs_info.obj_count);
|
Inc(dynlibs_info.obj_count);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure init_relo_bits_process(lib:p_lib_info);
|
procedure init_relo_bits(obj:p_lib_info);
|
||||||
var
|
var
|
||||||
count:Integer;
|
count:Integer;
|
||||||
begin
|
begin
|
||||||
if (lib^.rel_data=nil) then
|
if (obj^.rel_data=nil) then
|
||||||
begin
|
begin
|
||||||
count:=0;
|
count:=0;
|
||||||
end else
|
end else
|
||||||
begin
|
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;
|
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;
|
end;
|
||||||
|
|
||||||
function dynlib_load_sections(imgp:p_image_params;new:p_lib_info;phdr:p_elf64_phdr;count:Integer;delta:QWORD):Integer;
|
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:
|
ET_SCE_DYNAMIC:
|
||||||
else
|
else
|
||||||
begin
|
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;
|
error:=ENOEXEC;
|
||||||
goto _fail_dealloc;
|
goto _fail_dealloc;
|
||||||
end;
|
end;
|
||||||
|
@ -1645,6 +1713,37 @@ begin
|
||||||
end;
|
end;
|
||||||
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;
|
procedure donelist_init(var dlp:t_DoneList); inline;
|
||||||
begin
|
begin
|
||||||
SetLength(dlp.objs,dynlibs_info.obj_count);
|
SetLength(dlp.objs,dynlibs_info.obj_count);
|
||||||
|
@ -1892,7 +1991,7 @@ begin
|
||||||
goto _error;
|
goto _error;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
init_relo_bits_process(lib);
|
init_relo_bits(lib);
|
||||||
dynlibs_add_obj(new);
|
dynlibs_add_obj(new);
|
||||||
new^.loaded:=1;
|
new^.loaded:=1;
|
||||||
Exit(new);
|
Exit(new);
|
||||||
|
|
Loading…
Reference in New Issue