瀏覽代碼

* 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 17 年之前
父節點
當前提交
99e1e85447
共有 8 個文件被更改,包括 100 次插入4 次删除
  1. 4 0
      .gitattributes
  2. 1 3
      compiler/ncgutil.pas
  3. 5 0
      compiler/pmodules.pas
  4. 17 1
      compiler/systems/t_linux.pas
  5. 10 0
      tests/webtbs/tw6822a.pp
  6. 32 0
      tests/webtbs/tw6822b.pp
  7. 17 0
      tests/webtbs/tw6822c.pp
  8. 14 0
      tests/webtbs/uw6822a.pp

+ 4 - 0
.gitattributes

@@ -8799,6 +8799,9 @@ tests/webtbs/tw6735.pp svneol=native#text/plain
 tests/webtbs/tw6737.pp -text
 tests/webtbs/tw6737.pp -text
 tests/webtbs/tw6742.pp svneol=native#text/plain
 tests/webtbs/tw6742.pp svneol=native#text/plain
 tests/webtbs/tw6767.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/tw6865.pp svneol=native#text/plain
 tests/webtbs/tw6868.pp svneol=native#text/plain
 tests/webtbs/tw6868.pp svneol=native#text/plain
 tests/webtbs/tw6960.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/uw4541.pp svneol=native#text/plain
 tests/webtbs/uw6203.pp svneol=native#text/plain
 tests/webtbs/uw6203.pp svneol=native#text/plain
 tests/webtbs/uw6767.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/uw7381.pp svneol=native#text/plain
 tests/webtbs/uw7838a.pp svneol=native#text/plain
 tests/webtbs/uw7838a.pp svneol=native#text/plain
 tests/webtbs/uw8180.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_module.islibrary) then
           if (current_procinfo.procdef.proctypeoption = potype_proginit) 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
         if (current_procinfo.procdef.proctypeoption=potype_proginit) then
           begin
           begin

+ 5 - 0
compiler/pmodules.pas

@@ -2002,6 +2002,11 @@ implementation
            if force_init_final then
            if force_init_final then
              finalize_procinfo:=gen_implicit_initfinal(uf_finalize,current_module.localsymtable);
              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 }
          { all labels must be defined before generating code }
          if Errorcount=0 then
          if Errorcount=0 then
            tstoredsymtable(current_module.localsymtable).checklabels;
            tstoredsymtable(current_module.localsymtable).checklabels;

+ 17 - 1
compiler/systems/t_linux.pas

@@ -27,6 +27,7 @@ unit t_linux;
 interface
 interface
 
 
   uses
   uses
+    aasmdata,
     symsym,symdef,ppu,
     symsym,symdef,ppu,
     import,export,expunix,link;
     import,export,expunix,link;
 
 
@@ -36,6 +37,7 @@ interface
     end;
     end;
 
 
     texportliblinux=class(texportlibunix)
     texportliblinux=class(texportlibunix)
+      procedure setfininame(list: TAsmList; const s: string); override;
     end;
     end;
 
 
     tlinkerlinux=class(texternallinker)
     tlinkerlinux=class(texternallinker)
@@ -65,7 +67,7 @@ implementation
     verbose,systems,globtype,globals,
     verbose,systems,globtype,globals,
     symconst,script,
     symconst,script,
     fmodule,
     fmodule,
-    aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,
+    aasmbase,aasmtai,aasmcpu,cpubase,
     cgbase,cgobj,cgutils,ogbase,ncgutil,
     cgbase,cgobj,cgutils,ogbase,ncgutil,
     comprsrc,
     comprsrc,
     rescmn, i_linux
     rescmn, i_linux
@@ -88,6 +90,20 @@ implementation
       end;
       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
                                   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.