Browse Source

* moved the generation of the "main" stub for libc-based platforms from
hlcgobj to pmodules/symcreat/ngenutil, so that it also works for llvm

git-svn-id: trunk@31658 -

Jonas Maebe 10 years ago
parent
commit
faf4a9cb38
5 changed files with 45 additions and 23 deletions
  1. 0 16
      compiler/hlcgobj.pas
  2. 23 3
      compiler/ngenutil.pas
  3. 18 2
      compiler/pmodules.pas
  4. 2 1
      compiler/symconst.pas
  5. 2 1
      compiler/utils/ppuutils/ppudump.pp

+ 0 - 16
compiler/hlcgobj.pas

@@ -4398,22 +4398,6 @@ implementation
           { 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_exports],current_procinfo.procdef.mangledname);
-
-      if (current_procinfo.procdef.proctypeoption=potype_proginit) then
-        begin
-         if (target_info.system in (systems_darwin+[system_powerpc_macos]+systems_aix)) and
-            not(current_module.islibrary) then
-           begin
-            new_section(list,sec_code,'',4);
-            list.concat(tai_symbol.createname_global(
-              target_info.cprefix+mainaliasname,AT_FUNCTION,0));
-            { keep argc, argv and envp properly on the stack }
-            if not(target_info.system in systems_aix) then
-              cg.a_jmp_name(list,target_info.cprefix+'FPC_SYSTEMMAIN')
-            else
-              cg.a_call_name(list,target_info.cprefix+'FPC_SYSTEMMAIN',false)
-           end;
-        end;
     end;
 
 

+ 23 - 3
compiler/ngenutil.pas

@@ -598,7 +598,10 @@ implementation
     var
       pd: tprocdef;
     begin
-      pd:=cprocdef.create(main_program_level,true);
+      if potype<>potype_mainstub then
+        pd:=cprocdef.create(main_program_level,true)
+      else
+        pd:=cprocdef.create(normal_function_level,true);
       pd.procsym:=ps;
       ps.ProcdefList.Add(pd);
       include(pd.procoptions,po_global);
@@ -610,7 +613,11 @@ implementation
       { may be required to calculate the mangled name }
       add_main_procdef_paras(pd);
       pd.setmangledname(name);
-      pd.aliasnames.insert(pd.mangledname);
+      { 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
+        pd.aliasnames.insert(pd.mangledname);
       result:=pd;
     end;
 
@@ -1068,8 +1075,21 @@ implementation
 
 
    class procedure tnodeutils.add_main_procdef_paras(pd: tdef);
+     var
+       pvs: tparavarsym;
      begin
-       { no parameters by default }
+       { stub for calling FPC_SYSTEMMAIN from the C main -> add argc/argv/argp }
+       if (tprocdef(pd).proctypeoption=potype_mainstub) and
+          (target_info.system in (systems_darwin+[system_powerpc_macos]+systems_aix)) then
+         begin
+           pvs:=cparavarsym.create('ARGC',1,vs_const,s32inttype,[]);
+           tprocdef(pd).parast.insert(pvs);
+           pvs:=cparavarsym.create('ARGV',2,vs_const,cpointerdef.getreusable(charpointertype),[]);
+           tprocdef(pd).parast.insert(pvs);
+           pvs:=cparavarsym.create('ARGP',3,vs_const,cpointerdef.getreusable(charpointertype),[]);
+           tprocdef(pd).parast.insert(pvs);
+           tprocdef(pd).calcparas;
+         end;
      end;
 
 

+ 18 - 2
compiler/pmodules.pas

@@ -575,8 +575,13 @@ implementation
         pd:=tprocdef(cnodeutils.create_main_procdef(target_info.cprefix+name,potype,ps));
         { We don't need is a local symtable. Change it into the static
           symtable }
-        pd.localst.free;
-        pd.localst:=st;
+        if potype<>potype_mainstub then
+          begin
+            pd.localst.free;
+            pd.localst:=st;
+          end
+        else
+          pd.proccalloption:=pocall_cdecl;
         handle_calling_convention(pd);
         { set procinfo and current_procinfo.procdef }
         result:=tcgprocinfo(cprocinfo.create(nil));
@@ -2137,6 +2142,17 @@ type
           end
          else if (target_info.system in ([system_i386_netware,system_i386_netwlibc,system_powerpc_macos]+systems_darwin+systems_aix)) then
            begin
+             { create a stub with the name of the desired main routine, with
+               the same signature as the C "main" function, and call through to
+               FPC_SYSTEMMAIN, which will initialise everything based on its
+               parameters. This function cannot be in the system unit, because
+               its name can be configured on the command line (for use with e.g.
+               SDL, where the main function should be called SDL_main) }
+             main_procinfo:=create_main_proc(mainaliasname,potype_mainstub,current_module.localsymtable);
+             call_through_new_name(main_procinfo.procdef,target_info.cprefix+'FPC_SYSTEMMAIN');
+             main_procinfo.free;
+             { now create the PASCALMAIN routine (which will be called from
+               FPC_SYSTEMMAIN) }
              main_procinfo:=create_main_proc('PASCALMAIN',potype_proginit,current_module.localsymtable);
            end
          else

+ 2 - 1
compiler/symconst.pas

@@ -266,7 +266,8 @@ type
     potype_class_destructor,  { class destructor  }
     potype_propgetter,        { Dispinterface property accessors }
     potype_propsetter,
-    potype_exceptfilter       { SEH exception filter or termination handler }
+    potype_exceptfilter,      { SEH exception filter or termination handler }
+    potype_mainstub           { "main" function that calls through to FPC_SYSTEMMAIN }
   );
   tproctypeoptions=set of tproctypeoption;
 

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

@@ -1783,7 +1783,8 @@ const
      { Dispinterface property accessors }
      (mask:potype_propgetter;        str:'Property Getter'),
      (mask:potype_propsetter;        str:'Property Setter'),
-     (mask:potype_exceptfilter;      str:'SEH filter')
+     (mask:potype_exceptfilter;      str:'SEH filter'),
+     (mask:potype_mainstub;          str:'main stub')
   );
   procopt : array[1..ord(high(tprocoption))] of tprocopt=(
      (mask:po_classmethod;     str:'ClassMethod'),