From 99e1e8544731f2fbee5554ae6ca1a5599151e535 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Mon, 24 Mar 2008 22:19:21 +0000 Subject: [PATCH] * fixed execution of finalization section of smart linked shared libraries on linux (mantis #6822) * fixed execution of library finalization sections on darwin (previously only the finalization section of the library compilation unit itself was executed, now those of the units used by the library are also executed) git-svn-id: trunk@10554 - --- .gitattributes | 4 ++++ compiler/ncgutil.pas | 4 +--- compiler/pmodules.pas | 5 +++++ compiler/systems/t_linux.pas | 18 +++++++++++++++++- tests/webtbs/tw6822a.pp | 10 ++++++++++ tests/webtbs/tw6822b.pp | 32 ++++++++++++++++++++++++++++++++ tests/webtbs/tw6822c.pp | 17 +++++++++++++++++ tests/webtbs/uw6822a.pp | 14 ++++++++++++++ 8 files changed, 100 insertions(+), 4 deletions(-) create mode 100644 tests/webtbs/tw6822a.pp create mode 100644 tests/webtbs/tw6822b.pp create mode 100644 tests/webtbs/tw6822c.pp create mode 100644 tests/webtbs/uw6822a.pp diff --git a/.gitattributes b/.gitattributes index ceaca1be9f..58fac7622f 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8799,6 +8799,9 @@ tests/webtbs/tw6735.pp svneol=native#text/plain tests/webtbs/tw6737.pp -text tests/webtbs/tw6742.pp svneol=native#text/plain tests/webtbs/tw6767.pp svneol=native#text/plain +tests/webtbs/tw6822a.pp svneol=native#text/plain +tests/webtbs/tw6822b.pp svneol=native#text/plain +tests/webtbs/tw6822c.pp svneol=native#text/plain tests/webtbs/tw6865.pp svneol=native#text/plain tests/webtbs/tw6868.pp svneol=native#text/plain tests/webtbs/tw6960.pp svneol=native#text/plain @@ -9056,6 +9059,7 @@ tests/webtbs/uw4352e.pp svneol=native#text/plain tests/webtbs/uw4541.pp svneol=native#text/plain tests/webtbs/uw6203.pp svneol=native#text/plain tests/webtbs/uw6767.pp svneol=native#text/plain +tests/webtbs/uw6822a.pp svneol=native#text/plain tests/webtbs/uw7381.pp svneol=native#text/plain tests/webtbs/uw7838a.pp svneol=native#text/plain tests/webtbs/uw8180.pp svneol=native#text/plain diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index 6da0535dba..feb823c3ee 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -2062,9 +2062,7 @@ implementation if (current_module.islibrary) then if (current_procinfo.procdef.proctypeoption = potype_proginit) then - exportlib.setinitname(list,current_procinfo.procdef.mangledname) - else if ((current_module.flags and uf_finalize)<>0) then - exportlib.setfininame(list,current_procinfo.procdef.mangledname); + exportlib.setinitname(list,current_procinfo.procdef.mangledname); if (current_procinfo.procdef.proctypeoption=potype_proginit) then begin diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index 1037a36047..1cc881f6c5 100644 --- a/compiler/pmodules.pas +++ b/compiler/pmodules.pas @@ -2002,6 +2002,11 @@ implementation if force_init_final then finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable); + { the finalization routine of libraries is generic (and all libraries need to } + { be finalized, so they can finalize any units they use } + if (islibrary) then + exportlib.setfininame(current_asmdata.asmlists[al_procedures],'FPC_LIB_EXIT'); + { all labels must be defined before generating code } if Errorcount=0 then tstoredsymtable(current_module.localsymtable).checklabels; diff --git a/compiler/systems/t_linux.pas b/compiler/systems/t_linux.pas index 990803a5b7..1709f1c2ac 100644 --- a/compiler/systems/t_linux.pas +++ b/compiler/systems/t_linux.pas @@ -27,6 +27,7 @@ unit t_linux; interface uses + aasmdata, symsym,symdef,ppu, import,export,expunix,link; @@ -36,6 +37,7 @@ interface end; texportliblinux=class(texportlibunix) + procedure setfininame(list: TAsmList; const s: string); override; end; tlinkerlinux=class(texternallinker) @@ -65,7 +67,7 @@ implementation verbose,systems,globtype,globals, symconst,script, fmodule, - aasmbase,aasmtai,aasmdata,aasmcpu,cpubase, + aasmbase,aasmtai,aasmcpu,cpubase, cgbase,cgobj,cgutils,ogbase,ncgutil, comprsrc, rescmn, i_linux @@ -88,6 +90,20 @@ implementation end; +{***************************************************************************** + TEXPORTLIBLINUX +*****************************************************************************} + + procedure texportliblinux.setfininame(list: TAsmList; const s: string); + begin + { the problem with not having a .fini section is that a finalization + routine in regular code can get "smart" linked away -> reference it + just like the debug info } + list.concat(Tai_section.create(sec_fpc,'links',0)); + list.concat(Tai_const.Createname(s,0)); + inherited setfininame(list,s); + end; + {***************************************************************************** TLINKERLINUX *****************************************************************************} diff --git a/tests/webtbs/tw6822a.pp b/tests/webtbs/tw6822a.pp new file mode 100644 index 0000000000..9011e701d6 --- /dev/null +++ b/tests/webtbs/tw6822a.pp @@ -0,0 +1,10 @@ +{ %norun } +library tw6822a; +{$mode objfpc}{$H+} + +uses + uw6822a; + +begin + writeln('hello from library'); +end. diff --git a/tests/webtbs/tw6822b.pp b/tests/webtbs/tw6822b.pp new file mode 100644 index 0000000000..d038005749 --- /dev/null +++ b/tests/webtbs/tw6822b.pp @@ -0,0 +1,32 @@ +{ %needlibrary } + +program loader; +{$mode objfpc}{$H+} + +uses + dynlibs; +var + h: TLibHandle; +const +{$ifdef unix} +{$ifdef darwin} +libname = './libtw6822a.dylib'; +{$else darwin} +libname = './libtw6822a.so'; +{$endif darwin} +{$endif unix} + +{$ifdef mswindows} +libname = 'tw6822a.dll'; +{$endif mswindows} + +begin + writeln('hello from loader program'); + h:= loadlibrary(libname); + if h = nilhandle then + begin + write('could not load library'); + exit; + end; + freelibrary(h); +end. diff --git a/tests/webtbs/tw6822c.pp b/tests/webtbs/tw6822c.pp new file mode 100644 index 0000000000..29f47db8d2 --- /dev/null +++ b/tests/webtbs/tw6822c.pp @@ -0,0 +1,17 @@ +{ %target=win32,win64,wince,darwin,linux,freebsd,solaris,beos} +uses + SysUtils; + +var + t: text; +begin + { see uw6822a.pp } + assign(t,'uw6822a.txt'); +{$i-} + reset(t); +{$i+} + if ioresult<>0 then + halt(1); + close(t); + erase(t); +end. diff --git a/tests/webtbs/uw6822a.pp b/tests/webtbs/uw6822a.pp new file mode 100644 index 0000000000..6ba0c68bf5 --- /dev/null +++ b/tests/webtbs/uw6822a.pp @@ -0,0 +1,14 @@ +unit uw6822a; +{$mode objfpc}{$H+} + +interface + +implementation + +initialization + writeln('Unit 1'); + writeln('initialization'); +finalization + writeln('Unit 1'); // problem + writeln('finalization'); +end.