diff --git a/sys/kern/kern_dynlib.pas b/sys/kern/kern_dynlib.pas index 3df2eb72..2b0b5f02 100644 --- a/sys/kern/kern_dynlib.pas +++ b/sys/kern/kern_dynlib.pas @@ -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)); diff --git a/sys/kern/kern_reloc.pas b/sys/kern/kern_reloc.pas index 368854be..b176406d 100644 --- a/sys/kern/kern_reloc.pas +++ b/sys/kern/kern_reloc.pas @@ -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 diff --git a/sys/kern/kern_rtld.pas b/sys/kern/kern_rtld.pas index 76d384e0..0ac1e51e 100644 --- a/sys/kern/kern_rtld.pas +++ b/sys/kern/kern_rtld.pas @@ -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; diff --git a/sys/kern/subr_dynlib.pas b/sys/kern/subr_dynlib.pas index 7bb3058b..5cd182fa 100644 --- a/sys/kern/subr_dynlib.pas +++ b/sys/kern/subr_dynlib.pas @@ -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);