PageRenderTime 187ms CodeModel.GetById 58ms app.highlight 107ms RepoModel.GetById 4ms app.codeStats 0ms

/compiler/systems/t_linux.pas

https://github.com/slibre/freepascal
Pascal | 1558 lines | 1213 code | 108 blank | 237 comment | 99 complexity | 209a610774a1879467cb57f0d7d4b535 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, LGPL-3.0

Large files files are truncated, but you can click here to view the full file

   1{
   2    Copyright (c) 1998-2008 by Peter Vreman
   3
   4    This unit implements support import,export,link routines
   5    for the (i386) Linux target
   6
   7    This program is free software; you can redistribute it and/or modify
   8    it under the terms of the GNU General Public License as published by
   9    the Free Software Foundation; either version 2 of the License, or
  10    (at your option) any later version.
  11
  12    This program is distributed in the hope that it will be useful,
  13    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15    GNU General Public License for more details.
  16
  17    You should have received a copy of the GNU General Public License
  18    along with this program; if not, write to the Free Software
  19    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20
  21 ****************************************************************************
  22}
  23unit t_linux;
  24
  25{$i fpcdefs.inc}
  26
  27interface
  28
  29  uses
  30    aasmdata,
  31    symsym,symdef,ppu,
  32    import,export,expunix,link;
  33
  34  type
  35    timportliblinux=class(timportlib)
  36      procedure generatelib;override;
  37    end;
  38
  39    texportliblinux=class(texportlibunix)
  40      procedure setfininame(list: TAsmList; const s: string); override;
  41    end;
  42
  43    TLibcType=(libc5,glibc2,glibc21,uclibc);
  44
  45    tlinkerlinux=class(texternallinker)
  46    private
  47      libctype: TLibcType;
  48      prtobj  : string[80];
  49      reorder : boolean;
  50      linklibc: boolean;
  51      Function  WriteResponseFile(isdll:boolean) : Boolean;
  52    public
  53      constructor Create;override;
  54      procedure SetDefaultInfo;override;
  55      procedure InitSysInitUnitName;override;
  56      function  MakeExecutable:boolean;override;
  57      function  MakeSharedLibrary:boolean;override;
  58      procedure LoadPredefinedLibraryOrder; override;
  59    end;
  60
  61    TInternalLinkerLinux=class(TInternalLinker)
  62    private
  63      libctype: TLibcType;
  64      reorder: boolean;
  65      linklibc: boolean;
  66      prtobj: string[20];
  67      dynlinker: string[100];
  68    public
  69      constructor Create;override;
  70      procedure DefaultLinkScript;override;
  71      procedure InitSysInitUnitName;override;
  72    end;
  73
  74implementation
  75
  76  uses
  77    SysUtils,
  78    cutils,cfileutl,cclasses,
  79    verbose,systems,globtype,globals,
  80    symconst,script,
  81    fmodule,
  82    aasmbase,aasmtai,aasmcpu,cpubase,
  83    cgbase,cgobj,cgutils,ogbase,ncgutil,
  84    comprsrc,
  85    ogelf,
  86    rescmn, i_linux
  87    ;
  88
  89{*****************************************************************************
  90                               TIMPORTLIBLINUX
  91*****************************************************************************}
  92
  93    procedure timportliblinux.generatelib;
  94      var
  95        i : longint;
  96        ImportLibrary : TImportLibrary;
  97      begin
  98        for i:=0 to current_module.ImportLibraryList.Count-1 do
  99          begin
 100            ImportLibrary:=TImportLibrary(current_module.ImportLibraryList[i]);
 101            current_module.linkothersharedlibs.add(ImportLibrary.Name,link_always);
 102          end;
 103      end;
 104
 105
 106{*****************************************************************************
 107                               TEXPORTLIBLINUX
 108*****************************************************************************}
 109
 110    procedure texportliblinux.setfininame(list: TAsmList; const s: string);
 111      begin
 112        { the problem with not having a .fini section is that a finalization
 113          routine in regular code can get "smart" linked away -> reference it
 114          just like the debug info }
 115        new_section(list,sec_fpc,'links',0);
 116        list.concat(Tai_const.Createname(s,0));
 117        inherited setfininame(list,s);
 118      end;
 119
 120{*****************************************************************************
 121                                  TLINKERLINUX
 122*****************************************************************************}
 123
 124procedure SetupLibrarySearchPath;
 125begin
 126  if not Dontlinkstdlibpath Then
 127{$ifdef x86_64}
 128    LibrarySearchPath.AddPath(sysrootpath,'/lib64;/usr/lib64;/usr/X11R6/lib64',true);
 129{$else}
 130{$ifdef powerpc64}
 131    LibrarySearchPath.AddPath(sysrootpath,'/lib64;/usr/lib64;/usr/X11R6/lib64',true);
 132{$else powerpc64}
 133    LibrarySearchPath.AddPath(sysrootpath,'/lib;/usr/lib;/usr/X11R6/lib',true);
 134{$endif powerpc64}
 135{$endif x86_64}
 136
 137{$ifdef arm}
 138  { some newver Debian have the crt*.o files at uncommon locations,
 139    for other arm flavours, this cannot hurt }
 140  if not Dontlinkstdlibpath Then
 141{$ifdef FPC_ARMHF}
 142    LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/arm-linux-gnueabihf',true);
 143{$endif FPC_ARMHF}
 144{$ifdef FPC_ARMEL}
 145    LibrarySearchPath.AddPath(sysrootpath,'/usr/lib/arm-linux-gnueabi',true);
 146{$endif}
 147{$endif arm}
 148end;
 149
 150{$ifdef m68k}
 151  { experimental, is this correct? }
 152  const defdynlinker='/lib/ld-linux.so.2';
 153{$endif m68k}
 154
 155{$ifdef i386}
 156  const defdynlinker='/lib/ld-linux.so.2';
 157{$endif}
 158
 159{$ifdef x86_64}
 160  const defdynlinker='/lib64/ld-linux-x86-64.so.2';
 161{$endif x86_64}
 162
 163{$ifdef sparc}
 164  const defdynlinker='/lib/ld-linux.so.2';
 165{$endif sparc}
 166
 167{$ifdef powerpc}
 168  const defdynlinker='/lib/ld.so.1';
 169{$endif powerpc}
 170
 171{$ifdef powerpc64}
 172  const defdynlinker='/lib64/ld64.so.1';
 173{$endif powerpc64}
 174
 175{$ifdef arm}
 176{$ifdef FPC_ARMHF}
 177  const defdynlinker='/lib/ld-linux-armhf.so.3';
 178{$else FPC_ARMHF}
 179{$ifdef FPC_ARMEL}
 180  const defdynlinker='/lib/ld-linux.so.3';
 181{$else FPC_ARMEL}
 182  const defdynlinker='/lib/ld-linux.so.2';
 183{$endif FPC_ARMEL}
 184{$endif FPC_ARMHF}
 185{$endif arm}
 186
 187{$ifdef mips}
 188  const defdynlinker='/lib/ld.so.1';
 189{$endif mips}
 190
 191procedure SetupDynlinker(out DynamicLinker:string;out libctype:TLibcType);
 192begin
 193  {
 194    Search order:
 195    glibc 2.1+
 196    uclibc
 197    glibc 2.0
 198    If none is found (e.g. when cross compiling) glibc21 is assumed
 199  }
 200  if fileexists(sysrootpath+defdynlinker,false) then
 201    begin
 202      DynamicLinker:=defdynlinker;
 203{$ifdef i386}
 204      libctype:=glibc21;
 205{$else i386}
 206      libctype:=glibc2;
 207{$endif i386}
 208    end
 209  else if fileexists(sysrootpath+'/lib/ld-uClibc.so.0',false) then
 210    begin
 211      DynamicLinker:='/lib/ld-uClibc.so.0';
 212      libctype:=uclibc;
 213    end
 214{$ifdef i386}
 215  else if FileExists(sysrootpath+'/lib/ld-linux.so.1',false) then
 216    begin
 217      DynamicLinker:='/lib/ld-linux.so.1';
 218      libctype:=glibc2;
 219    end
 220{$endif i386}
 221  else
 222    begin
 223      { when no dyn. linker is found, we are probably
 224        cross compiling, so use the default dyn. linker }
 225      DynamicLinker:=defdynlinker;
 226      {
 227        the default c startup script is gcrt0.as on all platforms
 228        except i386
 229      }
 230{$ifdef i386}
 231      libctype:=glibc21;
 232{$else i386}
 233      libctype:=glibc2;
 234{$endif i386}
 235    end;
 236end;
 237
 238function ModulesLinkToLibc:boolean;
 239var
 240  hp: tmodule;
 241begin
 242  { This is called very early, ImportLibraryList is not yet merged into linkothersharedlibs.
 243    The former contains library names qualified with prefix and suffix (coming from
 244    "external 'c' name 'foo' declarations), the latter contains raw names (from "$linklib c"
 245    directives). }
 246  hp:=tmodule(loaded_units.first);
 247  while assigned(hp) do
 248    begin
 249      result:=Assigned(hp.ImportLibraryList.find(target_info.sharedClibprefix+'c'+target_info.sharedClibext));
 250      if result then break;
 251      result:=hp.linkothersharedlibs.find(target_info.sharedClibprefix+'c'+target_info.sharedClibext);
 252      if result then break;
 253      result:=hp.linkothersharedlibs.find('c');
 254      if result then break;
 255      hp:=tmodule(hp.next);
 256    end;
 257end;
 258
 259Constructor TLinkerLinux.Create;
 260begin
 261  Inherited Create;
 262  SetupLibrarySearchPath;
 263end;
 264
 265procedure TLinkerLinux.SetDefaultInfo;
 266{
 267  This will also detect which libc version will be used
 268}
 269
 270const
 271{$ifdef i386}      platform_select='-b elf32-i386 -m elf_i386';{$endif}
 272{$ifdef x86_64}    platform_select='-b elf64-x86-64 -m elf_x86_64';{$endif}
 273{$ifdef powerpc}   platform_select='-b elf32-powerpc -m elf32ppclinux';{$endif}
 274{$ifdef POWERPC64} platform_select='-b elf64-powerpc -m elf64ppc';{$endif}
 275{$ifdef sparc}     platform_select='-b elf32-sparc -m elf32_sparc';{$endif}
 276{$ifdef arm}       platform_select='';{$endif} {unknown :( }
 277{$ifdef m68k}      platform_select='';{$endif} {unknown :( }
 278{$ifdef mips}
 279  {$ifdef mipsel}  
 280	           platform_select='-EL';
 281  {$else}
 282                   platform_select='-EB';
 283  {$endif}
 284{$endif}
 285
 286
 287begin
 288  with Info do
 289   begin
 290     ExeCmd[1]:='ld '+platform_select+' $OPT $DYNLINK $STATIC $GCSECTIONS $STRIP -L. -o $EXE';
 291     { when we want to cross-link we need to override default library paths }
 292     if length(sysrootpath) > 0 then
 293       ExeCmd[1]:=ExeCmd[1]+' -T';
 294     ExeCmd[1]:=ExeCmd[1]+' $RES';
 295     DllCmd[1]:='ld '+platform_select+' $OPT $INIT $FINI $SONAME -shared -L. -o $EXE $RES';
 296     DllCmd[2]:='strip --strip-unneeded $EXE';
 297     ExtDbgCmd[1]:='objcopy --only-keep-debug $EXE $DBG';
 298     ExtDbgCmd[2]:='objcopy --add-gnu-debuglink=$DBG $EXE';
 299     ExtDbgCmd[3]:='strip --strip-unneeded $EXE';
 300
 301     SetupDynlinker(DynamicLinker,libctype);
 302   end;
 303end;
 304
 305
 306procedure TLinkerLinux.LoadPredefinedLibraryOrder;
 307// put your linkorder/linkalias overrides here.
 308// Note: assumes only called when reordering/aliasing is used.
 309Begin
 310   if not (cs_link_no_default_lib_order in  current_settings.globalswitches) Then
 311        Begin
 312          LinkLibraryOrder.add('gcc','',15);
 313          LinkLibraryOrder.add('c','',100);
 314          LinkLibraryOrder.add('gmon','',120);
 315          LinkLibraryOrder.add('dl','',140);
 316          LinkLibraryOrder.add('pthread','',160);
 317         end;
 318End;
 319
 320type
 321  tlibcnames=array [TLibcType] of string[8];
 322
 323const                     { libc5    glibc2   glibc21   uclibc }
 324  cprtnames: tlibcnames = ('cprt0', 'cprt0', 'cprt21', 'ucprt0');
 325  csinames: tlibcnames  = ('si_c',  'si_c',  'si_c21', 'si_uc');
 326  gprtnames: tlibcnames = ('gprt0', 'gprt0', 'gprt21', 'ugprt0');
 327  gsinames: tlibcnames  = ('si_g',  'si_g',  'si_c21g','si_ucg');
 328
 329  defprtnames: array[boolean] of string[8] = ('prt0',  'dllprt0');
 330  defsinames: array[boolean] of string[8]  = ('si_prc','si_dll');
 331
 332{ uclibc and glibc21 are not available on x86_64! si_g is also absent. }
 333Procedure TLinkerLinux.InitSysInitUnitName;
 334begin
 335  linklibc:=ModulesLinkToLibc;
 336  reorder:=linklibc and ReOrderEntries;
 337  sysinitunit:=defsinames[current_module.islibrary];
 338  prtobj:=defprtnames[current_module.islibrary];
 339
 340  if current_module.islibrary then
 341    exit;
 342  if cs_profile in current_settings.moduleswitches then
 343    begin
 344      prtobj:=gprtnames[libctype];
 345      sysinitunit:=gsinames[libctype];
 346      linklibc:=true;
 347    end
 348  else if linklibc then
 349    begin
 350      prtobj:=cprtnames[libctype];
 351      sysinitunit:=csinames[libctype];
 352    end;
 353end;
 354
 355Function TLinkerLinux.WriteResponseFile(isdll:boolean) : Boolean;
 356Var
 357  linkres      : TLinkRes;
 358  i            : longint;
 359  HPath        : TCmdStrListItem;
 360  s,s1,s2      : TCmdStr;
 361  found1,
 362  found2       : boolean;
 363  linksToSharedLibFiles : boolean;
 364begin
 365  result:=False;
 366{ set special options for some targets }
 367  if cs_profile in current_settings.moduleswitches then
 368   begin
 369     if not(libctype in [glibc2,glibc21]) then
 370       AddSharedLibrary('gmon');
 371     AddSharedLibrary('c');
 372   end;
 373
 374  { Open link.res file }
 375  LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true);
 376  with linkres do
 377    begin
 378      { Write path to search libraries }
 379      HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First);
 380      while assigned(HPath) do
 381       begin
 382         Add('SEARCH_DIR("'+HPath.Str+'")');
 383         HPath:=TCmdStrListItem(HPath.Next);
 384       end;
 385      HPath:=TCmdStrListItem(LibrarySearchPath.First);
 386      while assigned(HPath) do
 387       begin
 388         Add('SEARCH_DIR("'+HPath.Str+'")');
 389         HPath:=TCmdStrListItem(HPath.Next);
 390       end;
 391
 392      { force local symbol resolution (i.e., inside the shared }
 393      { library itself) for all non-exorted symbols, otherwise }
 394      { several RTL symbols of FPC-compiled shared libraries   }
 395      { will be bound to those of a single shared library or   }
 396      { to the main program                                    }
 397      if (isdll) then
 398        begin
 399          add('VERSION');
 400          add('{');
 401          add('  {');
 402          if not texportlibunix(exportlib).exportedsymnames.empty then
 403            begin
 404              add('    global:');
 405              repeat
 406                add('      '+texportlibunix(exportlib).exportedsymnames.getfirst+';');
 407              until texportlibunix(exportlib).exportedsymnames.empty;
 408            end;
 409          add('    local:');
 410          add('      *;');
 411          add('  };');
 412          add('}');
 413        end;
 414
 415      StartSection('INPUT(');
 416      { add objectfiles, start with prt0 always }
 417      if not (target_info.system in systems_internal_sysinit) and (prtobj<>'') then
 418       AddFileName(maybequoted(FindObjectFile(prtobj,'',false)));
 419      { try to add crti and crtbegin if linking to C }
 420      if linklibc and (libctype<>uclibc) then
 421       begin
 422         { crti.o must come first }
 423         if librarysearchpath.FindFile('crti.o',false,s) then
 424           AddFileName(s);
 425         { then the crtbegin* }
 426         if cs_create_pic in current_settings.moduleswitches then
 427           begin
 428             if librarysearchpath.FindFile('crtbeginS.o',false,s) then
 429               AddFileName(s);
 430           end
 431         else
 432           if (cs_link_staticflag in current_settings.globalswitches) and
 433              librarysearchpath.FindFile('crtbeginT.o',false,s) then
 434             AddFileName(s)
 435           else if librarysearchpath.FindFile('crtbegin.o',false,s) then
 436             AddFileName(s);
 437       end;
 438      { main objectfiles }
 439      while not ObjectFiles.Empty do
 440       begin
 441         s:=ObjectFiles.GetFirst;
 442         if s<>'' then
 443          AddFileName(maybequoted(s));
 444       end;
 445      EndSection(')');
 446
 447      { Write staticlibraries }
 448      if not StaticLibFiles.Empty then
 449       begin
 450         Add('GROUP(');
 451         While not StaticLibFiles.Empty do
 452          begin
 453            S:=StaticLibFiles.GetFirst;
 454            AddFileName(maybequoted(s))
 455          end;
 456         Add(')');
 457       end;
 458
 459      // we must reorder here because the result could empty sharedlibfiles
 460      if reorder Then
 461        ExpandAndApplyOrder(SharedLibFiles);
 462      // after this point addition of shared libs not allowed.
 463
 464      { Write sharedlibraries like -l<lib>, also add the needed dynamic linker
 465        here to be sure that it gets linked this is needed for glibc2 systems (PFV) }
 466      if (isdll) then
 467       begin
 468         Add('INPUT(');
 469         Add(info.DynamicLinker);
 470         Add(')');
 471       end;
 472      linksToSharedLibFiles := not SharedLibFiles.Empty;
 473
 474      if not SharedLibFiles.Empty then
 475       begin
 476
 477         if (SharedLibFiles.Count<>1) or
 478            (TCmdStrListItem(SharedLibFiles.First).Str<>'c') or
 479            reorder then
 480           begin
 481             Add('INPUT(');
 482             While not SharedLibFiles.Empty do
 483              begin
 484                S:=SharedLibFiles.GetFirst;
 485                if (s<>'c') or reorder then
 486                 begin
 487                   i:=Pos(target_info.sharedlibext,S);
 488                   if i>0 then
 489                    Delete(S,i,255);
 490                   Add('-l'+s);
 491                 end
 492                else
 493                 begin
 494                   linklibc:=true;
 495                 end;
 496              end;
 497             Add(')');
 498           end
 499         else
 500           linklibc:=true;
 501         if (cs_link_staticflag in current_settings.globalswitches) or
 502            (linklibc and not reorder) then
 503           begin
 504             Add('GROUP(');
 505             { when we have -static for the linker the we also need libgcc }
 506             if (cs_link_staticflag in current_settings.globalswitches) then
 507               begin
 508                 Add('-lgcc');
 509                 if librarysearchpath.FindFile('libgcc_eh.a',false,s1) then
 510                   Add('-lgcc_eh');
 511               end;
 512             { be sure that libc is the last lib }
 513             if linklibc and not reorder then
 514               Add('-lc');
 515             Add(')');
 516           end;
 517       end;
 518
 519      { objects which must be at the end }
 520      if linklibc and (libctype<>uclibc) then
 521       begin
 522         if cs_create_pic in current_settings.moduleswitches then
 523           found1:=librarysearchpath.FindFile('crtendS.o',false,s1)
 524         else
 525           found1:=librarysearchpath.FindFile('crtend.o',false,s1);
 526         found2:=librarysearchpath.FindFile('crtn.o',false,s2);
 527         if found1 or found2 then
 528          begin
 529            Add('INPUT(');
 530            if found1 then
 531             AddFileName(s1);
 532            if found2 then
 533             AddFileName(s2);
 534            Add(')');
 535          end;
 536       end;
 537
 538      {Entry point. Only needed for executables, set on the linker command line for
 539       shared libraries. }
 540      if (not isdll) then
 541       if (linksToSharedLibFiles and not linklibc) then
 542        add('ENTRY(_dynamic_start)')
 543       else
 544        add('ENTRY(_start)');
 545
 546{$ifdef x86_64}
 547{$define LINKERSCRIPT_INCLUDED}
 548      add('SECTIONS');
 549      add('{');
 550      {Read-only sections, merged into text segment:}
 551      if current_module.islibrary  then
 552        add('  . = 0 +  SIZEOF_HEADERS;')
 553      else
 554        add('  PROVIDE (__executable_start = 0x0400000); . = 0x0400000 +  SIZEOF_HEADERS;');
 555      add('  . = 0 +  SIZEOF_HEADERS;');
 556      add('  .interp         : { *(.interp) }');
 557      add('  .hash           : { *(.hash) }');
 558      add('  .dynsym         : { *(.dynsym) }');
 559      add('  .dynstr         : { *(.dynstr) }');
 560      add('  .gnu.version    : { *(.gnu.version) }');
 561      add('  .gnu.version_d  : { *(.gnu.version_d) }');
 562      add('  .gnu.version_r  : { *(.gnu.version_r) }');
 563      add('  .rel.dyn        :');
 564      add('    {');
 565      add('      *(.rel.init)');
 566      add('      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
 567      add('      *(.rel.fini)');
 568      add('      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
 569      add('      *(.rel.data.rel.ro*)');
 570      add('      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
 571      add('      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
 572      add('      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
 573      add('      *(.rel.got)');
 574      add('      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
 575      add('    }');
 576      add('  .rela.dyn       :');
 577      add('    {');
 578      add('      *(.rela.init)');
 579      add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
 580      add('      *(.rela.fini)');
 581      add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
 582      add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
 583      add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
 584      add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
 585      add('      *(.rela.got)');
 586      add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
 587      add('    }');
 588      add('  .rel.plt        : { *(.rel.plt) }');
 589      add('  .rela.plt       : { *(.rela.plt) }');
 590      add('  .init           :');
 591      add('  {');
 592      add('    KEEP (*(.init))');
 593      add('  } =0x90909090');
 594      add('  .plt            : { *(.plt) }');
 595      add('  .text           :');
 596      add('  {');
 597      add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
 598      add('    KEEP (*(.text.*personality*))');
 599      {.gnu.warning sections are handled specially by elf32.em.}
 600      add('    *(.gnu.warning)');
 601      add('  } =0x90909090');
 602      add('  .fini           :');
 603      add('  {');
 604      add('    KEEP (*(.fini))');
 605      add('  } =0x90909090');
 606      add('  PROVIDE (_etext = .);');
 607      add('  .rodata         :');
 608      add('  {');
 609      add('    *(.rodata .rodata.* .gnu.linkonce.r.*)');
 610      add('  }');
 611      {Adjust the address for the data segment.  We want to adjust up to
 612       the same address within the page on the next page up.}
 613      add('  . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1));');
 614      add('  .dynamic        : { *(.dynamic) }');
 615      add('  .got            : { *(.got .toc) }');
 616      add('  .got.plt        : { *(.got.plt .toc.plt) }');
 617      add('  .data           :');
 618      add('  {');
 619      add('    *(.data .data.* .gnu.linkonce.d.*)');
 620      add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
 621      add('    KEEP (*(.gnu.linkonce.d.*personality*))');
 622      add('  }');
 623      add('  PROVIDE (_edata = .);');
 624      add('  PROVIDE (edata = .);');
 625    {$ifdef zsegment_threadvars}
 626      add('  _z = .;');
 627      add('  .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
 628      add('  PROVIDE (_threadvar_size = SIZEOF(.threadvar));');
 629      add('  . = _z + SIZEOF (.threadvar);');
 630    {$else}
 631      add('  .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
 632    {$endif}
 633      add('  __bss_start = .;');
 634      add('  .bss            :');
 635      add('  {');
 636      add('   *(.dynbss)');
 637      add('   *(.bss .bss.* .gnu.linkonce.b.*)');
 638      add('   *(COMMON)');
 639      {Align here to ensure that the .bss section occupies space up to
 640       _end.  Align after .bss to ensure correct alignment even if the
 641       .bss section disappears because there are no input sections.}
 642      add('   . = ALIGN(32 / 8);');
 643      add('  }');
 644      add('  . = ALIGN(32 / 8);');
 645      add('  PROVIDE (_end = .);');
 646      add('  PROVIDE (end = .);');
 647      {Stabs debugging sections.}
 648      add('  .stab          0 : { *(.stab) }');
 649      add('  .stabstr       0 : { *(.stabstr) }');
 650      add('  /* DWARF debug sections.');
 651      add('     Symbols in the DWARF debugging sections are relative to the beginning');
 652      add('     of the section so we begin them at 0.  */');
 653      add('  /* DWARF 1 */');
 654      add('  .debug          0 : { *(.debug) }');
 655      add('  .line           0 : { *(.line) }');
 656      add('  /* GNU DWARF 1 extensions */');
 657      add('  .debug_srcinfo  0 : { *(.debug_srcinfo) }');
 658      add('  .debug_sfnames  0 : { *(.debug_sfnames) }');
 659      add('  /* DWARF 1.1 and DWARF 2 */');
 660      add('  .debug_aranges  0 : { *(.debug_aranges) }');
 661      add('  .debug_pubnames 0 : { *(.debug_pubnames) }');
 662      add('  /* DWARF 2 */');
 663      add('  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }');
 664      add('  .debug_abbrev   0 : { *(.debug_abbrev) }');
 665      add('  .debug_line     0 : { *(.debug_line) }');
 666      add('  .debug_frame    0 : { *(.debug_frame) }');
 667      add('  .debug_str      0 : { *(.debug_str) }');
 668      add('  .debug_loc      0 : { *(.debug_loc) }');
 669      add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
 670      add('  /* SGI/MIPS DWARF 2 extensions */');
 671      add('  .debug_weaknames 0 : { *(.debug_weaknames) }');
 672      add('  .debug_funcnames 0 : { *(.debug_funcnames) }');
 673      add('  .debug_typenames 0 : { *(.debug_typenames) }');
 674      add('  .debug_varnames  0 : { *(.debug_varnames) }');
 675      add('  /DISCARD/ : { *(.note.GNU-stack) }');
 676      add('}');
 677{$endif x86_64}
 678
 679{$ifdef ARM}
 680      if target_info.abi=abi_eabi then
 681        begin
 682          { from GNU ld (CodeSourcery Sourcery G++ Lite 2007q3-53) 2.18.50.20070820 }
 683          add('/* Script for -z combreloc: combine and sort reloc sections */');
 684          add('OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm",');
 685          add('	      "elf32-littlearm")');
 686          add('OUTPUT_ARCH(arm)');
 687          add('SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");');
 688          add('SECTIONS');
 689          add('{');
 690          add('  /* Read-only sections, merged into text segment: */');
 691          add('  PROVIDE (__executable_start = 0x8000); . = 0x8000 + SIZEOF_HEADERS;');
 692          add('  .interp         : { *(.interp) }');
 693          add('  .note.gnu.build-id : { *(.note.gnu.build-id) }');
 694          add('  .hash           : { *(.hash) }');
 695          add('  .gnu.hash       : { *(.gnu.hash) }');
 696          add('  .dynsym         : { *(.dynsym) }');
 697          add('  .dynstr         : { *(.dynstr) }');
 698          add('  .gnu.version    : { *(.gnu.version) }');
 699          add('  .gnu.version_d  : { *(.gnu.version_d) }');
 700          add('  .gnu.version_r  : { *(.gnu.version_r) }');
 701          add('  .rel.dyn        :');
 702          add('    {');
 703          add('      *(.rel.init)');
 704          add('      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
 705          add('      *(.rel.fini)');
 706          add('      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
 707          add('      *(.rel.data.rel.ro* .rel.gnu.linkonce.d.rel.ro.*)');
 708          add('      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
 709          add('      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
 710          add('      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
 711          add('      *(.rel.ctors)');
 712          add('      *(.rel.dtors)');
 713          add('      *(.rel.got)');
 714          add('      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
 715          add('    }');
 716          add('  .rela.dyn       :');
 717          add('    {');
 718          add('      *(.rela.init)');
 719          add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
 720          add('      *(.rela.fini)');
 721          add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
 722          add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
 723          add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
 724          add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
 725          add('      *(.rela.ctors)');
 726          add('      *(.rela.dtors)');
 727          add('      *(.rela.got)');
 728          add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
 729          add('    }');
 730          add('  .rel.plt        : { *(.rel.plt) }');
 731          add('  .rela.plt       : { *(.rela.plt) }');
 732          add('  .init           :');
 733          add('  {');
 734          add('    KEEP (*(.init))');
 735          add('  } =0');
 736          add('  .plt            : { *(.plt) }');
 737          add('  .text           :');
 738          add('  {');
 739          add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
 740          add('    KEEP (*(.text.*personality*))');
 741          add('    /* .gnu.warning sections are handled specially by elf32.em.  */');
 742          add('    *(.gnu.warning)');
 743          add('    *(.glue_7t) *(.glue_7) *(.vfp11_veneer)');
 744          add('  } =0');
 745          add('  .fini           :');
 746          add('  {');
 747          add('    KEEP (*(.fini))');
 748          add('  } =0');
 749          add('  PROVIDE (__etext = .);');
 750          add('  PROVIDE (_etext = .);');
 751          add('  PROVIDE (etext = .);');
 752          add('  .rodata         : { *(.rodata .rodata.* .gnu.linkonce.r.*) }');
 753          add('  .rodata1        : { *(.rodata1) }');
 754          add('  .ARM.extab   : { *(.ARM.extab* .gnu.linkonce.armextab.*) }');
 755          add('   __exidx_start = .;');
 756          add('  .ARM.exidx   : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) }');
 757          add('   __exidx_end = .;');
 758          add('  .eh_frame_hdr : { *(.eh_frame_hdr) }');
 759          add('  .eh_frame       : ONLY_IF_RO { KEEP (*(.eh_frame)) }');
 760          add('  .gcc_except_table   : ONLY_IF_RO { *(.gcc_except_table .gcc_except_table.*) }');
 761          add('  /* Adjust the address for the data segment.  We want to adjust up to');
 762          add('     the same address within the page on the next page up.  */');
 763          add('  . = ALIGN(CONSTANT (MAXPAGESIZE)) + (. & (CONSTANT (MAXPAGESIZE) - 1));');
 764          add('  /* Exception handling  */');
 765          add('  .eh_frame       : ONLY_IF_RW { KEEP (*(.eh_frame)) }');
 766          add('  .gcc_except_table   : ONLY_IF_RW { *(.gcc_except_table .gcc_except_table.*) }');
 767          add('  /* Thread Local Storage sections  */');
 768          add('  .tdata	  : { *(.tdata .tdata.* .gnu.linkonce.td.*) }');
 769          add('  .tbss		  : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) }');
 770          add('  .preinit_array     :');
 771          add('  {');
 772          add('    PROVIDE_HIDDEN (__preinit_array_start = .);');
 773          add('    KEEP (*(.preinit_array))');
 774          add('    PROVIDE_HIDDEN (__preinit_array_end = .);');
 775          add('  }');
 776          add('  .init_array     :');
 777          add('  {');
 778          add('     PROVIDE_HIDDEN (__init_array_start = .);');
 779          add('     KEEP (*(SORT(.init_array.*)))');
 780          add('     KEEP (*(.init_array))');
 781          add('     PROVIDE_HIDDEN (__init_array_end = .);');
 782          add('  }');
 783          add('  .fini_array     :');
 784          add('  {');
 785          add('    PROVIDE_HIDDEN (__fini_array_start = .);');
 786          add('    KEEP (*(.fini_array))');
 787          add('    KEEP (*(SORT(.fini_array.*)))');
 788          add('    PROVIDE_HIDDEN (__fini_array_end = .);');
 789          add('  }');
 790          add('  .ctors          :');
 791          add('  {');
 792          add('    /* gcc uses crtbegin.o to find the start of');
 793          add('       the constructors, so we make sure it is');
 794          add('       first.  Because this is a wildcard, it');
 795          add('       doesn''t matter if the user does not');
 796          add('       actually link against crtbegin.o; the');
 797          add('       linker won''t look for a file to match a');
 798          add('       wildcard.  The wildcard also means that it');
 799          add('       doesn''t matter which directory crtbegin.o');
 800          add('       is in.  */');
 801          add('    KEEP (*crtbegin.o(.ctors))');
 802          add('    KEEP (*crtbegin?.o(.ctors))');
 803          add('    /* We don''t want to include the .ctor section from');
 804          add('       the crtend.o file until after the sorted ctors.');
 805          add('       The .ctor section from the crtend file contains the');
 806          add('       end of ctors marker and it must be last */');
 807          add('    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors))');
 808          add('    KEEP (*(SORT(.ctors.*)))');
 809          add('    KEEP (*(.ctors))');
 810          add('  }');
 811          add('  .dtors          :');
 812          add('  {');
 813          add('    KEEP (*crtbegin.o(.dtors))');
 814          add('    KEEP (*crtbegin?.o(.dtors))');
 815          add('    KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors))');
 816          add('    KEEP (*(SORT(.dtors.*)))');
 817          add('    KEEP (*(.dtors))');
 818          add('  }');
 819          add('  .jcr            : { KEEP (*(.jcr)) }');
 820          add('  .data.rel.ro : { *(.data.rel.ro.local* .gnu.linkonce.d.rel.ro.local.*) *(.data.rel.ro* .gnu.linkonce.d.rel.ro.*) }');
 821          add('  .dynamic        : { *(.dynamic) }');
 822          add('  .got            : { *(.got.plt) *(.got) }');
 823          add('  .data           :');
 824          add('  {');
 825          add('    __data_start = . ;');
 826          add('    *(.data .data.* .gnu.linkonce.d.*)');
 827
 828          { extra by FPC }
 829          add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
 830
 831          add('    KEEP (*(.gnu.linkonce.d.*personality*))');
 832          add('    SORT(CONSTRUCTORS)');
 833          add('  }');
 834          add('  .data1          : { *(.data1) }');
 835          add('  _edata = .; PROVIDE (edata = .);');
 836          add('  __bss_start = .;');
 837          add('  __bss_start__ = .;');
 838          add('  .bss            :');
 839          add('  {');
 840          add('   *(.dynbss)');
 841          add('   *(.bss .bss.* .gnu.linkonce.b.*)');
 842          add('   *(COMMON)');
 843          add('   /* Align here to ensure that the .bss section occupies space up to');
 844          add('      _end.  Align after .bss to ensure correct alignment even if the');
 845          add('      .bss section disappears because there are no input sections.');
 846          add('      FIXME: Why do we need it? When there is no .bss section, we don''t');
 847          add('      pad the .data section.  */');
 848          add('   . = ALIGN(. != 0 ? 32 / 8 : 1);');
 849          add('  }');
 850          add('  _bss_end__ = . ; __bss_end__ = . ;');
 851          add('  . = ALIGN(32 / 8);');
 852          add('  . = ALIGN(32 / 8);');
 853          add('  __end__ = . ;');
 854          add('  _end = .; PROVIDE (end = .);');
 855          add('  /* Stabs debugging sections.  */');
 856          add('  .stab          0 : { *(.stab) }');
 857          add('  .stabstr       0 : { *(.stabstr) }');
 858          add('  .stab.excl     0 : { *(.stab.excl) }');
 859          add('  .stab.exclstr  0 : { *(.stab.exclstr) }');
 860          add('  .stab.index    0 : { *(.stab.index) }');
 861          add('  .stab.indexstr 0 : { *(.stab.indexstr) }');
 862          add('  .comment       0 : { *(.comment) }');
 863          add('  /* DWARF debug sections.');
 864          add('     Symbols in the DWARF debugging sections are relative to the beginning');
 865          add('     of the section so we begin them at 0.  */');
 866          add('  /* DWARF 1 */');
 867          add('  .debug          0 : { *(.debug) }');
 868          add('  .line           0 : { *(.line) }');
 869          add('  /* GNU DWARF 1 extensions */');
 870          add('  .debug_srcinfo  0 : { *(.debug_srcinfo) }');
 871          add('  .debug_sfnames  0 : { *(.debug_sfnames) }');
 872          add('  /* DWARF 1.1 and DWARF 2 */');
 873          add('  .debug_aranges  0 : { *(.debug_aranges) }');
 874          add('  .debug_pubnames 0 : { *(.debug_pubnames) }');
 875          add('  /* DWARF 2 */');
 876          add('  .debug_info     0 : { *(.debug_info .gnu.linkonce.wi.*) }');
 877          add('  .debug_abbrev   0 : { *(.debug_abbrev) }');
 878          add('  .debug_line     0 : { *(.debug_line) }');
 879          add('  .debug_frame    0 : { *(.debug_frame) }');
 880          add('  .debug_str      0 : { *(.debug_str) }');
 881          add('  .debug_loc      0 : { *(.debug_loc) }');
 882          add('  .debug_macinfo  0 : { *(.debug_macinfo) }');
 883          add('  /* SGI/MIPS DWARF 2 extensions */');
 884          add('  .debug_weaknames 0 : { *(.debug_weaknames) }');
 885          add('  .debug_funcnames 0 : { *(.debug_funcnames) }');
 886          add('  .debug_typenames 0 : { *(.debug_typenames) }');
 887          add('  .debug_varnames  0 : { *(.debug_varnames) }');
 888          add('  /* DWARF 3 */');
 889          add('  .debug_pubtypes 0 : { *(.debug_pubtypes) }');
 890          add('  .debug_ranges   0 : { *(.debug_ranges) }');
 891          add('    .stack         0x80000 :');
 892          add('  {');
 893          add('    _stack = .;');
 894          add('    *(.stack)');
 895          add('  }');
 896          add('  .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) }');
 897          add('  .note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }');
 898          add('  /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) }');
 899          add('}');
 900        end
 901      else
 902{$endif ARM}
 903
 904{$ifndef LINKERSCRIPT_INCLUDED}
 905        begin
 906          {Sections.}
 907          add('SECTIONS');
 908          add('{');
 909          {Read-only sections, merged into text segment:}
 910          add('  PROVIDE (__executable_start = 0x010000); . = 0x010000 + SIZEOF_HEADERS;');
 911          add('  .interp         : { *(.interp) }');
 912          add('  .hash           : { *(.hash) }');
 913          add('  .dynsym         : { *(.dynsym) }');
 914          add('  .dynstr         : { *(.dynstr) }');
 915          add('  .gnu.version    : { *(.gnu.version) }');
 916          add('  .gnu.version_d  : { *(.gnu.version_d) }');
 917          add('  .gnu.version_r  : { *(.gnu.version_r) }');
 918          add('  .rel.dyn        :');
 919          add('    {');
 920          add('      *(.rel.init)');
 921          add('      *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*)');
 922          add('      *(.rel.fini)');
 923          add('      *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*)');
 924          add('      *(.rel.data.rel.ro*)');
 925          add('      *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*)');
 926          add('      *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*)');
 927          add('      *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*)');
 928          add('      *(.rel.got)');
 929          add('      *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*)');
 930          add('    }');
 931          add('  .rela.dyn       :');
 932          add('    {');
 933          add('      *(.rela.init)');
 934          add('      *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*)');
 935          add('      *(.rela.fini)');
 936          add('      *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*)');
 937          add('      *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*)');
 938          add('      *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*)');
 939          add('      *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*)');
 940          add('      *(.rela.got)');
 941          add('      *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)');
 942          add('    }');
 943          add('  .rel.plt        : { *(.rel.plt) }');
 944          add('  .rela.plt       : { *(.rela.plt) }');
 945          add('  .init           :');
 946          add('  {');
 947          add('    KEEP (*(.init))');
 948          add('  } =0x90909090');
 949          add('  .plt            : { *(.plt) }');
 950          add('  .text           :');
 951          add('  {');
 952          add('    *(.text .stub .text.* .gnu.linkonce.t.*)');
 953          add('    KEEP (*(.text.*personality*))');
 954          {.gnu.warning sections are handled specially by elf32.em.}
 955          add('    *(.gnu.warning)');
 956          add('  } =0x90909090');
 957          add('  .fini           :');
 958          add('  {');
 959          add('    KEEP (*(.fini))');
 960          add('  } =0x90909090');
 961          add('  PROVIDE (_etext = .);');
 962          add('  .rodata         :');
 963          add('  {');
 964          add('    *(.rodata .rodata.* .gnu.linkonce.r.*)');
 965          add('  }');
 966          {Adjust the address for the data segment.  We want to adjust up to
 967           the same address within the page on the next page up.}
 968          add('  . = ALIGN (0x1000) - ((0x1000 - .) & (0x1000 - 1));');
 969          add('  .dynamic        : { *(.dynamic) }');
 970          add('  .got            : { *(.got) }');
 971          add('  .got.plt        : { *(.got.plt) }');
 972          add('  .data           :');
 973          add('  {');
 974          add('    *(.data .data.* .gnu.linkonce.d.*)');
 975          add('    KEEP (*(.fpc .fpc.n_version .fpc.n_links))');
 976          add('    KEEP (*(.gnu.linkonce.d.*personality*))');
 977          add('  }');
 978          add('  PROVIDE (_edata = .);');
 979          add('  PROVIDE (edata = .);');
 980        {$ifdef zsegment_threadvars}
 981          add('  _z = .;');
 982          add('  .threadvar 0 : AT (_z) { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
 983          add('  PROVIDE (_threadvar_size = SIZEOF(.threadvar));');
 984          add('  . = _z + SIZEOF (.threadvar);');
 985        {$else}
 986          add('  .threadvar : { *(.threadvar .threadvar.* .gnu.linkonce.tv.*) }');
 987        {$endif}
 988          add('  __bss_start = .;');
 989          add('  .bss            :');
 990          add('  {');
 991          add('   *(.dynbss)');
 992          add('   *(.bss .bss.* .gnu.linkonce.b.*)');
 993          add('   *(COMMON)');
 994          {Align here to ensure that the .bss section occupies space up to
 995           _end.  Align after .bss to ensure correct alignment even if the
 996           .bss section disappears because there are no input sections.}
 997          add('   . = ALIGN(32 / 8);');
 998          add('  }');
 999          add('  . = ALIGN(32 / 8);');
1000          add('  PROVIDE (_end = .);');
1001          add('  PROVIDE (end = .);');
1002          {Stabs debugging sections.}
1003          add('  .stab          0 : { *(.stab) }');
1004          add('  .stabstr       0 : { *(.stabstr) }');
1005          add('}');
1006        end;
1007{$endif LINKERSCRIPT_INCLUDED}
1008      { Write and Close response }
1009      writetodisk;
1010      Free;
1011    end;
1012
1013  WriteResponseFile:=True;
1014end;
1015
1016
1017function TLinkerLinux.MakeExecutable:boolean;
1018var
1019  i : longint;
1020  binstr,
1021  cmdstr  : TCmdStr;
1022  success : boolean;
1023  DynLinkStr : string;
1024  GCSectionsStr,
1025  StaticStr,
1026  StripStr   : string[40];
1027begin
1028  if not(cs_link_nolink in current_settings.globalswitches) then
1029   Message1(exec_i_linking,current_module.exefilename);
1030
1031{ Create some replacements }
1032  StaticStr:='';
1033  StripStr:='';
1034  GCSectionsStr:='';
1035  DynLinkStr:='';
1036  if (cs_link_staticflag in current_settings.globalswitches) then
1037   StaticStr:='-static';
1038  if (cs_link_strip in current_settings.globalswitches) and
1039     not(cs_link_separate_dbg_file in current_settings.globalswitches) then
1040   StripStr:='-s';
1041  if (cs_link_map in current_settings.globalswitches) then
1042   StripStr:='-Map '+maybequoted(ChangeFileExt(current_module.exefilename,'.map'));
1043  if create_smartlink_sections then
1044   GCSectionsStr:='--gc-sections';
1045  If (cs_profile in current_settings.moduleswitches) or
1046     ((Info.DynamicLinker<>'') and (not SharedLibFiles.Empty)) then
1047   begin
1048     DynLinkStr:='--dynamic-linker='+Info.DynamicLinker;
1049     if cshared then
1050       DynLinkStr:=DynLinkStr+' --shared ';
1051     if rlinkpath<>'' then
1052       DynLinkStr:=DynLinkStr+' --rpath-link '+rlinkpath;
1053   End;
1054
1055{ Write used files and libraries }
1056  WriteResponseFile(false);
1057
1058{ Call linker }
1059  SplitBinCmd(Info.ExeCmd[1],binstr,cmdstr);
1060  Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
1061  Replace(cmdstr,'$OPT',Info.ExtraOptions);
1062  Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
1063  Replace(cmdstr,'$STATIC',StaticStr);
1064  Replace(cmdstr,'$STRIP',StripStr);
1065  Replace(cmdstr,'$GCSECTIONS',GCSectionsStr);
1066  Replace(cmdstr,'$DYNLINK',DynLinkStr);
1067
1068  { create dynamic symbol table? }
1069  if HasExports then
1070    cmdstr:=cmdstr+' -E';
1071
1072  success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
1073
1074  { Create external .dbg file with debuginfo }
1075  if success and (cs_link_separate_dbg_file in current_settings.globalswitches) then
1076    begin
1077      for i:=1 to 3 do
1078        begin
1079          SplitBinCmd(Info.ExtDbgCmd[i],binstr,cmdstr);
1080          Replace(cmdstr,'$EXE',maybequoted(current_module.exefilename));
1081          Replace(cmdstr,'$DBGFN',maybequoted(extractfilename(current_module.dbgfilename)));
1082          Replace(cmdstr,'$DBG',maybequoted(current_module.dbgfilename));
1083          success:=DoExec(FindUtil(utilsprefix+BinStr),CmdStr,true,false);
1084          if not success then
1085            break;
1086        end;
1087    end;
1088
1089  { Remove ReponseFile }
1090  if (success) and not(cs_link_nolink in current_settings.globalswitches) then
1091   DeleteFile(outputexedir+Info.ResName);
1092
1093  MakeExecutable:=success;   { otherwise a recursive call to link method }
1094end;
1095
1096
1097Function TLinkerLinux.MakeSharedLibrary:boolean;
1098var
1099  InitStr,
1100  FiniStr,
1101  SoNameStr : string[80];
1102  binstr,
1103  cmdstr  : TCmdStr;
1104  success : boolean;
1105begin
1106  MakeSharedLibrary:=false;
1107  if not(cs_link_nolink in current_settings.globalswitches) then
1108   Message1(exec_i_linking,current_module.sharedlibfilename);
1109
1110{ Write used files and libraries }
1111  WriteResponseFile(true);
1112
1113 { Create some replacements }
1114 { note: linux does not use exportlib.initname/fininame due to the custom startup code }
1115  InitStr:='-init FPC_SHARED_LIB_START';
1116  FiniStr:='-fini FPC_LIB_EXIT';
1117  SoNameStr:='-soname '+ExtractFileName(current_module.sharedlibfilename);
1118
1119{ Call linker }
1120  SplitBinCmd(Info.DllCmd[1],binstr,cmdstr);
1121  Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
1122  Replace(cmdstr,'$OPT',Info.ExtraOptions);
1123  Replace(cmdstr,'$RES',maybequoted(outputexedir+Info.ResName));
1124  Replace(cmdstr,'$INIT',InitStr);
1125  Replace(cmdstr,'$FINI',FiniStr);
1126  Replace(cmdstr,'$SONAME',SoNameStr);
1127  success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
1128
1129{ Strip the library ? }
1130  if success and (cs_link_strip in current_settings.globalswitches) then
1131   begin
1132     { only remove non global symbols and debugging info for a library }
1133     Info.DllCmd[2]:='strip --discard-all --strip-debug $EXE';
1134     SplitBinCmd(Info.DllCmd[2],binstr,cmdstr);
1135     Replace(cmdstr,'$EXE',maybequoted(current_module.sharedlibfilename));
1136     success:=DoExec(FindUtil(utilsprefix+binstr),cmdstr,true,false);
1137   end;
1138
1139{ Remove ReponseFile }
1140  if (success) and not(cs_link_nolink in current_settings.globalswitches) then
1141   DeleteFile(outputexedir+Info.ResName);
1142
1143  MakeSharedLibrary:=success;   { otherwise a recursive call to link method }
1144end;
1145
1146{*****************************************************************************
1147                              TINTERNALLINKERLINUX
1148*****************************************************************************}
1149
1150constructor TInternalLinkerLinux.Create;
1151begin
1152  inherited Create;
1153  SetupLibrarySearchPath;
1154  SetupDynlinker(dynlinker,libctype);
1155
1156  CExeOutput:=ElfExeOutputClass;
1157  CObjInput:=TElfObjInput;
1158
1159end;
1160
1161procedure TInternalLinkerLinux.InitSysInitUnitName;
1162begin
1163  linklibc:=ModulesLinkToLibc;
1164  reorder:=linklibc and ReOrderEntries;
1165  sysinitunit:=defsinames[current_module.islibrary];
1166  prtobj:=defprtnames[current_module.islibrary];
1167
1168  if cs_profile in current_settings.moduleswitches then
1169    begin
1170      prtobj:=gprtnames[libctype];
1171      sysinitunit:=gsinames[libctype];
1172      linklibc:=true;
1173    end
1174  else if linklibc then
1175    begin
1176      prtobj:=cprtnames[libctype];
1177      sysinitunit:=csinames[libctype];
1178    end;
1179end;
1180
1181
1182const
1183  relsec_prefix:array[boolean] of TCmdStr = ('rel','rela');
1184
1185procedure TInternalLinkerLinux.DefaultLinkScript;
1186var
1187  s,s1,s2,relprefix:TCmdStr;
1188  found1,found2:boolean;
1189  linkToSharedLibs:boolean;
1190
1191  procedure AddLibraryStatement(const s:TCmdStr);
1192    var
1193      i:longint;
1194      s1,s2:TCmdStr;
1195    begin
1196      i:=pos(target_info.sharedClibext+'.',s);
1197      if (i>0) then
1198        s1:=target_info.sharedClibprefix+S
1199      else
1200        s1:=target_info.sharedClibprefix+S+target_info.sharedClibext;
1201      { TODO: to be compatible with ld search algorithm, each found file
1202        must be tested for target compatibility, incompatible ones should be skipped. }
1203      { TODO: shall we search library without suffix if one with suffix is not found? }
1204      if (not(cs_link_staticflag in current_settings.globalswitches)) and
1205         FindLibraryFile(s1,'','',s2) then
1206        LinkScript.Concat('READSTATICLIBRARY '+maybequoted(s2))
1207      { TODO: static libraries never have numeric suffix in their names }
1208      else if FindLibraryFile(s,target_info.staticClibprefix,target_info.staticClibext,s2) then
1209        LinkScript.Concat('READSTATICLIBRARY '+maybequoted(s2))
1210      else
1211        Comment(V_Error,'Import library not found for '+S);
1212    end;
1213
1214begin
1215  if cs_profile in current_settings.moduleswitches then
1216    begin
1217      if not(libctype in [glibc2,glibc21]) then
1218        AddSharedLibrary('gmon');
1219      AddSharedLibrary('c');
1220    end;
1221
1222  TElfExeOutput(exeoutput).interpreter:=stringdup(dynlinker);
1223
1224  { add objectfiles, start with prt0 always }
1225  if not (target_info.system in systems_internal_sysinit) and (prtobj<>'') then
1226    LinkScript.Concat('READOBJECT '+ maybequoted(FindObjectFile(prtobj,'',false)));
1227
1228  { try to add crti and crtbegin if linking to C }
1229  if linklibc and (libctype<>uclibc) then
1230    begin
1231      { crti.o must come first }
1232      if librarysearchpath.FindFile('crti.o',false,s) then
1233        LinkScript.Concat('READOBJECT '+maybequoted(s));
1234      { then the crtbegin* }
1235      if cs_create_pic in current_settings.moduleswitches then
1236        begin
1237          if librarysearchpath.FindFile('crtbeginS.o',false,s) then
1238            LinkScript.Concat('READOBJECT '+maybequoted(s));
1239        end
1240      else
1241        if (cs_link_staticflag in current_settings.globalswitches) and
1242          librarysearchpath.FindFile('crtbeginT.o',false,s) then
1243          LinkScript.Concat('READOBJECT '+maybequoted(s))
1244        else if librarysearchpath.FindFile('crtbegin.o',false,s) then
1245          LinkScript.Concat('READOBJECT '+maybequoted(s));
1246    end;
1247
1248  ScriptAddSourceStatements(false);
1249  { we must reorder here because the result could empty sharedlibfiles }
1250  if reorder then
1251    ExpandAndApplyOrder(SharedLibFiles);
1252
1253  { See tw9089*.pp: if more than one pure-Pascal shared libs are loaded,
1254    and none have rtld in their DT_NEEDED, then rtld cannot finalize correctly.  }
1255  if IsSharedLibrary then
1256    LinkScript.Concat('READSTATICLIBRARY '+maybequoted(dynlinker));
1257
1258  linkToSharedLibs:=(not SharedLibFiles.Empty);
1259
1260  { Symbols declared as "external 'libx.so'" are added to ImportLibraryList, library
1261    prefix/extension *not* stripped. TImportLibLinux copies these to SharedLibFiles,
1262    stripping prefixes and extensions.
1263    However extension won't be stripped if library is specified with numeric suffix
1264    (like "libpango-1.0.so.0")
1265    Libraries specified with $LINKLIB directive are directly added to SharedLibFiles
1266    and won't be present in ImportLibraryList. }
1267  while not SharedLibFiles.Empty do
1268    begin
1269      S:=SharedLibFiles.GetFirst;
1270      if (S<>'c') or reorder then
1271        AddLibraryStatement(S);
1272    end;
1273
1274  if (cs_link_staticflag in current_settings.globalswitches) or
1275    (linklibc and not reorder) then
1276    begin
1277      LinkScript.Concat('GROUP');
1278      if (cs_link_staticflag in current_settings.globalswitches) then
1279        begin
1280          AddLibraryStatement('gcc');
1281          AddLibraryStatement('gcc_eh');
1282        end;
1283      if linklibc and not reorder then
1284        AddLibraryStatement('c');
1285      LinkScript.Concat('ENDGROUP');
1286    end;
1287
1288  { objects which must be at the end }
1289  if linklibc and (libctype<>uclibc) then
1290    begin
1291      if cs_create_pic in current_settings.moduleswitches then
1292        found1:=librarysearchpath.FindFile('crtendS.o',false,s1)
1293      else
1294        found1:=librarysearchpath.FindFile('crtend.o',false,s1);
1295      found2:=librarysearchpath.FindFile('crtn.o',false,s2);
1296      if found1 then
1297        LinkScript.Concat('READOBJECT '+maybequoted(s1));
1298      if found2 then
1299        LinkScript.Concat('READOBJECT '+maybequoted(s2));
1300    end;
1301
1302   if (not IsSharedLibrary) then
1303     if (linkToSharedLibs and not linklibc) then
1304       LinkScript.Concat('ENTRYNAME _dynamic_start')
1305     else
1306       LinkScript.Concat('ENTRYNAME _start')
1307   else
1308     LinkScript.Concat('ISSHAREDLIBRARY');
1309
1310  relprefix:=relsec_prefix[ElfTarget.relocs_use_addend];
1311
1312  with LinkScript do
1313    begin
1314      Concat('HEADER');
1315      Concat('EXESECTION .interp');
1316      Concat('  OBJSECTION .interp');
1317      Concat('ENDEXESECTION');
1318      Concat('EXESECTION .note.ABI-tag');
1319      Concat('  OBJSECTION .no…

Large files files are truncated, but you can click here to view the full file