From aad87820e687fd71d0c8f87b559b8f4b367df657 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Sun, 19 May 2019 19:20:47 +0000 Subject: [PATCH] * abstracted registration of library init/fini routines (to be able to add LLVM support) git-svn-id: trunk@42104 - --- compiler/ngenutil.pas | 37 ++++++++++++++++++++++++++---- compiler/pmodules.pas | 32 +++++++++++++++----------- compiler/symconst.pas | 6 +++-- compiler/utils/ppuutils/ppudump.pp | 3 ++- rtl/inc/compproc.inc | 2 +- rtl/inc/system.inc | 2 +- 6 files changed, 59 insertions(+), 23 deletions(-) diff --git a/compiler/ngenutil.pas b/compiler/ngenutil.pas index 5a93c5a3b4..a3821f8da9 100644 --- a/compiler/ngenutil.pas +++ b/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; diff --git a/compiler/pmodules.pas b/compiler/pmodules.pas index ef7a98b698..b7c24278b8 100644 --- a/compiler/pmodules.pas +++ b/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 diff --git a/compiler/symconst.pas b/compiler/symconst.pas index bf284cb58f..5904dbeac7 100644 --- a/compiler/symconst.pas +++ b/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 } diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index 498da3e1a9..adc8721e40 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/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'), diff --git a/rtl/inc/compproc.inc b/rtl/inc/compproc.inc index f6312c17e6..457ab16ea7 100644 --- a/rtl/inc/compproc.inc +++ b/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; diff --git a/rtl/inc/system.inc b/rtl/inc/system.inc index 7466e6ab87..3989789d30 100644 --- a/rtl/inc/system.inc +++ b/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;