Bladeren bron

Merged revision(s) 32052 from trunk:
* Return a real base address for ELF executables by GetModuleByAddr() instead of hard-coded 0.
* Obtain a real processaddress for ELF images by OpenExeFile() instead of hard-coded 0.
* It fixes line info information for Position Independent Executables (PIE).
........

git-svn-id: branches/fixes_3_0@33442 -

yury 9 jaren geleden
bovenliggende
commit
3006670da1
2 gewijzigde bestanden met toevoegingen van 39 en 0 verwijderingen
  1. 37 0
      rtl/inc/exeinfo.pp
  2. 2 0
      rtl/unix/dl.pp

+ 37 - 0
rtl/inc/exeinfo.pp

@@ -728,6 +728,16 @@ type
       sh_addralign      : longword;
       sh_entsize        : longword;
     end;
+  telfproghdr=packed record
+    p_type            : longword;
+    p_offset          : longword;
+    p_vaddr           : longword;
+    p_paddr           : longword;
+    p_filesz          : longword;
+    p_memsz           : longword;
+    p_flags           : longword;
+    p_align           : longword;
+  end;
 {$endif ELF32 or BEOS}
 {$ifdef ELF64}
 type
@@ -764,6 +774,17 @@ type
       sh_addralign      : int64;
       sh_entsize        : int64;
     end;
+
+  telfproghdr=packed record
+    p_type            : longword;
+    p_flags           : longword;
+    p_offset          : qword;
+    p_vaddr           : qword;
+    p_paddr           : qword;
+    p_filesz          : qword;
+    p_memsz           : qword;
+    p_align           : qword;
+  end;
 {$endif ELF64}
 
 
@@ -772,6 +793,8 @@ function OpenElf(var e:TExeFile):boolean;
 var
   elfheader : telfheader;
   elfsec    : telfsechdr;
+  phdr      : telfproghdr;
+  i         : longint;
 begin
   OpenElf:=false;
   { read and check header }
@@ -788,6 +811,20 @@ begin
   e.secstrofs:=elfsec.sh_offset;
   e.sechdrofs:=elfheader.e_shoff;
   e.nsects:=elfheader.e_shnum;
+
+  { scan program headers to find the image base address }
+  e.processaddress:=High(e.processaddress);
+  seek(e.f,elfheader.e_phoff);
+  for i:=1 to elfheader.e_phnum do
+    begin
+      blockread(e.f,phdr,sizeof(phdr));
+      if (phdr.p_type = 1 {PT_LOAD}) and (ptruint(phdr.p_vaddr) < e.processaddress) then
+        e.processaddress:=phdr.p_vaddr;
+    end;
+
+  if e.processaddress = High(e.processaddress) then
+    e.processaddress:=0;
+
   OpenElf:=true;
 end;
 

+ 2 - 0
rtl/unix/dl.pp

@@ -125,8 +125,10 @@ uses
       dladdr(addr, @dlinfo);
       baseaddr:=dlinfo.dli_fbase;
       filename:=String(dlinfo.dli_fname);
+    {$ifdef darwin}
       if SimpleExtractFilename(filename)=SimpleExtractFilename(ParamStr(0)) then
         baseaddr:=nil;
+    {$endif darwin}
     end;
 
 {$ifdef aix}