Procházet zdrojové kódy

* 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 -

Jonas Maebe před 17 roky
rodič
revize
99e1e85447

+ 4 - 0
.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

+ 1 - 3
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

+ 5 - 0
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;

+ 17 - 1
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
 *****************************************************************************}

+ 10 - 0
tests/webtbs/tw6822a.pp

@@ -0,0 +1,10 @@
+{ %norun }
+library tw6822a;
+{$mode objfpc}{$H+}
+
+uses
+  uw6822a;
+
+begin
+  writeln('hello from library');
+end.

+ 32 - 0
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.

+ 17 - 0
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.

+ 14 - 0
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.