This commit is contained in:
Pavel 2024-12-13 15:55:51 +03:00
parent e70e331627
commit a8e266b79a
4 changed files with 101 additions and 79 deletions

View File

@ -447,8 +447,9 @@ begin
Writeln(' get_info_ex :',obj^.lib_path);
Writeln(' obj.id :',obj^.id);
Writeln(' tls_index :0x',HexStr(tls_index shr 16,4),':',HexStr(tls_index,4));
Writeln(' tls_init_addr:0x',HexStr(obj^.tls_init_addr));
Writeln(' tls_flags :0x',HexStr(tls_index shr 16,4));
Writeln(' tls_index :0x',HexStr(tls_index,4));
Writeln(' tls_init_addr:0x',HexStr(QWORD(obj^.tls_init_addr),10));
Writeln(' tls_init_size:0x',HexStr(obj^.tls_init_size,8));
Writeln(' tls_size :0x',HexStr(obj^.tls_size ,8));
Writeln(' tls_offset :0x',HexStr(obj^.tls_offset ,8));

View File

@ -532,6 +532,11 @@ function dynlib_unlink_non_plt_reloc_each(root,obj:p_lib_info):Integer;
var
rela:p_elf64_rela;
entry:p_elf64_rela;
def:p_elf64_sym;
defobj:p_lib_info;
where:Pointer;
data:Pointer;
@ -551,73 +556,51 @@ begin
begin
if check_relo_bits(obj,i) then
begin
where:=Pointer(obj^.relocbase)+rela^.r_offset;
entry:=rela+i;
r_type:=ELF64_R_TYPE(rela^.r_info);
defobj:=nil;
def:=find_symdef(ELF64_R_SYM(entry^.r_info),obj,defobj,0,nil,nil);
case r_type of
if (def<>nil) and (defobj=root) then
begin
where:=Pointer(obj^.relocbase)+entry^.r_offset;
R_X86_64_NONE:; //ignore
r_type:=ELF64_R_TYPE(entry^.r_info);
R_X86_64_COPY:
if (obj^.rtld_flags.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
case r_type of
R_X86_64_64,
R_X86_64_GLOB_DAT,
R_X86_64_RELATIVE,
R_X86_64_TPOFF64:
begin
data:=Pointer(QWORD($840000000));
R_X86_64_NONE:; //ignore
Result:=relocate_text_or_data_segment(obj,@data,where,SizeOf(Pointer));
if (Result<>0) then
R_X86_64_COPY:
if (obj^.rtld_flags.mainprog=0) then
begin
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
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;
end; //R_X86_64_COPY
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
R_X86_64_64,
R_X86_64_GLOB_DAT,
R_X86_64_RELATIVE,
R_X86_64_TPOFF64:
begin
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','copyout() failed. where=0x',HexStr(where),' ref=',dynlib_basename(obj^.lib_path));
Exit(-1);
end;
data:=Pointer(QWORD($840000000));
reset_relo_bits(obj,i);
end; //64
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;
R_X86_64_DTPOFF32:
reset_relo_bits(obj,i);
end; //64
R_X86_64_PC32,
R_X86_64_TPOFF32:
begin
data32:=0;
data32:=Integer($40000000);
Result:=copyout(@data32,where,SizeOf(Integer));
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));
@ -627,11 +610,41 @@ begin
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;
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;
//non reset
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;
//non reset
end; //32
else
begin
Writeln(StdErr,'dynlib_unlink_non_plt_reloc_each:','Unsupported reloc type=',r_type);
Exit(-1);
end;
end;
end;
end; //case
@ -643,6 +656,8 @@ function dynlib_unlink_plt_reloc_each(root,obj:p_lib_info):Integer;
var
i,count,idofs:Integer;
plrel:p_elf64_rela;
entry:p_elf64_rela;
def:p_elf64_sym;
@ -655,15 +670,16 @@ var
begin
Result:=0;
plrel:=obj^.rel_data^.pltrela_addr;
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
if (plrel<>nil) and (count<>0) then
For i:=0 to count-1 do
begin
if check_relo_bits(obj,idofs+i) then
begin
entry:=obj^.rel_data^.pltrela_addr+i;
entry:=plrel+i;
if (ELF64_R_TYPE(entry^.r_info)<>R_X86_64_JUMP_SLOT) then
begin

View File

@ -164,8 +164,8 @@ function rtld_file_exists(path:pchar):Boolean;
function convert_prot(flags:Elf64_Word):Byte;
function rtld_mmap (addr:PQWORD;size:QWORD):Integer;
procedure rtld_munmap(base:Pointer;size:QWORD);
function rtld_mmap (addr:PQWORD ;size:QWORD;hint:PChar):Integer;
procedure rtld_munmap(base:Pointer;size:QWORD;hint:PChar);
function scan_phdr(imgp:p_image_params;phdr:p_elf64_phdr;count:Integer):Integer;
@ -621,10 +621,12 @@ begin
if ((flags and PF_R)<>0) then Result:=Result or VM_PROT_READ;
end;
function rtld_mmap(addr:PQWORD;size:QWORD):Integer;
function rtld_mmap(addr:PQWORD;size:QWORD;hint:PChar):Integer;
var
map:vm_map_t;
begin
Writeln(' rtld_mmap:0x',HexStr(addr^,12),'..0x',HexStr(addr^+size,12),':',hint);
map:=p_proc.p_vmspace;
if (addr^=0) and ((g_appinfo.mmap_flags and 2)<>0) then
@ -635,10 +637,12 @@ begin
Result:=vm_mmap2(map,addr,size,0,0,MAP_ANON or MAP_PRIVATE or (21 shl MAP_ALIGNMENT_BIT),OBJT_DEFAULT,nil,0,nil);
end;
procedure rtld_munmap(base:Pointer;size:QWORD);
procedure rtld_munmap(base:Pointer;size:QWORD;hint:PChar);
var
map:vm_map_t;
begin
Writeln(' rtld_munmap:0x',HexStr(QWORD(base),12),'..0x',HexStr(QWORD(base)+size,12),':',hint);
if (base<>nil) and (size<>0) then
begin
map:=p_proc.p_vmspace;

View File

@ -2195,9 +2195,7 @@ begin
end;
end;
error:=rtld_mmap(@addr,imgp^.max_addr-imgp^.min_addr);
Writeln(' rtld_mmap:0x',HexStr(addr,12),'..0x',HexStr(addr+(imgp^.max_addr-imgp^.min_addr),12),':',imgp^.execpath);
error:=rtld_mmap(@addr,imgp^.max_addr-imgp^.min_addr,imgp^.execpath);
if (error<>0) then
begin
@ -2739,7 +2737,7 @@ begin
_error:
rtld_munmap(new^.map_base,new^.map_size);
rtld_munmap(new^.map_base,new^.map_size,dynlib_basename(new^.lib_path));
obj_free(new);
@ -2792,13 +2790,16 @@ begin
begin
next:=TAILQ_NEXT(obj,@obj^.link);
//
rtld_munmap(obj^.map_base, obj^.map_size);
if (obj^.ref_count=0) then
begin
rtld_munmap(obj^.map_base, obj^.map_size,dynlib_basename(obj^.lib_path));
dynlibs_del_obj(obj);
dynlibs_del_obj(obj);
//dynlib_notify_event(td,lib->id,0x80);
//dynlib_notify_event(td,lib->id,0x80);
obj_free(obj);
obj_free(obj);
end;
//
obj:=next;
end;
@ -2836,9 +2837,7 @@ begin
//alloc addr
vaddr_lo:=ET_DYN_LOAD_ADDR_SYS;
error:=rtld_mmap(@vaddr_lo,obj^.map_size);
Writeln(' rtld_mmap:0x',HexStr(vaddr_lo,12),'..0x',HexStr(vaddr_lo+obj^.map_size,12),':',obj^.lib_path);
error:=rtld_mmap(@vaddr_lo,obj^.map_size,dynlib_basename(obj^.lib_path));
if (error<>0) then
begin
@ -2903,8 +2902,9 @@ begin
vm_map_unlock(map);
//
obj^.map_base :=Pointer(vaddr_lo);
obj^.data_addr:=data;
obj^.map_base :=Pointer(vaddr_lo);
obj^.data_addr :=data;
obj^.tls_init_addr:=data;
end;
const
@ -2978,6 +2978,7 @@ begin
Result^.rtld_flags.init_plt :=1;
Result^.rtld_flags.is_system:=1;
Result^.rtld_flags.internal :=1;
Result^.rtld_flags.tls_done :=1;
Result^.loaded:=1;
Writeln(' preload_prx_internal:',path);