diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-05-18 18:42:09 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2008-05-18 18:42:09 +0000 |
commit | 96b4ec27c24ed9e4564315438a754401edfa6bf8 (patch) | |
tree | c63befb2995afaf56cd0be4f117bf2a5df2776b5 | |
parent | f01a80862c74cc83e0ae721f3c46a9c70fff76ef (diff) | |
download | fpc-96b4ec27c24ed9e4564315438a754401edfa6bf8.tar.gz |
+ proper handling of lineinfo retrival for dyn. libs in unix
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@11010 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | rtl/inc/exeinfo.pp | 21 | ||||
-rw-r--r-- | rtl/inc/lineinfo.pp | 10 | ||||
-rw-r--r-- | rtl/inc/lnfodwrf.pp | 8 | ||||
-rw-r--r-- | rtl/unix/dl.pp | 61 | ||||
-rw-r--r-- | rtl/unix/sysunixh.inc | 7 |
5 files changed, 79 insertions, 28 deletions
diff --git a/rtl/inc/exeinfo.pp b/rtl/inc/exeinfo.pp index 08c6da2c5a..24491b3834 100644 --- a/rtl/inc/exeinfo.pp +++ b/rtl/inc/exeinfo.pp @@ -48,7 +48,6 @@ function ReadDebugLink(var e:TExeFile;var dbgfn:string):boolean; procedure GetModuleByAddr(addr: pointer; var baseaddr: pointer; var filename: string); - implementation uses @@ -56,21 +55,15 @@ uses {$ifdef unix} - var - dlinfo: dl_info; - procedure GetModuleByAddr(addr: pointer; var baseaddr: pointer; var filename: string); begin - baseaddr:= nil; - filename:=ParamStr(0); - { - FillChar(dlinfo, sizeof(dlinfo), 0); - dladdr(addr, @dlinfo); - baseaddr:= dlinfo.dli_fbase; - filename:= String(dlinfo.dli_fname); - if ExtractFileName(filename) = ExtractFileName(ParamStr(0)) then - baseaddr:= nil; - } + if assigned(UnixGetModuleByAddrHook) then + UnixGetModuleByAddrHook(addr,baseaddr,filename) + else + begin + baseaddr:=nil; + filename:=ParamStr(0); + end; end; {$else unix} diff --git a/rtl/inc/lineinfo.pp b/rtl/inc/lineinfo.pp index ff76386c60..7c7ea2fd67 100644 --- a/rtl/inc/lineinfo.pp +++ b/rtl/inc/lineinfo.pp @@ -24,7 +24,6 @@ interface function GetLineInfo(addr:ptruint;var func,source:string;var line:longint) : boolean; - implementation uses @@ -85,11 +84,9 @@ begin GetModuleByAddr(addr,baseaddr,filename); {$ifdef DEBUG_LINEINFO} - writeln(stderr,filename); + writeln(stderr,filename,' Baseaddr: ',hexstr(ptruint(baseaddr),sizeof(baseaddr)*2)); {$endif DEBUG_LINEINFO} - e.processaddress:=e.processaddress-dword(baseaddr); - if not OpenExeFile(e,filename) then exit; if ReadDebugLink(e,dbgfn) then @@ -98,6 +95,7 @@ begin if not OpenExeFile(e,dbgfn) then exit; end; + e.processaddress:=e.processaddress+dword(baseaddr); StabsFunctionRelative := E.FunctionRelative; if FindExeSection(e,'.stab',stabofs,stablen) and FindExeSection(e,'.stabstr',stabstrofs,stabstrlen) then @@ -146,6 +144,10 @@ begin { processaddress is set in OpenStabs } addr := addr - e.processaddress; +{$ifdef DEBUG_LINEINFO} + writeln(stderr,'Addr: ',hexstr(addr,sizeof(addr)*2)); +{$endif DEBUG_LINEINFO} + fillchar(funcstab,sizeof(tstab),0); fillchar(filestab,sizeof(tstab),0); fillchar(dirstab,sizeof(tstab),0); diff --git a/rtl/inc/lnfodwrf.pp b/rtl/inc/lnfodwrf.pp index 98de111d30..437a5de7c4 100644 --- a/rtl/inc/lnfodwrf.pp +++ b/rtl/inc/lnfodwrf.pp @@ -141,10 +141,9 @@ begin GetModuleByAddr(addr,baseaddr,filename); {$ifdef DEBUG_LINEINFO} - writeln(stderr,filename); + writeln(stderr,filename,' Baseaddr: ',hexstr(ptruint(baseaddr),sizeof(baseaddr)*2)); {$endif DEBUG_LINEINFO} - e.processaddress:=e.processaddress-dword(baseaddr); if not OpenExeFile(e,filename) then exit; if ReadDebugLink(e,dbgfn) then @@ -153,6 +152,9 @@ begin if not OpenExeFile(e,dbgfn) then exit; end; + + e.processaddress:=e.processaddress+dword(baseaddr); + if FindExeSection(e,'.debug_line',dwarfoffset,dwarfsize) then Opendwarf:=true else @@ -694,6 +696,8 @@ begin exit; end; + addr := addr - e.processaddress; + current_offset := DwarfOffset; end_offset := DwarfOffset + DwarfSize; diff --git a/rtl/unix/dl.pp b/rtl/unix/dl.pp index 0f1fc16c24..b8dfb28500 100644 --- a/rtl/unix/dl.pp +++ b/rtl/unix/dl.pp @@ -1,11 +1,25 @@ +{ + This file is part of the Free Pascal run time library. + Copyright (c) 1999-2008 by the Free Pascal development team + + This file implements dyn. lib calls calls for Unix + + See the file COPYING.FPC, included in this distribution, + for details about the copyright. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + **********************************************************************} unit dl; interface const - {$ifdef BSD} // dlopen is in libc on FreeBSD. +{$ifdef BSD} // dlopen is in libc on FreeBSD. LibDL = 'c'; - {$else} +{$else} LibDL = 'dl'; {$endif} @@ -19,18 +33,17 @@ const RTLD_BINDING_MASK = $003; RTLD_GLOBAL = $100; RTLD_NEXT = pointer(-1); - {$ifdef LINUX} +{$ifdef LINUX} RTLD_DEFAULT = nil; - {$endif} - {$ifdef BSD} +{$endif} +{$ifdef BSD} RTLD_DEFAULT = pointer(-2); RTLD_MODEMASK = RTLD_BINDING_MASK; - {$endif} +{$endif} type Pdl_info = ^dl_info; - dl_info = - record + dl_info = record dli_fname : Pchar; dli_fbase : pointer; dli_sname : Pchar; @@ -48,4 +61,36 @@ function dladdr(Lib: pointer; info: Pdl_info): Longint; cdecl; external; implementation + function PosLastSlash(const s : string) : longint; + var + i : longint; + begin + PosLastSlash:=0; + for i:=1 to length(s) do + if s[i]='/' then + PosLastSlash:=i; + end; + + + function SimpleExtractFilename(const s : string) : string; + begin + SimpleExtractFilename:=Copy(s,PosLastSlash(s)+1,Length(s)-PosLastSlash(s)); + end; + + + procedure UnixGetModuleByAddr(addr: pointer; var baseaddr: pointer; var filename: openstring); + var + dlinfo: dl_info; + begin + baseaddr:=nil; + FillChar(dlinfo, sizeof(dlinfo), 0); + dladdr(addr, @dlinfo); + baseaddr:=dlinfo.dli_fbase; + filename:=String(dlinfo.dli_fname); + if SimpleExtractFilename(filename)=SimpleExtractFilename(ParamStr(0)) then + baseaddr:=nil; + end; + +begin + UnixGetModuleByAddrHook:=@UnixGetModuleByAddr; end. diff --git a/rtl/unix/sysunixh.inc b/rtl/unix/sysunixh.inc index 7ef558a590..4e4abd9193 100644 --- a/rtl/unix/sysunixh.inc +++ b/rtl/unix/sysunixh.inc @@ -62,3 +62,10 @@ var argc:longint;external name 'operatingsystem_parameter_argc'; {$endif} {$endif} +{$ifdef unix} +const + { hook for lineinfo, to get the module name from an address, + unit dl sets it if it is used + } + UnixGetModuleByAddrHook : procedure (addr: pointer; var baseaddr: pointer; var filename: string) = nil; +{$endif unix} |