| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982 | {    Copyright (c) 1998-2002 by Peter Vreman (original Linux)              (c) 2000      by Marco van de Voort (FreeBSD mods)    This unit implements support import,export,link routines    for the (i386)FreeBSD target    This program is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.    This program is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.    You should have received a copy of the GNU General Public License    along with this program; if not, write to the Free Software    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. ****************************************************************************}unit t_bsd;{$i fpcdefs.inc}interfaceimplementation  uses    sysutils,    cutils,cfileutl,cclasses,    verbose,systems,globtype,globals,    symconst,script,    fmodule,aasmbase,aasmtai,aasmdata,aasmcpu,cpubase,symsym,symdef,    import,export,link,comprsrc,rescmn,i_bsd,expunix,    cgutils,cgbase,cgobj,cpuinfo,ogbase;  type    timportlibdarwin=class(timportlib)      procedure generatelib;override;    end;    timportlibbsd=class(timportlib)      procedure generatelib;override;    end;    texportlibbsd=class(texportlibunix)    end;    texportlibdarwin=class(texportlibbsd)      procedure setinitname(list: TAsmList; const s: string); override;      procedure setfininame(list: TAsmList; const s: string); override;    end;    tlinkerbsd=class(texternallinker)    private      LdSupportsNoResponseFile : boolean;      LibrarySuffix : Char;      Function  WriteResponseFile(isdll:boolean) : Boolean;      function GetDarwinCrt1ObjName(isdll: boolean): TCmdStr;      Function GetDarwinPrtobjName(isdll: boolean): TCmdStr;    public      constructor Create;override;      procedure SetDefaultInfo;override;      function  MakeExecutable:boolean;override;      function  MakeSharedLibrary:boolean;override;      procedure LoadPredefinedLibraryOrder; override;    end;{*****************************************************************************                             TIMPORTLIBDARWIN*****************************************************************************}    procedure timportlibdarwin.generatelib;      begin      end;{*****************************************************************************                             TEXPORTLIBDARWIN*****************************************************************************}    procedure texportlibdarwin.setinitname(list: TAsmList; const s: string);      begin        new_section(list,sec_init_func,'',sizeof(pint));        list.concat(Tai_const.Createname(s,0));      end;    procedure texportlibdarwin.setfininame(list: TAsmList; const s: string);      begin        new_section(list,sec_term_func,'',sizeof(pint));        list.concat(Tai_const.Createname(s,0));      end;{*****************************************************************************                               TIMPORTLIBBSD*****************************************************************************}    procedure timportlibbsd.generatelib;      var        i : longint;        ImportLibrary : TImportLibrary;      begin        for i:=0 to current_module.ImportLibraryList.Count-1 do          begin            ImportLibrary:=TImportLibrary(current_module.ImportLibraryList[i]);            current_module.linkothersharedlibs.add(ImportLibrary.Name,link_always);          end;      end;{*****************************************************************************                                  TLINKERBSD*****************************************************************************}Constructor TLinkerBSD.Create;begin  Inherited Create;  if not Dontlinkstdlibpath Then   if not(target_info.system in systems_darwin) then     LibrarySearchPath.AddPath(sysrootpath,'/lib;/usr/lib;/usr/X11R6/lib',true)   else     { Mac OS X doesn't have a /lib }     LibrarySearchPath.AddPath(sysrootpath,'/usr/lib',true)end;procedure TLinkerBSD.SetDefaultInfo;{  This will also detect which libc version will be used}begin  LibrarySuffix:=' ';  LdSupportsNoResponseFile := (target_info.system in ([system_m68k_netbsd]+systems_darwin));  with Info do   begin     if LdSupportsNoResponseFile then       begin         if not(target_info.system in systems_darwin) then           begin             ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE $CATRES';             DllCmd[1]:='ld $TARGET $EMUL $OPT -shared -L. -o $EXE $CATRES'           end         else           begin{$ifndef cpu64bitaddr}             { Set the size of the page at address zero to 64kb, so nothing               is loaded below that address. This avoids problems with the               strange Windows-compatible resource handling that assumes               that addresses below 64kb do not exist.               On 64bit systems, page zero is 4GB by default, so no problems               there.             }             { In case of valgrind, don't do that, because it cannot deal with               a custom pagezero size -- in general, this should not cause any               problems because the resources are added at the end and most               programs with problems that require Valgrind will have more               than 60KB of data (first 4KB of address space is always invalid)             }               ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';             if not(cs_gdb_valgrind in current_settings.globalswitches) then               ExeCmd[1]:=ExeCmd[1]+' -pagezero_size 0x10000';{$else ndef cpu64bitaddr}             ExeCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -multiply_defined suppress -L. -o $EXE $CATRES';{$endif ndef cpu64bitaddr}             if (apptype<>app_bundle) then               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -dylib -multiply_defined suppress -L. -o $EXE $CATRES'             else               DllCmd[1]:='ld $PRTOBJ $TARGET $EMUL $OPT $GCSECTIONS -dynamic -bundle -multiply_defined suppress -L. -o $EXE $CATRES'           end       end     else       begin         ExeCmd[1]:='ld $TARGET $EMUL $OPT $DYNLINK $STATIC  $GCSECTIONS $STRIP -L. -o $EXE $RES';         DllCmd[1]:='ld $TARGET $EMUL $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';       end;     if not(target_info.system in systems_darwin) then       DllCmd[2]:='strip --strip-unneeded $EXE'     else       DllCmd[2]:='strip -x $EXE';     { OpenBSD seems to use a wrong dynamic linker by default }     if target_info.system in systems_openbsd then      DynamicLinker:='/usr/libexec/ld.so'     else if target_info.system in systems_netbsd then      DynamicLinker:='/usr/libexec/ld.elf_so'     else       DynamicLinker:='';   end;end;procedure TLinkerBSD.LoadPredefinedLibraryOrder;// put your linkorder/linkalias overrides here.// Note: assumes only called when reordering/aliasing is used.Begin  if not(target_info.system in systems_darwin) then    begin      if (target_info.system =system_i386_freebsd) and         not (cs_link_no_default_lib_order in  current_settings.globalswitches) Then        Begin          LinkLibraryOrder.add('gcc','',15);          LinkLibraryOrder.add('c','',50);		     // c and c_p mutual. excl?          LinkLibraryOrder.add('c_p','',55);          LinkLibraryOrder.add('pthread','',75);	     // pthread and c_r should be mutually exclusive          LinkLibraryOrder.add('c_r','',76);          LinkLibraryOrder.add('kvm','',80);		     // must be before ncurses          if (cs_link_pthread in current_settings.globalswitches) Then     // convert libpthread to libc_r.            LinkLibraryAliases.add('pthread','c_r');        end;    endelse    begin          LinkLibraryOrder.add('gcc','',15);          LinkLibraryOrder.add('c','',50);   end;End;function TLinkerBSD.GetDarwinCrt1ObjName(isdll: boolean): TCmdStr;begin  if not isdll then    begin      if not(cs_profile in current_settings.moduleswitches) then        begin          { 10.8 and later: no crt1.* }          if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then            exit('');          { x86: crt1.10.6.o -> crt1.10.5.o -> crt1.o }          { others: crt1.10.5 -> crt1.o }{$if defined(i386) or defined(x86_64)}          if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then            exit('crt1.10.6.o');{$endif}          if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then            exit('crt1.10.5.o');{$if defined(arm)}          { iOS:              iOS 6 and later: nothing              iOS 3.1 - 5.x: crt1.3.1.o              pre-iOS 3.1: crt1.o          }          if (CompareVersionStrings(iPhoneOSVersionMin,'6.0')>=0) then            exit('');          if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then            exit('crt1.3.1.o');{$endif}          { nothing special -> default }          result:='crt1.o';        end      else        begin          result:='gcrt1.o';          { 10.8 and later: tell the linker to use 'start' instead of "_main"            as entry point }          if CompareVersionStrings(MacOSXVersionMin,'10.8')>=0 then            Info.ExeCmd[1]:=Info.ExeCmd[1]+' -no_new_main';        end;    end  else    begin      if (apptype=app_bundle) then        begin          { < 10.6: bundle1.o            >= 10.6: nothing }          if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then            exit('');          { iOS: < 3.1: bundle1.o                 >= 3.1: nothing }{$if defined(arm)}          if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then            exit('');{$endif}          result:='bundle1.o';        end      else        begin          { >= 10.6: nothing            = 10.5: dylib1.10.5.o            < 10.5: dylib1.o          }          if CompareVersionStrings(MacOSXVersionMin,'10.6')>=0 then            exit('');          if CompareVersionStrings(MacOSXVersionMin,'10.5')>=0 then            exit('dylib1.10.5.o');          { iOS: < 3.1: dylib1.o                 >= 3.1: nothing }{$if defined(arm)}          if (CompareVersionStrings(iPhoneOSVersionMin,'3.1')>=0) then            exit('');{$endif}          result:='dylib1.o';        end;    end;end;Function TLinkerBSD.GetDarwinPrtobjName(isdll: boolean): TCmdStr;var  startupfile: TCmdStr;begin  startupfile:=GetDarwinCrt1ObjName(isdll);  if startupfile<>'' then    begin     if not librarysearchpath.FindFile(startupfile,false,result) then       result:='/usr/lib/'+startupfile    end  else    result:='';  result:=maybequoted(result);end;Function TLinkerBSD.WriteResponseFile(isdll:boolean) : Boolean;Var  linkres      : TLinkRes;  i            : longint;  cprtobj,  gprtobj,  prtobj       : string[80];  HPath        : TCmdStrListItem;  s,s1,s2      : TCmdStr;  linkdynamic,  linklibc     : boolean;  Fl1,Fl2      : Boolean;  IsDarwin     : Boolean;  ReOrder      : Boolean;begin  WriteResponseFile:=False;  ReOrder:=False;  linkdynamic:=False;  IsDarwin:=target_info.system in systems_darwin;{ set special options for some targets }  if not IsDarwin Then    begin      if isdll and         (target_info.system in systems_bsd) then        begin          prtobj:='dllprt0';          cprtobj:='dllprt0';          gprtobj:='dllprt0';        end      else        begin          prtobj:='prt0';          cprtobj:='cprt0';          gprtobj:='gprt0';        end;      linkdynamic:=not(SharedLibFiles.empty);      linklibc:=(SharedLibFiles.Find('c')<>nil);      // this one is a bit complex.      // Only reorder for now if -XL or -XO params are given      // or when -Xf.      reorder:= linklibc and                (                  ReorderEntries                   or                  (cs_link_pthread in current_settings.globalswitches));      if cs_profile in current_settings.moduleswitches then       begin         prtobj:=gprtobj;         AddSharedLibrary('c');         LibrarySuffix:='p';         linklibc:=true;       end      else       begin         if linklibc then          prtobj:=cprtobj;       end;      // after this point addition of shared libs not allowed.    end  else    begin      { for darwin: always link dynamically against libc }      linklibc := true;{$ifdef MACOSX104ORHIGHER}      { not sure what this is for, but gcc always links against it }      if not(cs_profile in current_settings.moduleswitches) then        AddSharedLibrary('SystemStubs')      else        AddSharedLibrary('SystemStubs_profile');{$endif MACOSX104ORHIGHER}      reorder:=reorderentries;      prtobj:='';    end;  if reorder Then     ExpandAndApplyOrder(SharedLibFiles);  { Open link.res file }  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,not LdSupportsNoResponseFile);  if (target_info.system in systems_darwin) and     (sysrootpath<>'') then    begin      LinkRes.Add('-syslibroot');      LinkRes.Add(sysrootpath);    end;  if (target_info.system in systems_darwin) then    begin      LinkRes.Add('-arch');      case target_info.system of        system_powerpc_darwin:          LinkRes.Add('ppc');        system_i386_darwin,        system_i386_iphonesim:          LinkRes.Add('i386');        system_powerpc64_darwin:          LinkRes.Add('ppc64');        system_x86_64_darwin:          LinkRes.Add('x86_64');        system_arm_darwin:          { current versions of the linker require the sub-architecture type            to be specified }          LinkRes.Add(lower(cputypestr[current_settings.cputype]));      end;      if MacOSXVersionMin<>'' then        begin          LinkRes.Add('-macosx_version_min');          LinkRes.Add(MacOSXVersionMin);        end      else if iPhoneOSVersionMin<>'' then        begin          LinkRes.Add('-iphoneos_version_min');          LinkRes.Add(iPhoneOSVersionMin);        end;    end;  { Write path to search libraries }  HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);  while assigned(HPath) do   begin     if LdSupportsNoResponseFile then       LinkRes.Add('-L'+HPath.Str)     else       LinkRes.Add('SEARCH_DIR("'+HPath.Str+'")');     HPath:=TCmdStrListItem(HPath.Next);   end;  HPath:=TCmdStrListItem(LibrarySearchPath.First);  while assigned(HPath) do   begin     if LdSupportsNoResponseFile then       LinkRes.Add('-L'+HPath.Str)     else       LinkRes.Add('SEARCH_DIR("'+HPath.Str+'")');     HPath:=TCmdStrListItem(HPath.Next);   end;  if (target_info.system in systems_darwin) then    begin      HPath:=TCmdStrListItem(current_module.localframeworksearchpath.First);      while assigned(HPath) do       begin         LinkRes.Add('-F'+HPath.Str);         HPath:=TCmdStrListItem(HPath.Next);       end;      HPath:=TCmdStrListItem(FrameworkSearchPath.First);      while assigned(HPath) do       begin         LinkRes.Add('-F'+HPath.Str);         HPath:=TCmdStrListItem(HPath.Next);       end;    end;      { force local symbol resolution (i.e., inside the shared }      { library itself) for all non-exorted symbols, otherwise }      { several RTL symbols of FPC-compiled shared libraries   }      { will be bound to those of a single shared library or   }      { to the main program                                    }      if (isdll) and (target_info.system in systems_bsd) then        begin          LinkRes.add('VERSION');          LinkRes.add('{');          LinkRes.add('  {');          if not texportlibunix(exportlib).exportedsymnames.empty then            begin              LinkRes.add('    global:');              repeat                LinkRes.add('      '+texportlibunix(exportlib).exportedsymnames.getfirst+';');              until texportlibunix(exportlib).exportedsymnames.empty;            end;          LinkRes.add('    local:');          LinkRes.add('      *;');          LinkRes.add('  };');          LinkRes.add('}');        end;  if not LdSupportsNoResponseFile then    LinkRes.Add('INPUT(');  { add objectfiles, start with prt0 always }  if prtobj<>'' then   LinkRes.AddFileName(FindObjectFile(prtobj,'',false));  { try to add crti and crtbegin if linking to C }  if linklibc and     not IsDarwin Then   begin     if librarysearchpath.FindFile('crti.o',false,s) then      LinkRes.AddFileName(s);     if cs_create_pic in current_settings.moduleswitches then       begin         if librarysearchpath.FindFile('crtbeginS.o',false,s) then           LinkRes.AddFileName(s);       end       else         if (cs_link_staticflag in current_settings.globalswitches) and           librarysearchpath.FindFile('crtbeginT.o',false,s) then             LinkRes.AddFileName(s)         else if librarysearchpath.FindFile('crtbegin.o',false,s) then             LinkRes.AddFileName(s);   end;  { main objectfiles }  while not ObjectFiles.Empty do   begin     s:=ObjectFiles.GetFirst;     if s<>'' then      if LdSupportsNoResponseFile then        LinkRes.AddFileName(s)      else        LinkRes.AddFileName(maybequoted(s));   end;  if not LdSupportsNoResponseFile then   LinkRes.Add(')');  { Write staticlibraries }  if not StaticLibFiles.Empty then   begin     if not LdSupportsNoResponseFile then       LinkRes.Add('GROUP(');     While not StaticLibFiles.Empty do      begin        S:=StaticLibFiles.GetFirst;        if LdSupportsNoResponseFile then          LinkRes.AddFileName(s)        else          LinkRes.AddFileName(maybequoted(s))      end;     if not LdSupportsNoResponseFile then       LinkRes.Add(')');   end;  { Write sharedlibraries like -l<lib>, also add the needed dynamic linker    here to be sure that it gets linked this is needed for glibc2 systems (PFV) }  if not SharedLibFiles.Empty then   begin     if not LdSupportsNoResponseFile then       LinkRes.Add('INPUT(');     While not SharedLibFiles.Empty do      begin        S:=SharedLibFiles.GetFirst;        if (s<>'c') or reorder then         begin           i:=Pos(target_info.sharedlibext,S);           if i>0 then            Delete(S,i,255);           LinkRes.Add('-l'+s);         end        else         begin           linklibc:=true;           linkdynamic:=false; { libc will include the ld-* for us }         end;      end;     { be sure that libc is the last lib }     if linklibc and not reorder then       Begin         If LibrarySuffix=' ' Then          LinkRes.Add('-lc')         else          LinkRes.Add('-lc_'+LibrarySuffix);         If LibrarySuffix='r' Then             LinkRes.Add('-lc');       end;     { when we have -static for the linker the we also need libgcc }     if (cs_link_staticflag in current_settings.globalswitches) then      LinkRes.Add('-lgcc');     if linkdynamic and (Info.DynamicLinker<>'') then      LinkRes.AddFileName(Info.DynamicLinker);     if not LdSupportsNoResponseFile then       LinkRes.Add(')');   end;  { frameworks for Darwin }  if IsDarwin then    while not FrameworkFiles.empty do      begin        LinkRes.Add('-framework');        LinkRes.Add(FrameworkFiles.GetFirst);      end;  { objects which must be at the end }  if linklibc and     not IsDarwin Then   begin     if cs_create_pic in current_settings.moduleswitches then       Fl1:=librarysearchpath.FindFile('crtendS.o',false,s1)     else       Fl1:=librarysearchpath.FindFile('crtend.o',false,s1);     Fl2:=librarysearchpath.FindFile('crtn.o',false,s2);     if Fl1 or Fl2 then      begin        LinkRes.Add('INPUT(');         If Fl1 Then        LinkRes.AddFileName(s1);        If Fl2 Then         LinkRes.AddFileName(s2);        LinkRes.Add(')');      end;   end;{ Write and Close response }  linkres.writetodisk;  linkres.Free;  WriteResponseFile:=True;end;function TLinkerBSD.MakeExecutable:boolean;var  binstr,  cmdstr,  targetstr,  emulstr,  extdbgbinstr,  extdbgcmdstr: TCmdStr;  linkscript: TAsmScript;  DynLinkStr : string[60];  GCSectionsStr,  StaticStr,  StripStr   : string[63];  success,  useshell : boolean;begin  if not(cs_link_nolink in current_settings.globalswitches) then   Message1(exec_i_linking,current_module.exefilename);{ Create some replacements }  StaticStr:='';  StripStr:='';  DynLinkStr:='';  GCSectionsStr:='';  linkscript:=nil;  { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd    to avoid creation of a i386:x86_64 arch binary }  if target_info.system=system_i386_freebsd then    begin      targetstr:='-b elf32-i386-freebsd';      emulstr:='-m elf_i386_fbsd';    end  else    begin      targetstr:='';      emulstr:='';    end;  if (cs_link_staticflag in current_settings.globalswitches) then    begin      if (target_info.system=system_m68k_netbsd) and         ((cs_link_on_target in current_settings.globalswitches) or          (target_info.system=source_info.system)) then        StaticStr:='-Bstatic'      else        StaticStr:='-static';    end;  if (cs_link_strip in current_settings.globalswitches) then    if (target_info.system in systems_darwin) then      StripStr:='-x'    else      StripStr:='-s';  if (cs_link_smart in current_settings.globalswitches) and     (tf_smartlink_sections in target_info.flags) then    if not(target_info.system in systems_darwin) then      GCSectionsStr:='--gc-sections'    else      GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';   if(not(target_info.system in systems_darwin) and      (cs_profile in current_settings.moduleswitches)) or     ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then   DynLinkStr:='-dynamic-linker='+Info.DynamicLinker;  if CShared Then   begin   if not(target_info.system in systems_darwin) then     DynLinKStr:=DynLinkStr+' --shared'    else     DynLinKStr:=DynLinkStr+' -dynamic'; // one dash!   end;   { Use -nopie on OpenBSD }  if (target_info.system in systems_openbsd) and     (target_info.system <> system_x86_64_openbsd) then    Info.ExtraOptions:=Info.ExtraOptions+' -nopie';    { Write used files and libraries }  WriteResponseFile(false);{ Call linker }  SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);  Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));  Replace(cmdstr,'$OPT',Info.ExtraOptions);  Replace(cmdstr,'$TARGET',targetstr);  Replace(cmdstr,'$EMUL',EmulStr);  Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));  Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));  Replace(cmdstr,'$STATIC',StaticStr);  Replace(cmdstr,'$STRIP',StripStr);  Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);  Replace(cmdstr,'$DYNLINK',DynLinkStr);  if (target_info.system in systems_darwin) then    Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(false));  BinStr:=FindUtil(utilsprefix+BinStr);  { create dsym file? }  extdbgbinstr:='';  extdbgcmdstr:='';  if (target_info.system in systems_darwin) and     (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and     (cs_link_separate_dbg_file in current_settings.globalswitches) then    begin      extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');      extdbgcmdstr:=maybequoted(current_module.exefilename);    end;  if (LdSupportsNoResponseFile) and     not(cs_link_nolink in current_settings.globalswitches) then    begin      { we have to use a script to use the IFS hack }      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');      linkscript.AddLinkCommand(BinStr,CmdStr,'');      if (extdbgcmdstr<>'') then        linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');      linkscript.WriteToDisk;      BinStr:=linkscript.fn;      if not path_absolute(BinStr) then        BinStr:='./'+BinStr;      CmdStr:='';    end;  useshell:=not (tf_no_backquote_support in source_info.flags);  success:=DoExec(BinStr,CmdStr,true,LdSupportsNoResponseFile or useshell);  if (success and      (extdbgbinstr<>'') and      (cs_link_nolink in current_settings.globalswitches)) then    success:=DoExec(extdbgbinstr,extdbgcmdstr,false,LdSupportsNoResponseFile);{ Remove ReponseFile }  if (success) and not(cs_link_nolink in current_settings.globalswitches) then   begin     DeleteFile(outputexedir+Info.ResName);     if LdSupportsNoResponseFile Then       begin         DeleteFile(linkscript.fn);         linkscript.free       end;   end;  MakeExecutable:=success;   { otherwise a recursive call to link method }end;Function TLinkerBSD.MakeSharedLibrary:boolean;var  InitStr,  FiniStr,  SoNameStr : string[80];  linkscript: TAsmScript;  binstr,  cmdstr,  targetstr,  emulstr,  extdbgbinstr,  extdbgcmdstr  : TCmdStr;  GCSectionsStr : string[63];  exportedsyms: text;  success : boolean;begin  MakeSharedLibrary:=false;  GCSectionsStr:='';  linkscript:=nil;  if not(cs_link_nolink in current_settings.globalswitches) then   Message1(exec_i_linking,current_module.sharedlibfilename);{ Write used files and libraries }  WriteResponseFile(true);  if (cs_link_smart in current_settings.globalswitches) and     (tf_smartlink_sections in target_info.flags) then    if not(target_info.system in systems_darwin) then     { disabled because not tested      GCSectionsStr:='--gc-sections' }    else      GCSectionsStr:='-dead_strip -no_dead_strip_inits_and_terms';  { i386_freebsd needs -b elf32-i386-freebsd and -m elf_i386_fbsd    to avoid creation of a i386:x86_64 arch binary }  if target_info.system=system_i386_freebsd then    begin      targetstr:='-b elf32-i386-freebsd';      emulstr:='-m elf_i386_fbsd';    end  else    begin      targetstr:='';      emulstr:='';    end;  InitStr:='-init FPC_LIB_START';  FiniStr:='-fini FPC_LIB_EXIT';  SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename);{ Call linker }  SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);{$ifndef darwin}  Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));{$else darwin}  Replace(cmdstr,'$EXE',maybequoted(ExpandFileName(current_module.sharedlibfilename)));{$endif darwin}  Replace(cmdstr,'$OPT',Info.ExtraOptions);  Replace(cmdstr,'$TARGET',targetstr);  Replace(cmdstr,'$EMUL',EmulStr);  Replace(cmdstr,'$CATRES',CatFileContent(outputexedir+Info.ResName));  Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));  Replace(cmdstr,'$INIT',InitStr);  Replace(cmdstr,'$FINI',FiniStr);  Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);  Replace(cmdstr,'$SONAME',SoNameStr);  if (target_info.system in systems_darwin) then    Replace(cmdstr,'$PRTOBJ',GetDarwinPrtobjName(true));  BinStr:=FindUtil(utilsprefix+BinStr);  { create dsym file? }  extdbgbinstr:='';  extdbgcmdstr:='';  if (target_info.system in systems_darwin) and     (target_dbg.id in [dbg_dwarf2,dbg_dwarf3]) and     (cs_link_separate_dbg_file in current_settings.globalswitches) then    begin      extdbgbinstr:=FindUtil(utilsprefix+'dsymutil');      extdbgcmdstr:=maybequoted(current_module.sharedlibfilename);    end;  if (target_info.system in systems_darwin) then    begin      { exported symbols for darwin }      if not texportlibunix(exportlib).exportedsymnames.empty then        begin          assign(exportedsyms,outputexedir+'linksyms.fpc');          rewrite(exportedsyms);          repeat            writeln(exportedsyms,texportlibunix(exportlib).exportedsymnames.getfirst);          until texportlibunix(exportlib).exportedsymnames.empty;          close(exportedsyms);          cmdstr:=cmdstr+' -exported_symbols_list '+maybequoted(outputexedir)+'linksyms.fpc';        end;    end;  if (LdSupportsNoResponseFile) and     not(cs_link_nolink in current_settings.globalswitches) then    begin      { we have to use a script to use the IFS hack }      linkscript:=TAsmScriptUnix.create(outputexedir+'ppaslink');      linkscript.AddLinkCommand(BinStr,CmdStr,'');      if (extdbgbinstr<>'') then        linkscript.AddLinkCommand(extdbgbinstr,extdbgcmdstr,'');      linkscript.WriteToDisk;      BinStr:=linkscript.fn;      if not path_absolute(BinStr) then        BinStr:='./'+BinStr;      CmdStr:='';    end;  success:=DoExec(BinStr,cmdstr,true,LdSupportsNoResponseFile);  if (success and      (extdbgbinstr<>'') and      (cs_link_nolink in current_settings.globalswitches)) then    success:=DoExec(extdbgbinstr,extdbgcmdstr,false,LdSupportsNoResponseFile);{ Strip the library ? }  if success and (cs_link_strip in current_settings.globalswitches) then   begin     SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);     Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));     success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,false,false);   end;{ Remove ReponseFile }  if (success) and not(cs_link_nolink in current_settings.globalswitches) then    begin      DeleteFile(outputexedir+Info.ResName);      if LdSupportsNoResponseFile Then        begin          DeleteFile(linkscript.fn);          linkscript.free        end;      if (target_info.system in systems_darwin) then        DeleteFile(outputexedir+'linksyms.fpc');    end;  MakeSharedLibrary:=success;   { otherwise a recursive call to link method }end;{*****************************************************************************                                     Initialize*****************************************************************************}initialization  RegisterLinker(ld_bsd,TLinkerBSD);{$ifdef x86_64}  RegisterImport(system_x86_64_dragonfly,timportlibbsd);  RegisterExport(system_x86_64_dragonfly,texportlibbsd);  RegisterTarget(system_x86_64_dragonfly_info);  RegisterImport(system_x86_64_freebsd,timportlibbsd);  RegisterExport(system_x86_64_freebsd,texportlibbsd);  RegisterTarget(system_x86_64_freebsd_info);  RegisterImport(system_x86_64_openbsd,timportlibbsd);  RegisterExport(system_x86_64_openbsd,texportlibbsd);  RegisterTarget(system_x86_64_openbsd_info);  RegisterImport(system_x86_64_netbsd,timportlibbsd);  RegisterExport(system_x86_64_netbsd,texportlibbsd);  RegisterTarget(system_x86_64_netbsd_info);  RegisterImport(system_x86_64_darwin,timportlibdarwin);  RegisterExport(system_x86_64_darwin,texportlibdarwin);  RegisterTarget(system_x86_64_darwin_info);{$endif}{$ifdef i386}  RegisterImport(system_i386_freebsd,timportlibbsd);  RegisterExport(system_i386_freebsd,texportlibbsd);  RegisterTarget(system_i386_freebsd_info);  RegisterImport(system_i386_netbsd,timportlibbsd);  RegisterExport(system_i386_netbsd,texportlibbsd);  RegisterTarget(system_i386_netbsd_info);  RegisterImport(system_i386_openbsd,timportlibbsd);  RegisterExport(system_i386_openbsd,texportlibbsd);  RegisterTarget(system_i386_openbsd_info);  RegisterImport(system_i386_darwin,timportlibdarwin);  RegisterExport(system_i386_darwin,texportlibdarwin);  RegisterTarget(system_i386_darwin_info);  RegisterImport(system_i386_iphonesim,timportlibdarwin);  RegisterExport(system_i386_iphonesim,texportlibdarwin);  RegisterTarget(system_i386_iphonesim_info);{$endif i386}{$ifdef m68k}  RegisterImport(system_m68k_netbsd,timportlibbsd);  RegisterExport(system_m68k_netbsd,texportlibbsd);  RegisterTarget(system_m68k_netbsd_info);{$endif m68k}{$ifdef powerpc}  RegisterImport(system_powerpc_darwin,timportlibdarwin);  RegisterExport(system_powerpc_darwin,texportlibdarwin);  RegisterTarget(system_powerpc_darwin_info);  RegisterImport(system_powerpc_netbsd,timportlibbsd);  RegisterExport(system_powerpc_netbsd,texportlibbsd);  RegisterTarget(system_powerpc_netbsd_info);{$endif powerpc}{$ifdef powerpc64}  RegisterImport(system_powerpc64_darwin,timportlibdarwin);  RegisterExport(system_powerpc64_darwin,texportlibdarwin);  RegisterTarget(system_powerpc64_darwin_info);{$endif powerpc64}{$ifdef arm}  RegisterImport(system_arm_darwin,timportlibdarwin);  RegisterExport(system_arm_darwin,texportlibdarwin);  RegisterTarget(system_arm_darwin_info);{$endif arm}  RegisterRes(res_elf_info,TWinLikeResourceFile);  RegisterRes(res_macho_info,TWinLikeResourceFile);end.
 |