Forráskód Böngészése

* abstracted registration of library init/fini routines (to be able to add
LLVM support)

git-svn-id: trunk@42104 -

Jonas Maebe 6 éve
szülő
commit
aad87820e6

+ 33 - 4
compiler/ngenutil.pas

@@ -29,7 +29,7 @@ interface
   uses
     cclasses,globtype,
     fmodule,
-    aasmdata,
+    aasmbase,aasmdata,
     node,nbas,symtype,symsym,symconst,symdef;
 
 
@@ -138,6 +138,14 @@ interface
         info) }
       class procedure InsertObjectInfo; virtual;
 
+      { register that asm symbol sym with type def has to be considered as "used" even if not
+        references to it can be found. If compileronly, this is only for the compiler, otherwise
+        also for the linker }
+      class procedure RegisterUsedAsmSym(sym: TAsmSymbol; def: tdef; compileronly: boolean); virtual;
+
+      class procedure RegisterModuleInitFunction(pd: tprocdef); virtual;
+      class procedure RegisterModuleFiniFunction(pd: tprocdef); virtual;
+
      strict protected
       class procedure add_main_procdef_paras(pd: tdef); virtual;
     end;
@@ -152,11 +160,12 @@ implementation
     uses
       verbose,version,globals,cutils,constexp,compinnr,
       systems,procinfo,pparautl,
-      aasmbase,aasmtai,aasmcnst,
+      aasmtai,aasmcnst,
       symbase,symtable,defutil,
       nadd,ncal,ncnv,ncon,nflw,ninl,nld,nmem,nutils,
       ppu,
-      pass_1;
+      pass_1,
+      export;
 
   class function tnodeutils.call_fail_node:tnode;
     var
@@ -942,7 +951,7 @@ implementation
       { the mainstub is generated via a synthetic proc -> parsed via
         psub.read_proc_body() -> that one will insert the mangled name in the
         alias names already }
-      if potype<>potype_mainstub then
+      if not(potype in [potype_mainstub,potype_libmainstub]) then
         pd.aliasnames.insert(pd.mangledname);
       result:=pd;
     end;
@@ -1551,6 +1560,26 @@ implementation
     end;
 
 
+  class procedure tnodeutils.RegisterUsedAsmSym(sym: TAsmSymbol; def: tdef; compileronly: boolean);
+    begin
+      { don't do anything by default }
+    end;
+
+
+  class procedure tnodeutils.RegisterModuleInitFunction(pd: tprocdef);
+    begin
+      { setinitname may generate a new section -> don't add to the
+        current list, because we assume this remains a text section }
+      exportlib.setinitname(current_asmdata.AsmLists[al_pure_assembler],pd.mangledname);
+    end;
+
+
+  class procedure tnodeutils.RegisterModuleFiniFunction(pd: tprocdef);
+    begin
+      exportlib.setfininame(current_asmdata.AsmLists[al_pure_assembler],pd.mangledname);
+    end;
+
+
    class procedure tnodeutils.add_main_procdef_paras(pd: tdef);
      var
        pvs: tparavarsym;

+ 18 - 14
compiler/pmodules.pas

@@ -665,7 +665,7 @@ implementation
         st.insert(ps);
         pd:=tprocdef(cnodeutils.create_main_procdef(target_info.cprefix+name,potype,ps));
         { We don't need a local symtable, change it into the static symtable }
-        if not (potype in [potype_mainstub,potype_pkgstub]) then
+        if not (potype in [potype_mainstub,potype_pkgstub,potype_libmainstub]) then
           begin
             pd.localst.free;
             pd.localst:=st;
@@ -1898,13 +1898,13 @@ type
       var
          main_file : tinputfile;
          hp,hp2    : tmodule;
+         initpd    : tprocdef;
          finalize_procinfo,
          init_procinfo,
          main_procinfo : tcgprocinfo;
          force_init_final : boolean;
          resources_used : boolean;
          program_uses_checkpointer : boolean;
-         initname,
          program_name : ansistring;
          consume_semicolon_after_uses : boolean;
          ps : tprogramparasym;
@@ -2124,6 +2124,17 @@ type
            from the bootstrap code.}
          if islibrary then
           begin
+            initpd:=nil;
+            { ToDo: other systems that use indirect entry info, but check back with Windows! }
+            { we need to call FPC_LIBMAIN in sysinit which in turn will call PascalMain -> create dummy stub }
+            if target_info.system in systems_darwin then
+              begin
+                main_procinfo:=create_main_proc(make_mangledname('sysinitcallthrough',current_module.localsymtable,'stub'),potype_libmainstub,current_module.localsymtable);
+                call_through_new_name(main_procinfo.procdef,target_info.cprefix+'FPC_LIBMAIN');
+                initpd:=main_procinfo.procdef;
+                main_procinfo.free;
+              end;
+
             main_procinfo:=create_main_proc(make_mangledname('',current_module.localsymtable,mainaliasname),potype_proginit,current_module.localsymtable);
             { Win32 startup code needs a single name }
             if not(target_info.system in (systems_darwin+systems_aix)) then
@@ -2131,17 +2142,10 @@ type
             else
               main_procinfo.procdef.aliasnames.concat(target_info.Cprefix+'PASCALMAIN');
 
-            { ToDo: systems that use indirect entry info, but check back with Windows! }
-            if target_info.system in systems_darwin then
-              { we need to call FPC_LIBMAIN in sysinit which in turn will call PascalMain }
-              initname:=target_info.cprefix+'FPC_LIBMAIN'
-            else
-              initname:=main_procinfo.procdef.mangledname;
-            { setinitname may generate a new section -> don't add to the
-              current list, because we assume this remains a text section
-              -- add to pure assembler section, so in case of special directives
-                they are directly added to the assembler output by llvm }
-            exportlib.setinitname(current_asmdata.AsmLists[al_pure_assembler],initname);
+            if not(target_info.system in systems_darwin) then
+              initpd:=main_procinfo.procdef;
+
+            cnodeutils.RegisterModuleInitFunction(initpd);
           end
          else if (target_info.system in ([system_i386_netware,system_i386_netwlibc,system_powerpc_macos]+systems_darwin+systems_aix)) then
            begin
@@ -2220,7 +2224,7 @@ type
           { Place in "pure assembler" list so that the llvm assembler writer
             directly emits the generated directives }
           if (islibrary) then
-            exportlib.setfininame(current_asmdata.asmlists[al_pure_assembler],'FPC_LIB_EXIT');
+            cnodeutils.RegisterModuleFiniFunction(search_system_proc('fpc_lib_exit'));
 
          { all labels must be defined before generating code }
          if Errorcount=0 then

+ 4 - 2
compiler/symconst.pas

@@ -307,7 +307,8 @@ type
     potype_propsetter,
     potype_exceptfilter,      { SEH exception filter or termination handler }
     potype_mainstub,          { "main" function that calls through to FPC_SYSTEMMAIN }
-    potype_pkgstub            { stub for a package file, that tells OS that all is OK }
+    potype_pkgstub,           { stub for a package file, that tells OS that all is OK }
+    potype_libmainstub        { "main" function for a library that calls through to FPC_LIBMAIN }
   );
   tproctypeoptions=set of tproctypeoption;
 
@@ -967,7 +968,8 @@ inherited_objectoptions : tobjectoptions = [oo_has_virtual,oo_has_private,oo_has
       'property setters',   {potype_propsetter}
       'exception filters',  {potype_exceptfilter}
       '"main" stub',        {potype_mainstub}
-      'package stub'        {potype_pkgstub}
+      'package stub',       {potype_pkgstub}
+      'lib "main" stub'     {potype_libmainstub}
     );
 
     { TProcOption string identifiers for error messages }

+ 2 - 1
compiler/utils/ppuutils/ppudump.pp

@@ -1948,7 +1948,8 @@ const
      (mask:potype_propsetter;        str:'Property Setter'),
      (mask:potype_exceptfilter;      str:'SEH filter'),
      (mask:potype_mainstub;          str:'main stub'),
-     (mask:potype_pkgstub;           str:'package stub')
+     (mask:potype_pkgstub;           str:'package stub'),
+     (mask:potype_libmainstub;       str:'library main stub')
   );
   procopt : array[1..ord(high(tprocoption))] of tprocopt=(
      (mask:po_classmethod;     str:'ClassMethod'),

+ 1 - 1
rtl/inc/compproc.inc

@@ -791,9 +791,9 @@ procedure fpc_do_exit;compilerproc;
 
 {
 Procedure fpc_do_exit; compilerproc;
-Procedure fpc_lib_exit; compilerproc;
 Procedure fpc_HandleErrorAddrFrame (Errno : longint;addr,frame : pointer); compilerproc;
 }
+Procedure fpc_lib_exit; compilerproc;
 Procedure fpc_HandleError (Errno : longint); compilerproc;
 
 procedure fpc_AbstractErrorIntern;compilerproc;

+ 1 - 1
rtl/inc/system.inc

@@ -1135,7 +1135,7 @@ end;
 procedure internal_do_exit; external name 'FPC_DO_EXIT';
 
 
-Procedure lib_exit;[Public,Alias:'FPC_LIB_EXIT'];
+Procedure fpc_lib_exit;[Public,Alias:'FPC_LIB_EXIT'];
 begin
   InternalExit;
 end;