/compiler/systems/t_linux.pas
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