diff --git a/binutils-section-ordering.patch b/binutils-section-ordering.patch new file mode 100644 index 0000000..6632da6 --- /dev/null +++ b/binutils-section-ordering.patch @@ -0,0 +1,26973 @@ +diff -rupN binutils.orig/ld/NEWS binutils-2.41/ld/NEWS +--- binutils.orig/ld/NEWS 2024-05-13 13:03:48.141602288 +0100 ++++ binutils-2.41/ld/NEWS 2024-05-13 13:04:43.757681506 +0100 +@@ -1,5 +1,8 @@ + -*- text -*- + ++* Add --section-ordering-file option to add extra mapping of input ++ sections to output sections. ++ + * On RISC-V, add ld target option --[no-]check-uleb128. Should rebuild the + objects by binutils 2.42 and up if enabling the option and get warnings, + since the non-zero addend of SUB_ULEB128 shouldn't be generated from .uleb128 +diff -rupN binutils.orig/ld/NEWS.orig binutils-2.41/ld/NEWS.orig +--- binutils.orig/ld/NEWS.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/NEWS.orig 2024-05-13 13:04:08.590633292 +0100 +@@ -0,0 +1,991 @@ ++-*- text -*- ++ ++* On RISC-V, add ld target option --[no-]check-uleb128. Should rebuild the ++ objects by binutils 2.42 and up if enabling the option and get warnings, ++ since the non-zero addend of SUB_ULEB128 shouldn't be generated from .uleb128 ++ directives. ++ ++* Added --warn-execstack-objects to warn about executable stacks only when an ++ input object file requests one. Also added --error-execstack and ++ --error-rxw-segments options to convert warnings about executable stacks and ++ segments into errors. ++ ++ Also added --enable-error-execstack=[yes|no] and ++ --enable-error-rwx-segments=[yes|no] configure options to set the default for ++ converting warnings into errors. ++ ++Changes in 2.41: ++ ++* The linker now accepts a command line option of --remap-inputs ++ = to relace any input file that matches with ++ . In addition the option --remap-inputs-file= can be used to ++ specify a file containing any number of these remapping directives. ++ ++* The linker command line option --print-map-locals can be used to include ++ local symbols in a linker map. (ELF targets only). ++ ++* For most ELF based targets, if the --enable-linker-version option is used ++ then the version of the linker will be inserted as a string into the .comment ++ section. ++ ++* The linker script syntax has a new command for output sections: ASCIZ "string" ++ This will insert a zero-terminated string at the current location. ++ ++* Add command-line option, -z nosectionheader, to omit ELF section ++ header. ++ ++Changes in 2.40: ++ ++* The linker has a new command line option to suppress the generation of any ++ warning or error messages. This can be useful when there is a need to create ++ a known non-working binary. The option is -w or --no-warnings. ++ ++* ld now supports zstd compressed debug sections. The new option ++ --compress-debug-sections=zstd compresses debug sections with zstd. ++ ++* Add --enable-default-compressed-debug-sections-algorithm={zlib,zstd} ++ that selects the default compression algorithm ++ for --enable-compressed-debug-sections. ++ ++* Remove support for -z bndplt (MPX prefix instructions). ++ ++Changes in 2.39: ++ ++* The ELF linker will now generate a warning message if the stack is made ++ executable. By default this warning is not issued if the user has ++ specifically requested an executable stack via the "-z execstack" ++ command line option, but the warning can be forced via the new ++ "--warn-execstack" option. Alternatively all warnings about creating ++ an executable stack can be suppressed via the "--no-warn-execstack" ++ option. ++ ++ In addition the ELF linker will also warn if it creates a memory resident ++ segment with all three of the Read, Write and eXecute permissions set, or ++ if it creates a thread local data segment with the eXecute permission set. ++ These warnings can be disabled via --no-warn-rwx-segments option and ++ re-enabled via the --warn-rwx-segments option. ++ ++ New configure options can also control these new features: ++ ++ --enable-warn-execstack=no ++ will disable the warnings about creating an executable stack. ++ ++ --enable-warn-execstack=yes ++ will make --warn-execstack enabled by default. ++ ++ --enable-warn-rwx-segments=no ++ will make --no-warn-rwx-segments enabled by default. ++ ++ --enable-default-execstack=no ++ will stop the creation of an executable stack simply because an input file ++ is missing a .note.GNU-stack section, even on architectures where this ++ behaviour is the default. ++ ++* TYPE= is now supported in an output section description to set the ++ section type value. ++ ++* Remove (rudimentary) support for the x86-64 sub-architectures Intel L1OM and ++ Intel K1OM. ++ ++* The ELF linker now supports a new --package-metadata option that allows ++ embedding a JSON payload in accordance to the Package Metadata specification. ++ If support for libjansson is enabled at build time, the linker will use it to ++ validate the input. This can be enabled with --enable-jansson. ++ For more details, see: https://systemd.io/ELF_PACKAGE_METADATA/ ++ ++Changes in 2.38: ++ ++* Add -z pack-relative-relocs/-z no pack-relative-relocs to x86 ELF ++ linker to pack relative relocations in the DT_RELR section. ++ ++* Add support for the LoongArch architecture. ++ ++* Add -z indirect-extern-access/-z noindirect-extern-access to x86 ELF ++ linker to control canonical function pointers and copy relocation. ++ ++* Add --max-cache-size=SIZE to set the the maximum cache size to SIZE ++ bytes. ++ ++Changes in 2.37: ++ ++* arm-symbianelf support removed. ++ ++* Add -z report-relative-reloc to x86 ELF linker to report dynamic ++ relative relocations. ++ ++* Add -z start-stop-gc to disable special treatment of __start_*/__stop_* ++ references when --gc-sections. ++ ++* Add -Bno-symbolic to cancel -Bsymbolic and -Bsymbolic-functions. ++ ++Changes in 2.36: ++ ++* Add libdep plugin, for linking dependencies of static libraries that ++ were recorded by ar in the __.LIBDEP archive member. ++ ++* Add --error-handling-script= command line option to allow a helper ++ script to be invoked when an undefined symbol or a missing library is ++ encountered. This option can be suppressed via the configure time ++ switch: --enable-error-handling-script=no. ++ ++* Add -z lam-u48 to x86-64 ELF linker to generate LAM_U48 property. ++ ++* Add -z lam-u57 to x86-64 ELF linker to enerate LAM_U57 property. ++ ++* Add -z lam-u48-report=[none|warning|error] to report missing LAM_U48 ++ property. ++ ++* Add -z lam-u57-report=[none|warning|error] to report missing LAM_U57 ++ property. ++ ++* Add -z lam-report=[none|warning|error] to report missing LAM_U48 and ++ LAM_U57 properties. ++ ++* Add -z x86-64-{baseline|v[234]} to the x86 ELF linker to mark ++ x86-64-{baseline|v[234]} ISA level as needed. ++ ++* Add -z unique-symbol to avoid duplicated local symbol names. ++ ++* The creation of PE format DLLs now defaults to using a more secure set of DLL ++ characteristics. ++ ++* The linker now deduplicates the types in .ctf sections. The new ++ command-line option --ctf-share-types describes how to do this: ++ its default value, share-unconflicted, produces the most compact ++ output. ++ ++* The linker now omits the "variable section" from .ctf sections by ++ default, saving space. This is almost certainly what you want ++ unless you are working on a project that has its own analogue ++ of symbol tables that are not reflected in the ELF symtabs. ++ ++* Add support for the SHF_GNU_RETAIN ELF section flag. ++ This flag specifies that the section should not be garbage collected by the ++ linker. ++ ++Changes in 2.35: ++ ++* X86 NaCl target support is removed. ++ ++* Add ELF linker command-line options, --export-dynamic-symbol and ++ --export-dynamic-symbol-list, to make symbols dynamic. ++ ++* Add a configure option, --enable-textrel-check=[no|yes|warning|error], ++ to decide what ELF linker should do by default with DT_TEXTREL in an ++ executable or shared library. Default to yes for Linux/x86 targets. ++ ++* The -Map= command line option has been extended so that if ++ is a directory then /.map will be ++ created. ++ ++* Add a command-line option for ELF linker, --warn-textrel, to warn that ++ DT_TEXTREL is set in a position-independent executable or shared object. ++ ++* Add command-line options --enable-non-contiguous-regions and ++ --enable-non-contiguous-regions-warnings. ++ ++* Add command-line option --imagic for the pdp11-aout target to output format ++ IMAGIC (0411) for separate instruction and data spaces, and change the ++ default format option for pdp11-aout to be --omagic. ++ ++* Relative pathnames in INPUT() and GROUP() directives in linker scripts are ++ searched relative to the directory of the linker script before other search ++ paths. ++ ++* Add ELF linker command-line option `-z start-stop-visibility=...' to control ++ the visibility of synthetic `__start_SECNAME` and `__stop_SECNAME` symbols. ++ ++* Add command-line option --dependency-file to write a Make-style dependency ++ file listing the input files consulted by the linker, like the files written ++ by the compiler's -M -MP options. ++ ++Changes in 2.34: ++ ++* The ld check for "PHDR segment not covered by LOAD segment" is more ++ effective, catching cases that were wrongly allowed by previous versions of ++ ld. If you see this error it is likely you are linking with a bad linker ++ script or the binary you are building is not intended to be loaded by a ++ dynamic loader. In the latter case --no-dynamic-linker is appropriate. ++ ++* cr16c support removed. ++ ++* Add support for z80-elf. ++ ++* Add support for relocation of each byte or word of multibyte value to Z80 ++ targets. ++ ++* Add support for Zilog eZ80 (both ADL and Z80 mode) and Zilog Z180 CPUs. ++ ++Changes in 2.33: ++ ++* Add command-line option --no-print-map-discarded. ++ ++* The Cortex-A53 Erratum 843419 workaround now supports a choice of which ++ workaround to use. The option --fix-cortex-a53-843419 now takes an ++ optional argument --fix-cortex-a53-843419[=full|adr|adrp] which can be ++ used to force a particular workaround to be used. See --help for AArch64 ++ for more details. ++ ++* Add target handlers for AArch64 for ELF GNU program properties. ++ ++* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_BTI in ELF GNU program ++ properties in the AArch64 ELF linker. ++ ++* Add support for GNU_PROPERTY_AARCH64_FEATURE_1_PAC in ELF GNU program ++ properties in the AArch64 ELF linker. ++ ++* Add -z force-bti for AArch64 to enable GNU_PROPERTY_AARCH64_FEATURE_1_BTI ++ on output while warning about missing GNU_PROPERTY_AARCH64_FEATURE_1_BTI ++ on inputs and use PLTs protected with BTI. ++ ++* Add -z pac-plt for AArch64 to pick PAC enabled PLTs. ++ ++Changes in 2.32: ++ ++* Report property change in linker map file when merging GNU properties. ++ ++* Add support for the C-SKY processor series. ++ ++* -t now doesn't report members within archives, unless -t is given twice. ++ A single -t is now more useful when generating a list of files that should be ++ packaged for a linker bug report. For example: ++ gcc hello.c -save-temps -Wl,-t | xargs realpath | sort | uniq > files ++ tar cJf test.tar.xz `cat files` ++ ++Changes in 2.31: ++ ++* Speed up direct linking with DLLs for Cygwin and Mingw targets. ++ ++* Add a configure option --enable-separate-code to decide whether ++ -z separate-code should be enabled in ELF linker by default. Default ++ to yes for Linux/x86 targets. Note that -z separate-code can increase ++ disk and memory size. ++ ++Changes in 2.30: ++ ++* Add -z separate-code to generate separate code PT_LOAD segment. ++ ++* Add "-z undefs" command-line option as the inverse of the "-z defs" option. ++ ++* Add -z globalaudit command-line option to force audit libraries to be run ++ for every dynamic object loaded by an executable - provided that the loader ++ supports this functionality. ++ ++* Tighten linker script grammar around file name specifiers to prevent the use ++ of SORT_BY_ALIGNMENT and SORT_BY_INIT_PRIORITY on filenames. These would ++ previously be accepted but had no effect. ++ ++* The EXCLUDE_FILE directive can now be placed within any SORT_* directive ++ within input section lists. ++ ++Changes in 2.29: ++ ++* Support for -z shstk in the x86 ELF linker to generate ++ GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program properties. ++ ++* Add support for GNU_PROPERTY_X86_FEATURE_1_SHSTK in ELF GNU program ++ properties in the x86 ELF linker. ++ ++* Add support for GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program ++ properties in the x86 ELF linker. ++ ++* Support for -z ibtplt in the x86 ELF linker to generate IBT-enabled ++ PLT. ++ ++* Support for -z ibt in the x86 ELF linker to generate IBT-enabled ++ PLT as well as GNU_PROPERTY_X86_FEATURE_1_IBT in ELF GNU program ++ properties. ++ ++* Add support for ELF SHF_GNU_MBIND and PT_GNU_MBIND_XXX. ++ ++* Add support for ELF GNU program properties. ++ ++* Add support for the Texas Instruments PRU processor. ++ ++* When configuring for arc*-*-linux* targets the default linker emulation will ++ change if --with-cpu=nps400 is used at configure time. ++ ++* Improve assignment of LMAs to orphan sections in some edge cases where a ++ mixture of both AT>LMA_REGION and AT(LMA) are used. ++ ++* Orphan sections placed after an empty section that has an AT(LMA) will now ++ take an load memory address starting from LMA. ++ ++* Section groups can now be resolved (the group deleted and the group members ++ placed like normal sections) at partial link time either using the new linker ++ option --force-group-allocation or by placing FORCE_GROUP_ALLOCATION into the ++ linker script. ++ ++Changes in 2.28: ++ ++* The EXCLUDE_FILE linker script construct can now be applied outside of the ++ section list in order for the exclusions to apply over all input sections in ++ the list. ++ ++* Add support for the RISC-V architecture. ++ ++* The command-line option --no-eh-frame-hdr can now be used in ELF based ++ linkers to disable the automatic generation of .eh_frame_hdr sections. ++ ++* Add --in-implib= to the ARM linker to enable specifying a set of ++ Secure Gateway veneers that must exist in the output import library specified ++ by --out-implib= and the address they must have. As such, ++ --in-implib is only supported in combination with --cmse-implib. ++ ++* Extended the --out-implib= option, previously restricted to x86 PE ++ targets, to any ELF based target. This allows the generation of an import ++ library for an ELF executable, which can then be used by another application ++ to link against the executable. ++ ++Changes in 2.27: ++ ++* Add a configure option --enable-relro to decide whether -z relro should ++ be enabled in ELF linker by default. Default to yes for all Linux ++ targets except FRV, HPPA, IA64 and MIPS. Note that -z relro can increase ++ disk and memory size. ++ ++* Support for -z noreloc-overflow in the x86-64 ELF linker to disable ++ relocation overflow check. ++ ++* Add -z common/-z nocommon options for ELF targets to control whether to ++ convert common symbols to the STT_COMMON type during a relocatable link. ++ ++* Support for -z nodynamic-undefined-weak in the x86 ELF linker, which ++ avoids dynamic relocations against undefined weak symbols in executable. ++ ++* The NOCROSSREFSTO command was added to the linker script language. ++ ++* Add --no-apply-dynamic-relocs to the AArch64 linker to do not apply link-time ++ values for dynamic relocations. ++ ++Changes in 2.26: ++ ++* Add --fix-stm32l4xx-629360 to the ARM linker to enable a link-time ++ workaround for a bug in the bus matrix / memory controller for some of ++ the STM32 Cortex-M4 based products (STM32L4xx) ++ ++* Add a configure option --enable-compressed-debug-sections={all,ld} to ++ decide whether DWARF debug sections should be compressed by default. ++ ++* Add support for the ARC EM/HS, and ARC600/700 architectures. ++ ++* Experimental support for linker garbage collection (--gc-sections) ++ has been enabled for COFF and PE based targets. ++ ++* New command-line option for ELF targets to compress DWARF debug ++ sections, --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]. ++ ++* New command-line option, --orphan-handling=[place|warn|error|discard], to ++ adjust how orphan sections are handled. The default is 'place' which gives ++ the current behaviour, 'warn' and 'error' issue a warning or error ++ respectively when orphan sections are found, and 'discard' will discard all ++ orphan sections. ++ ++* Add support for LLVM plugin. ++ ++* Add --print-memory-usage option to report memory blocks usage. ++ ++* Add --require-defined option, it's like --undefined except the new symbol ++ must be defined by the end of the link. ++ ++Changes in 2.25: ++ ++* PE binaries now once again contain real timestamps by default. To disable ++ the inclusion of a timestamp in a PE binary, use the --no-insert-timestamp ++ command-line option. ++ ++* Replace support for openrisc and or32 with support for or1k. ++ ++* Add support for the --build-id command-line option to COFF based targets. ++ ++* x86/x86_64 pe-coff now supports the --build-id option. ++ ++* Add support for the Andes NDS32. ++ ++Changes in 2.24: ++ ++* Add LOG2CEIL() builtin function to the linker script language ++ ++* Add support for the Texas Instruments MSP430X processor. ++ ++* Add support for Altera Nios II. ++ ++* Add support for the V850E3V5 architecture. ++ ++* Add support for the Imagination Technologies Meta processor. ++ ++* --enable-new-dtags no longer generates old dtags in addition to new dtags. ++ ++* Remove linker support for MIPS ECOFF targets. ++ ++* Add ALIGN_WITH_INPUT to the linker script language to force the alignment of ++ an output section to use the maximum alignment of all its input sections. ++ ++Changes in 2.23: ++ ++* Enable compressed debug section feature for x86/x86_64 pe-coff. ++ ++* Add support for the 64-bit ARM architecture: AArch64. ++ ++* Added SORT_NONE to the linker script language to disable section sorting. ++ ++* Add a linker-provided symbol when producing ELF output, '__ehdr_start' ++ to point to the ELF file header (and nearby program headers) in the ++ program's memory image. ++ ++* Add support for S12X processor. ++ ++* Add support for the VLE extension to the PowerPC architecture. ++ ++* Add support for the Freescale XGATE architecture. ++ ++* Add option -f FILE on AIX (for response file). ++ ++* Add support for the Renesas RL78 architecture. ++ ++* Add support for the Adapteva EPIPHANY architecture. ++ ++Changes in 2.22: ++ ++* --copy-dt-needed-entries is no longer enabled by default. Instead ++ --no-copy-dt-needed-entries is the default. ++ ++* INPUT_SECTION_FLAGS has been added to the linker script language ++ to allow selection of input sections by section header section flags. ++ ++* Add support for the Tilera TILEPro and TILE-Gx architectures. ++ ++* Added SORT_BY_INIT_PRIORITY to the linker script language to permit ++ sorting sections by numerical value of the GCC init_priority attribute ++ encoded in the section name. ++ ++Changes in 2.21: ++ ++* Linker script expression evaluation is somewhat more sane. This may ++ break scripts that depend on quirks of the old expression evaluation. ++ ++* Turn off underscoring for x86_64 PE+-COFF targets. For old behavior the ++ option --enable-leading-mingw64-underscores can be used on configure of ++ bfd. ++ ++* Add support for the TMS320C6000 (TI C6X) processor family. ++ ++* --add-needed renamed to --copy-dt-needed-entries in order to avoid confusion ++ with --as-needed option. ++ ++* Extend .def file syntax by '== ' for imports and exports. This allows ++ to alias the import/export table name written in PE image. ++ ++* Add --exclude-all-symbols option to PE based linkers. This prevents all ++ symbols from automatically being exported. ++ ++* Add support for the Renesas RX processor. ++ ++* Add support for alpha-vms target. ++ ++Changes in 2.20: ++ ++* GNU/Linux targets now support the STB_GNU_UNIQUE symbol binding. This is a ++ GNU extension to the standard set of ELF symbol bindings. The binding will ++ be passed on to the dynamic linker which will make sure that in the entire ++ process there is just one symbol with the given name and type in use. ++ ++* PE targets now support a GNU extension to allow the alignment of common ++ common symbols to be specified. This support uses custom options in ++ the .drectve section, which will be disregarded by the native tools. ++ ++* PE targets now add primitive support for ELF version scripts; symbols ++ are not versioned, but the local and global symbol visibility directives ++ are respected when filtering symbols in auto-export mode. ++ ++* New option --no-export-dynamic to undo the effect of the -E and ++ --export-dynamic options. ++ ++* ELF: --warn-alternate-em option to warn if an object has alternate ++ ELF machine code. ++ ++* New script function REGION_ALIAS to add alias names to memory regions. ++ ++* PE targets no longer make use of the long section names PE extension to ++ the COFF format when generating executable images, by default. The old ++ (slightly non-conformant) behaviour can still be invoked by using the ++ new '--enable-long-section-names' command-line option. It is also enabled ++ automatically in the presence of un-stripped debug information, as GDB ++ needs to be able to find the debug info sections by their full names. ++ ++* For GNU/Linux systems the linker will now avoid processing any relocations ++ made against symbols of the STT_GNU_IFUNC type and instead emit them into ++ the resulting binary for processing by the loader. ++ ++* --as-needed now links in a dynamic library if it satisfies undefined ++ symbols in regular objects, or in other dynamic libraries. In the ++ latter case the library is not linked if it is found in a DT_NEEDED ++ entry of one of the libraries already linked. ++ ++* Add a new command-line option, -Ttext-segment ADDR, for ELF targets ++ to set the address of the first byte of the text segment. ++ ++* Add support for Sunplus score architecture. ++ ++* Add new option --use-nul-prefixed-import-tables to ld for PE targets to ++ allow fallback to old import table generation with null element prefix. ++ ++* Windows PE systems now support a new --exclude-modules-for-implib option, ++ allowing users to partition object files and archive members between a DLL ++ and its associated import library as they are generated during linking. ++ ++* Add support for Lattice Mico32 (lm32) architecture. ++ ++* Add CR16 ELF --embedded-relocs (used to embedded relocations into binaries ++ for Embedded-PIC code) option. ++ ++* Add to the PE/PE+ targets the support of two different kinds of ++ pseudo-relocations. They can be selected by the switches ++ --enable-runtime-pseudo-reloc-v1 and --enable-runtime-pseudo-reloc-v2. ++ For the switch --enable-runtime-pseudo-reloc it uses for 32-bit ++ runtime pseudo relocation version one, for 64-bit the version two. ++ ++Changes in 2.19: ++ ++* Linker scripts support a new INSERT command that makes it easier to ++ augment the default script. ++ ++* Linker script input section filespecs may now specify a file within an ++ archive by writing "archive:file". ++ ++* The --sort-common switch now has an optional argument which specifies the ++ direction of sorting. ++ ++* The M68K linker now supports multiple GOT generation schemes controlled via ++ the --got= command-line option. ++ ++* The ARM EABI linker will now generate stubs for function calls to symbols ++ that are too far away. The placement of the stubs is controlled by a new ++ linker command-line option: --stub-group-size=N. ++ ++Changes in 2.18: ++ ++* Linker sources now released under version 3 of the GNU General Public ++ License. ++ ++* ELF: New --build-id option to generate a unique per-binary identifier ++ embedded in a note section. ++ ++* Added support for National Semicondutor CompactRISC (ie CR16) target. ++ ++* -l:foo now searches the library path for a filename called foo, ++ without converting it to libfoo.a or libfoo.so. ++ ++* Add a new command-line option '--default-script=FILE' or '-dT FILE' ++ which specifies a replacement for the built in, default linker ++ script. ++ ++* ELF: Add -Bsymbolic-functions, --dynamic-list-cpp-new, which puts C++ ++ operator new and delete on the dynamic list, and --dynamic-list-data, ++ builtin list for --dynamic-list, which puts global data symbols on the ++ dynamic list. ++ ++* Add support for x86_64 PE+ target. ++ ++* Add support for Score target. ++ ++* ELF: Add --dynamic-list option to specify a list of global symbols ++ whose references shouldn't be bound to the definition within the ++ shared library, or a list of symbols which should be added to the ++ symbol table in the executable. ++ ++* The default output section LMA has changed for allocatable sections from ++ being equal to VMA, to keeping the difference between LMA and VMA the same as ++ the previous output section in the same region. This is a more useful ++ default when using overlays and other cases where you specify an LMA ++ differing from the VMA for some sections. ++ ++* New switch: --print-gc-sections to list any sections removed by garabge ++ collection. ++ ++* ARM: Added --vfp11-denorm-fix option to work around an erratum in current ++ VFP11 coprocessors. ++ ++Changes in 2.17: ++ ++* Support for the Infineon XC16X has been added by KPIT Cummins Infosystems. ++ ++* Modify the Linux linker search order to better match ld.so search order. ++ Look for DT_NEEDED libraries in paths specified by ld.so.conf before ++ searching the default directories, rather than vice versa. ++ Use $prefix/etc/ld.so.conf if it exists, otherwise /etc/ld.so.conf. ++ ++* PE-COFF: Forward exports from DLL's can now be specified in .def files ++ passed directly to ld. ++ ++* Support for the Z80 processor family has been added. ++ ++* Add support for the "@" syntax to the command line, so that extra ++ switches can be read from . ++ ++Changes in 2.16: ++ ++* Support for the R_ARM_V4BX relocation as defined in the ARM AAELF ++ specification has been added via the --fix-v4bx command-line option. ++ ++* New linker script construct AS_NEEDED(), which sets the --as-needed flag ++ for input files listed inside of it. ++ ++* A new command-line option, --sysroot, can be used to override the ++ default sysroot location. It only applies to toolchains that were ++ configured using --with-sysroot. ++ ++* New linker script functions: ORIGIN() and LENGTH() which return information ++ about a specified memory region. ++ ++* Port to MAXQ processor contributed by HCL Tech. ++ ++* Added SEGMENT_START to the linker script language to permit the user to ++ override the base address for a segment from the command-line. ++ ++* ELF: --warn-shared-textrel option to warn if adding a DT_TEXTREL to a shared ++ object. ++ ++* Added SORT_BY_NAME and SORT_BY_ALIGNMENT to the linker script ++ language to permit sorting sections by section name or section ++ maximum alignment. ++ ++* Added a new linker command-line switch, --sort-section name|alignment, ++ to sort sections by section name or maximum alignment. ++ ++* ELF: --add-needed/--no-add-needed options to control if a DT_NEEDED tag ++ should be added when a shared library comes from DT_NEEDED tags. ++ ++* Support for the crx-elf target added. ++ ++* Support for the sh-symbianelf target added. ++ ++* A new linker command-line switch has been added which allows the hash table ++ size to be set to a suitable prime value near to its argument. This switch ++ is --hash-size=. Also if the switch --reduce-memory-overheads is ++ used, and --hash-size has not been used, then the default value will be set ++ to 1021. ++ ++* Linker map files are now generated with an O(N) algorithm for finding symbols ++ that are defined in each section. This uses about 40% more memory for ++ symbols than the old O(N^2) algorithm. You can use the new ++ --reduce-memory-overheads option to select the old algorithm; this option ++ might also be used in the future to select similar tradeoffs. ++ ++Changes in 2.15: ++ ++* ELF: --as-needed/--no-as-needed options to control if a DT_NEEDED tag should ++ be added only when a shared library is referenced. ++ ++* PE: --large-address-aware option to indicate executables support virtual ++ addresses greater than 2 gigabytes. ++ ++* DWARF 2 support for i386pe added. ++ ++* The linker script operator DEFINED() will now yield 1 only for a symbol that ++ is defined before the statement where DEFINED is used. ++ ++* The MIPS --embedded-relocs (used to embed relocations into binaries for ++ Embedded-PIC code) is deprecated and will be removed in a future release. ++ ++* cr16c support added by NSC. ++ ++* m32r Linux (ELF) support added by Renesas. ++ ++* Improved linker's handling of unresolved symbols. The switch ++ --unresolved-symbols= has been added to tell the linker when it ++ should report them and the switch --warn-unresolved-symbols has been added to ++ make reports be issued as warning messages rather than errors. ++ ++Changes in 2.14: ++ ++* Added support for Xtensa architecture. ++ ++* Added --with-sysroot configure switch to specify a target system root, for ++ linking against a target filesystem image. ++ ++* Added --accept-unknown-linker-format to restore old linker behaviour (pre ++ 2.14) of silently accepting and linking in any files in an unknown binary ++ file format. ++ ++* Added --no-omagic to undo the effects of the -N option. ++ ++* Support for Texas Instruments TMS320C4x and TMS320C3x series of ++ DSP's contributed by Michael Hayes and Svein E. Seldal. ++ ++* Added --with-lib-path configure switch to specify default value for ++ LIB_PATH. ++ ++* ARM port to QNX operating system added by Graeme Peterson. ++ ++* IP2K support added by Denis Chertykov. ++ ++Changes in 2.13: ++ ++* Support for the Fujitsu FRV architecture added by Red Hat. Models for FR400 ++ and FR500 included. ++ ++Changes in version 2.13: ++ ++* DEC VAX ELF support, by Matt Thomas. ++ ++Changes in version 2.12: ++ ++* Support for Don Knuth's MMIX, by Hans-Peter Nilsson. ++ ++* Support for the OpenRISC 32-bit embedded processor by OpenCores. ++ ++* Support for -z nocopyreloc in the x86 ELF linker, which disables ++ production of copy relocs. Warning: using this option may result in ++ non-sharable applications. ++ ++* Support for -z combreloc in the ELF linker, which puts dynamic ++ relocations against the same symbol together, so that dynamic linker ++ can use an one-entry symbol lookup cache. ++ ++* Support for ELF SHF_MERGE section merging, by Jakub Jelinek. ++ ++Changes in version 2.11: ++ ++* Support for AMD x86-64 architecture, by Jan Hubicka, SuSE Labs. ++ ++* Support added for eliminating duplicate DWARF2 debug information by ++ having the compiler generate the information in sections called ++ .gnu.linkonce.wi.XXXX where XXXX is a checksum for the contents. The ++ linker then merges these sections together into the normal .debug_info ++ section. ++ ++* The native ELF linker now searches the directories in DT_RUNPATH or ++ DT_RPATH of a shared library for shared libraries needed by it. ++ ++* TI C54x support, by Timothy Wall. ++ ++* Added command-line switch --section-start to set the start address of any ++ specified section. ++ ++* Added ability to emit full relocation information in linked executables, ++ enabled by --emit-relocs. Some post-linkage optimization tools need ++ this information in order to be able to correctly identify and perform ++ symbol relative addressing in the event of changes in section contents ++ (instructions being added or deleted, extending data sections, etc.) ++ ++* Support for i860, by Jason Eckhardt (preliminary, alpha quality). ++ ++* Support for CRIS (Axis Communications ETRAX series). ++ ++* Support for PDP-11 and 2.11BSD a.out format, by Lars Brinkhoff. ++ ++Changes in version 2.10: ++ ++* Added AT> to the linker script language to allow load-time allocation of ++ sections into regions. ++ ++* Added garbage collection of unused sections, enabled by --gc-sections. ++ It does require a bit of backend support; currently implemented are ++ arm-elf, avr-elf, d10v-elf, fr30-elf, i386-elf, m32r-elf, m68k-elf, ++ mcore-elf, mips-elf, mn10300-elf, ppc-elf, sh-elf, sparc-elf, and v850-elf. ++ Others will ignore the option. ++ ++* Added SORT to the linker script language to permit sorting sections by file ++ name or section name. ++ ++* Added EXTERN to the linker script language as an equivalent to the -u ++ command-line option. ++ ++* Added ASSERT to the linker script language. ++ ++* Added EXCLUDE_FILE to the linker script language for further control over ++ wildcard file names. ++ ++* Added -O option to optimize linker output (as of this writing, this only ++ affects ELF shared library generation). ++ ++* The -e option now accepts a number as well as a symbol name. ++ ++* Added --no-undefined option to disallow undefined symbols when creating a ++ shared library. ++ ++* The linker now issues a warning, not an error, for an undefined symbol when ++ using -Bsymbolic; use the new --no-undefined option to get the old ++ behaviour. ++ ++* Added --demangle and --no-demangle options. ++ ++Changes in version 2.9: ++ ++* Added SQUAD to the linker script language. ++ ++* New option --no-warn-mismatch. ++ ++* The MEMORY command now parses the attributes to determine where sections that ++ are not placed in a specific memory region are placed. ++ ++Changes in version 2.8: ++ ++* Linker scripts may now contain shell wildcard characters for file and section ++ names. ++ ++* The linker now supports symbol versions in ELF. ++ ++* The NOCROSSREFS command was added to the linker script language. ++ ++* The LOADADDR expression was added to the linker script language. ++ ++* MAX and MIN functions were added to the linker script language. ++ ++* The OVERLAY construct was added to the linker script language. ++ ++* New option --warn-section-align to warn when the address of an output section ++ changes due to alignment of an input section. ++ ++* New options --filter/-F and --auxiliary/-f. ++ ++Changes in version 2.7: ++ ++* New option --cref to print out a cross reference table. ++ ++* New option --wrap SYMBOL. ++ ++* New option --no-whole-archive, to turn off the effect of --whole-archive. ++ ++* Input sections assigned to the output section /DISCARD/ in the linker script ++ are not included in the output file. ++ ++* The SunOS and ELF linkers now merge stabs debugging information which uses ++ the N_BINCL and N_EINCL stab types. This reduces the amount of debugging ++ information generated. ++ ++Changes in version 2.6: ++ ++* When an ELF section name is representable as a C identifier (this is not true ++of most ELF section names), the linker will automatically define symbols ++__start_SECNAME and __stop_SECNAME, where SECNAME is the section name, at the ++beginning and the end of the section. This is used by glibc. ++ ++ Addendum: Current versions of the linker (at least for version 2.18 onwards ++and possibly much earlier as well) place two restrictions on this feature: The ++symbols are only implemented for orphaned sections, not for explicitly placed ++sections and they are PROVIDEd rather than being defined. ++ ++* When an ELF section named .gnu.warning is encountered in an input file, the ++contents of the section are displayed as an error message, and the section is ++not copied into the output file. This is used by glibc. ++ ++* When an ELF section named .gnu.warning.SYMBOL is encountered in an input ++file, and the symbol SYMBOL is referenced by some object file, the contents of ++the section are displayed as an error message. The section is not copied into ++the output file, unless doing a relocatable or shared link. This is used by ++glibc. ++ ++* New options -split-by-reloc and -split-by-file. ++ ++* The linker now supports linking PIC compiled code on SPARC SunOS. It can ++also create SPARC SunOS shared libraries, and, like the native SunOS linker, ++will do so whenever there is an undefined symbol in the link and neither the -e ++nor the -r option was used. ++ ++* The -rpath option may be used on SunOS to set the list of directories to be ++searched at run time. This overrides the default of building the list from the ++-L options. ++ ++* The COFF linker now combines debugging information for structs, unions, and ++enums, so that even if the same type is defined in multiple input files it will ++only be defined once in the output file. The --traditional-format switch will ++prevent this optimization. ++ ++Changes in version 2.5: ++ ++* The linker now supports linking against SunOS shared libraries. It still can ++not link SunOS PIC (Position Independent Code) files, so it can not be used to ++generate shared libraries. ++ ++* The linker now supports linking against ELF shared libraries for the i386 ++(UnixWare) and SPARC (Solaris). It can also link ELF PIC files, and can be ++used to generate shared libraries. Shared library generation is not well ++tested; please report any problems encountered. The linker is now enabled for ++Solaris again. ++ ++* Eric Youngdale has contributed Linux support code, including linking against ++Linux a.out shared libraries. The linker produces Linux QMAGIC binaries. ++ ++* The ELF backend has been converted to the new linker code. To use the new ++ELF linker, each particular target requires a relocation function. So far, ++this function has been written for i386 (UnixWare), SPARC (Solaris) MIPS (Irix ++5), and HPPA ELF targets. ++ ++* The -( (--start-group) and -) (--end-group) options have been added to ++support searching a group of archives as though they were a single archive. ++This can also be used in a linker script, as GROUP ( files ). ++ ++* When a file is named on the command line, and the linker does not recognize ++it as an object file, the linker will now treat the file as a linker script ++file. A linker script named in this way augments, but does not replace, the ++default linker script. ++ ++* The -warn-once option was added. It causes the linker to only warn once per ++undefined symbol, rather than once per reference. ++ ++* The COFF backend has been converted to the new linker code. As with ELF, to ++use the new linker, each particular target requires a relocation function. So ++far, this function has been written for the i386, m68k, a29k and SH targets. ++ ++* The -V flag was made a synonym for -v, for SVR4 compatibility. The old -V ++behaviour is available via --verbose. ++ ++Changes in version 2.4: ++ ++* New linker code, by Steve Chamberlain and Ian Taylor. For a.out and ecoff ++ formats (so far), this should result in considerable savings in time ++ and memory used while linking; slightly poorer performance than ++ before for formats not converted yet. ++ ++* Command-line parsing is no longer done with flex. This means ++ oddball characters in filenames won't get treated as argument ++ separators. ++ ++* HP-PA ELF support, by Jeff Law. (No SOM support yet.) ++ ++* Mach i386 support, by David Mackenzie. ++ ++* Irix 4 shared libraries are now supported (Irix 5 uses ELF, and ELF shared ++ libraries are not yet supported). ++ ++* COFF shared libraries (as on SCO) should work as well. ++ ++* The linker is disabled for Solaris. (Actually, it was in 2.3 also, I just ++ forgot to note it.) Some of their C library routines don't work when ++ statically linked, and the GNU linker doesn't support dynamic linking yet. ++ ++Changes in version 2.3: ++ ++* Weak symbols are now supported. ++ ++* ELF support has been added. The linker has been bootstrapped on ++ UnixWare and Solaris. ++ ++* Alpha OSF/1 support has been added (non dynamic linking only). ++ ++Changes in version 2.2: ++ ++* The `bfd' library has been updated to reduce a.out-format string ++ table size. The effect of this is that files linked from many input ++ files with duplicate symbols (`-g' debugging records, or identical ++ static symbols) should be much smaller. ++ ++Changes in version 2.1: ++ ++* The ld -ySYMBOL flag (to trace references to SYMBOL) is now implemented. ++ ++* There is now support for writing ECOFF files, so ld and the ++ other utilities should work on Risc/Ultrix and Irix. ++ ++ ++Copyright (C) 2012-2023 Free Software Foundation, Inc. ++ ++Copying and distribution of this file, with or without modification, ++are permitted in any medium without royalty provided the copyright ++notice and this notice are preserved. ++ ++Local variables: ++fill-column: 79 ++End: +diff -rupN binutils.orig/ld/NEWS.rej binutils-2.41/ld/NEWS.rej +--- binutils.orig/ld/NEWS.rej 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/NEWS.rej 2024-05-13 13:04:08.590633292 +0100 +@@ -0,0 +1,11 @@ ++--- ld/NEWS +++++ ld/NEWS ++@@ -1,5 +1,8 @@ ++ -*- text -*- ++ +++* Add --section-ordering-file option to add extra mapping of input +++ sections to output sections. +++ ++ * Add -plugin-save-temps to store plugin intermediate files permanently. ++ ++ Changes in 2.42: +diff -rupN binutils.orig/ld/ld.h binutils-2.41/ld/ld.h +--- binutils.orig/ld/ld.h 2024-05-13 13:03:47.798601768 +0100 ++++ binutils-2.41/ld/ld.h 2024-05-13 13:04:08.591633294 +0100 +@@ -193,6 +193,9 @@ typedef struct + + /* Default linker script. */ + char *default_script; ++ ++ /* Linker script fragment provided by the --section-order command line option. */ ++ char *section_ordering_file; + } args_type; + + extern args_type command_line; +@@ -319,6 +322,7 @@ extern ld_config_type config; + + extern FILE * saved_script_handle; + extern bool force_make_executable; ++extern bool in_section_ordering; + + extern int yyparse (void); + extern void add_cref (const char *, bfd *, asection *, bfd_vma); +diff -rupN binutils.orig/ld/ld.h.orig binutils-2.41/ld/ld.h.orig +--- binutils.orig/ld/ld.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ld.h.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,338 @@ ++/* ld.h -- general linker header file ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifndef LD_H ++#define LD_H ++ ++#ifndef SEEK_CUR ++#define SEEK_CUR 1 ++#endif ++#ifndef SEEK_END ++#define SEEK_END 2 ++#endif ++ ++#ifndef ENABLE_NLS ++ /* The Solaris version of locale.h always includes libintl.h. If we have ++ been configured with --disable-nls then ENABLE_NLS will not be defined ++ and the dummy definitions of bindtextdomain (et al) below will conflict ++ with the defintions in libintl.h. So we define these values to prevent ++ the bogus inclusion of libintl.h. */ ++# define _LIBINTL_H ++# define _LIBGETTEXT_H ++#endif ++#include ++ ++#ifdef ENABLE_NLS ++# include ++# define _(String) gettext (String) ++# ifdef gettext_noop ++# define N_(String) gettext_noop (String) ++# else ++# define N_(String) (String) ++# endif ++#else ++# define gettext(Msgid) (Msgid) ++# define dgettext(Domainname, Msgid) (Msgid) ++# define dcgettext(Domainname, Msgid, Category) (Msgid) ++# define ngettext(Msgid1, Msgid2, n) \ ++ (n == 1 ? Msgid1 : Msgid2) ++# define dngettext(Domainname, Msgid1, Msgid2, n) \ ++ (n == 1 ? Msgid1 : Msgid2) ++# define dcngettext(Domainname, Msgid1, Msgid2, n, Category) \ ++ (n == 1 ? Msgid1 : Msgid2) ++# define textdomain(Domainname) do {} while (0) ++# define bindtextdomain(Domainname, Dirname) do {} while (0) ++# define _(String) (String) ++# define N_(String) (String) ++#endif ++ ++/* Look in this environment name for the linker to pretend to be */ ++#define EMULATION_ENVIRON "LDEMULATION" ++/* If in there look for the strings: */ ++ ++/* Look in this variable for a target format */ ++#define TARGET_ENVIRON "GNUTARGET" ++ ++/* Input sections which are put in a section of this name are actually ++ discarded. */ ++#define DISCARD_SECTION_NAME "/DISCARD/" ++ ++/* A file name list. */ ++typedef struct name_list ++{ ++ const char *name; ++ struct name_list *next; ++} ++name_list; ++ ++typedef enum {sort_none, sort_ascending, sort_descending} sort_order; ++ ++/* A wildcard specification. */ ++ ++typedef enum ++{ ++ none, by_name, by_alignment, by_name_alignment, by_alignment_name, ++ by_none, by_init_priority ++} sort_type; ++ ++extern sort_type sort_section; ++ ++struct wildcard_spec ++{ ++ const char *name; ++ struct name_list *exclude_name_list; ++ struct flag_info *section_flag_list; ++ size_t namelen, prefixlen, suffixlen; ++ sort_type sorted; ++}; ++ ++struct wildcard_list ++{ ++ struct wildcard_list *next; ++ struct wildcard_spec spec; ++}; ++ ++#define BYTE_SIZE (1) ++#define SHORT_SIZE (2) ++#define LONG_SIZE (4) ++#define QUAD_SIZE (8) ++ ++enum endian_enum { ENDIAN_UNSET = 0, ENDIAN_BIG, ENDIAN_LITTLE }; ++ ++typedef struct ++{ ++ /* 1 => assign space to common symbols even if `relocatable_output'. */ ++ bool force_common_definition; ++ ++ /* If TRUE, build MIPS embedded PIC relocation tables in the output ++ file. */ ++ bool embedded_relocs; ++ ++ /* If TRUE, force generation of a file with a .exe file. */ ++ bool force_exe_suffix; ++ ++ /* If TRUE, generate a cross reference report. */ ++ bool cref; ++ ++ /* If TRUE (which is the default), warn about mismatched input ++ files. */ ++ bool warn_mismatch; ++ ++ /* Warn on attempting to open an incompatible library during a library ++ search. */ ++ bool warn_search_mismatch; ++ ++ /* If non-zero check section addresses, once computed, ++ for overlaps. Relocatable links only check when this is > 0. */ ++ signed char check_section_addresses; ++ ++ /* If TRUE allow the linking of input files in an unknown architecture ++ assuming that the user knows what they are doing. This was the old ++ behaviour of the linker. The new default behaviour is to reject such ++ input files. */ ++ bool accept_unknown_input_arch; ++ ++ /* Name of the import library to generate. */ ++ char *out_implib_filename; ++ ++ /* If TRUE we'll just print the default output on stdout. */ ++ bool print_output_format; ++ ++ /* If set, display the target memory usage (per memory region). */ ++ bool print_memory_usage; ++ ++ /* Should we force section groups to be resolved? Controlled with ++ --force-group-allocation on the command line or FORCE_GROUP_ALLOCATION ++ in the linker script. */ ++ bool force_group_allocation; ++ ++ /* Big or little endian as set on command line. */ ++ enum endian_enum endian; ++ ++ /* Name of runtime interpreter to invoke. */ ++ char *interpreter; ++ ++ /* Name to give runtime library from the -soname argument. */ ++ char *soname; ++ ++ /* Runtime library search path from the -rpath argument. */ ++ char *rpath; ++ ++ /* Link time runtime library search path from the -rpath-link ++ argument. */ ++ char *rpath_link; ++ ++ /* Name of shared object whose symbol table should be filtered with ++ this shared object. From the --filter option. */ ++ char *filter_shlib; ++ ++ /* Name of shared object for whose symbol table this shared object ++ is an auxiliary filter. From the --auxiliary option. */ ++ char **auxiliary_filters; ++ ++ /* A version symbol to be applied to the symbol names found in the ++ .exports sections. */ ++ char *version_exports_section; ++ ++ /* Default linker script. */ ++ char *default_script; ++} args_type; ++ ++extern args_type command_line; ++ ++typedef int token_code_type; ++ ++/* Different ways we can handle orphan sections. */ ++ ++enum orphan_handling_enum ++{ ++ /* The classic strategy, find a suitable section to place the orphan ++ into. */ ++ orphan_handling_place = 0, ++ ++ /* Discard any orphan sections as though they were assign to the section ++ /DISCARD/. */ ++ orphan_handling_discard, ++ ++ /* Find somewhere to place the orphan section, as with ++ ORPHAN_HANDLING_PLACE, but also issue a warning. */ ++ orphan_handling_warn, ++ ++ /* Issue a fatal error if any orphan sections are found. */ ++ orphan_handling_error, ++}; ++ ++typedef struct ++{ ++ bool magic_demand_paged; ++ bool make_executable; ++ ++ /* If TRUE, -shared is supported. */ ++ /* ??? A better way to do this is perhaps to define this in the ++ ld_emulation_xfer_struct since this is really a target dependent ++ parameter. */ ++ bool has_shared; ++ ++ /* If TRUE, build constructors. */ ++ bool build_constructors; ++ ++ /* If TRUE, warn about any constructors. */ ++ bool warn_constructors; ++ ++ /* If TRUE, warn about merging common symbols with others. */ ++ bool warn_common; ++ ++ /* If TRUE, only warn once about a particular undefined symbol. */ ++ bool warn_once; ++ ++ /* How should we deal with orphan sections. */ ++ enum orphan_handling_enum orphan_handling; ++ ++ /* If TRUE, warn if multiple global-pointers are needed (Alpha ++ only). */ ++ bool warn_multiple_gp; ++ ++ /* If TRUE, warn if the starting address of an output section ++ changes due to the alignment of an input section. */ ++ bool warn_section_align; ++ ++ /* If TRUE, warning messages are fatal. */ ++ bool fatal_warnings; ++ ++ /* If TRUE, warning and error messages are ignored. */ ++ bool no_warnings; ++ ++ sort_order sort_common; ++ ++ bool text_read_only; ++ ++ bool stats; ++ ++ /* If set, orphan input sections will be mapped to separate output ++ sections. */ ++ bool unique_orphan_sections; ++ ++ /* If set, only search library directories explicitly selected ++ on the command line. */ ++ bool only_cmd_line_lib_dirs; ++ ++ /* If set, numbers and absolute symbols are simply treated as ++ numbers everywhere. */ ++ bool sane_expr; ++ ++ /* If set, code and non-code sections should never be in one segment. */ ++ bool separate_code; ++ ++ /* If set, generation of ELF section header should be suppressed. */ ++ bool no_section_header; ++ ++ /* The rpath separation character. Usually ':'. */ ++ char rpath_separator; ++ ++ char *map_filename; ++ FILE *map_file; ++ ++ char *dependency_file; ++ ++ unsigned int split_by_reloc; ++ bfd_size_type split_by_file; ++ ++ /* The size of the hash table to use. */ ++ unsigned long hash_table_size; ++ ++ /* If set, print discarded sections in map file output. */ ++ bool print_map_discarded; ++ ++ /* If set, print local symbols in map file output. */ ++ bool print_map_locals; ++ ++ /* If set, emit the names and types of statically-linked variables ++ into the CTF. */ ++ bool ctf_variables; ++ ++ /* If set, share only duplicated types in CTF, rather than sharing ++ all types that are not in conflict. */ ++ bool ctf_share_duplicated; ++ ++ /* Compress DWARF debug sections. */ ++ enum compressed_debug_section_type compress_debug; ++} ld_config_type; ++ ++extern ld_config_type config; ++ ++extern FILE * saved_script_handle; ++extern bool force_make_executable; ++ ++extern int yyparse (void); ++extern void add_cref (const char *, bfd *, asection *, bfd_vma); ++extern bool handle_asneeded_cref (bfd *, enum notice_asneeded_action); ++extern void output_cref (FILE *); ++extern void check_nocrossrefs (void); ++extern void ld_abort (const char *, int, const char *) ATTRIBUTE_NORETURN; ++ ++/* If gcc >= 2.6, we can give a function name, too. */ ++#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) ++#define __PRETTY_FUNCTION__ NULL ++#endif ++ ++#undef abort ++#define abort() ld_abort (__FILE__, __LINE__, __PRETTY_FUNCTION__) ++ ++#endif +diff -rupN binutils.orig/ld/ld.texi binutils-2.41/ld/ld.texi +--- binutils.orig/ld/ld.texi 2024-05-13 13:03:48.141602288 +0100 ++++ binutils-2.41/ld/ld.texi 2024-05-13 13:04:08.594633298 +0100 +@@ -301,6 +301,7 @@ and the script command language. If @em + are specified, the linker does not produce any output, and issues the + message @samp{No input files}. + ++@anchor{unrecognised-input-files} + If the linker cannot recognize the format of an object file, it will + assume that it is a linker script. A script specified in this way + augments the main linker script used for the link (either the default +@@ -1146,18 +1147,32 @@ a linker bug report. + @itemx --script=@var{scriptfile} + Use @var{scriptfile} as the linker script. This script replaces + @command{ld}'s default linker script (rather than adding to it), +-unless the script contains @code{INSERT}, so +-@var{commandfile} must specify everything necessary to describe the +-output file. @xref{Scripts}. If @var{scriptfile} does not exist in +-the current directory, @code{ld} looks for it in the directories +-specified by any preceding @samp{-L} options. Multiple @samp{-T} +-options accumulate. ++unless the script contains @code{INSERT}, so @var{commandfile} must ++specify everything necessary to describe the output file. ++@xref{Scripts}. ++ ++If @var{scriptfile} does not exist in the current directory, @code{ld} ++looks for it in the directories specified by any preceding @samp{-L} ++options. ++ ++Command line options that appear before the @option{-T} option can ++affect the script, but command line options that appear after it do ++not. ++ ++Multiple @samp{-T} options will accumulate if they are augmenting the ++current script, otherwise the last, non-augmenting, @option{-T} option ++will be used. ++ ++There are other ways of specifying linker scripts. See ++@xref{--default-script}, @xref{--section-ordering-file} and ++@xref{unrecognised-input-files}. + + @kindex -dT @var{script} + @kindex --default-script=@var{script} + @cindex script files + @item -dT @var{scriptfile} + @itemx --default-script=@var{scriptfile} ++@anchor{--default-script} + Use @var{scriptfile} as the default linker script. @xref{Scripts}. + + This option is similar to the @option{--script} option except that +@@ -2487,6 +2502,51 @@ warning and continue with the link. + + @end ifset + ++@kindex --section-ordering-file ++@item --section-ordering-file=@var{script} ++@anchor{--section-ordering-file} ++This option is used to augment the current linker script with ++additional mapping of input sections to output sections. This file ++must use the same syntax for @code{SECTIONS} as is used in normal ++linker scripts, but it should not do anything other than place input ++sections into output sections. @pxref{SECTIONS} ++ ++A second constraint on the section ordering script is that it can only ++reference output sections that are already defined by whichever linker ++script is currently in use. (Ie the default linker script or a script ++specified on the command line). The benefit of the section ordering ++script however is that the input sections are mapped to the start of ++the output sections, so that they can ensure the ordering of sections ++in the output section. For example, imagine that the default linker ++script looks like this: ++ ++@smallexample ++SECTIONS @{ ++ .text : @{ *(.text.hot) ; *(.text .text.*) @} ++ .data : @{ *(.data.big) ; *(.data .data.*) @} ++ @} ++@end smallexample ++ ++Then if a section ordering file like this is used: ++ ++@smallexample ++ .text : @{ *(.text.first) ; *(.text.z*) @} ++ .data : @{ foo.o(.data.first) ; *(.data.small) @} ++@end smallexample ++ ++This would be equivalent to a linker script like this: ++ ++@smallexample ++SECTIONS @{ ++ .text : @{ *(.text.first) ; *(.text.z*) ; *(.text.hot) ; *(.text .text.*) @} ++ .data : @{ foo.o(.data.first) ; *(.data.small) ; *(.data.big) ; *(.data .data.*) @} ++ @} ++@end smallexample ++ ++The advantage of the section ordering file is that it can be used to ++order those sections that matter to the user without having to worry ++about any other sections, or memory regions, or anything else. ++ + @kindex -shared + @kindex -Bshareable + @item -shared +diff -rupN binutils.orig/ld/ld.texi.orig binutils-2.41/ld/ld.texi.orig +--- binutils.orig/ld/ld.texi.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ld.texi.orig 2024-05-13 13:03:26.615569650 +0100 +@@ -0,0 +1,9639 @@ ++\input texinfo ++@setfilename ld.info ++@c Copyright (C) 1991-2023 Free Software Foundation, Inc. ++@syncodeindex ky cp ++@c man begin INCLUDE ++@include configdoc.texi ++@c (configdoc.texi is generated by the Makefile) ++@include bfdver.texi ++@c man end ++ ++@c @smallbook ++ ++@macro gcctabopt{body} ++@code{\body\} ++@end macro ++ ++@c man begin NAME ++@ifset man ++@c Configure for the generation of man pages ++@set UsesEnvVars ++@set GENERIC ++@set ARM ++@set C6X ++@set CSKY ++@set H8300 ++@set HPPA ++@set M68HC11 ++@set M68K ++@set MIPS ++@set MMIX ++@set MSP430 ++@set NDS32 ++@set NIOSII ++@set PDP11 ++@set POWERPC ++@set POWERPC64 ++@set Renesas ++@set S/390 ++@set SPU ++@set TICOFF ++@set WIN32 ++@set XTENSA ++@end ifset ++@c man end ++ ++@ifnottex ++@dircategory Software development ++@direntry ++* Ld: (ld). The GNU linker. ++@end direntry ++@end ifnottex ++ ++@copying ++This file documents the @sc{gnu} linker LD ++@ifset VERSION_PACKAGE ++@value{VERSION_PACKAGE} ++@end ifset ++version @value{VERSION}. ++ ++Copyright @copyright{} 1991-2023 Free Software Foundation, Inc. ++ ++Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 ++or any later version published by the Free Software Foundation; ++with no Invariant Sections, with no Front-Cover Texts, and with no ++Back-Cover Texts. A copy of the license is included in the ++section entitled ``GNU Free Documentation License''. ++@end copying ++@iftex ++@finalout ++@setchapternewpage odd ++@settitle The GNU linker ++@titlepage ++@title The GNU linker ++@sp 1 ++@subtitle @code{ld} ++@ifset VERSION_PACKAGE ++@subtitle @value{VERSION_PACKAGE} ++@end ifset ++@subtitle Version @value{VERSION} ++@author Steve Chamberlain ++@author Ian Lance Taylor ++@page ++ ++@tex ++{\parskip=0pt ++\hfill Red Hat Inc\par ++\hfill nickc\@redhat.com, doc\@redhat.com\par ++\hfill {\it The GNU linker}\par ++\hfill Edited by Jeffrey Osier (jeffrey\@cygnus.com)\par ++} ++\global\parindent=0pt % Steve likes it this way. ++@end tex ++ ++@vskip 0pt plus 1filll ++@c man begin COPYRIGHT ++Copyright @copyright{} 1991-2023 Free Software Foundation, Inc. ++ ++Permission is granted to copy, distribute and/or modify this document ++under the terms of the GNU Free Documentation License, Version 1.3 ++or any later version published by the Free Software Foundation; ++with no Invariant Sections, with no Front-Cover Texts, and with no ++Back-Cover Texts. A copy of the license is included in the ++section entitled ``GNU Free Documentation License''. ++@c man end ++ ++@end titlepage ++@end iftex ++@contents ++@c FIXME: Talk about importance of *order* of args, cmds to linker! ++ ++@ifnottex ++@node Top ++@top LD ++This file documents the @sc{gnu} linker ld ++@ifset VERSION_PACKAGE ++@value{VERSION_PACKAGE} ++@end ifset ++version @value{VERSION}. ++ ++This document is distributed under the terms of the GNU Free ++Documentation License version 1.3. A copy of the license is included ++in the section entitled ``GNU Free Documentation License''. ++ ++@menu ++* Overview:: Overview ++* Invocation:: Invocation ++* Scripts:: Linker Scripts ++* Plugins:: Linker Plugins ++@ifset GENERIC ++* Machine Dependent:: Machine Dependent Features ++@end ifset ++@ifclear GENERIC ++@ifset H8300 ++* H8/300:: ld and the H8/300 ++@end ifset ++@ifset Renesas ++* Renesas:: ld and other Renesas micros ++@end ifset ++@ifset ARM ++* ARM:: ld and the ARM family ++@end ifset ++@ifset M68HC11 ++* M68HC11/68HC12:: ld and the Motorola 68HC11 and 68HC12 families ++@end ifset ++@ifset HPPA ++* HPPA ELF32:: ld and HPPA 32-bit ELF ++@end ifset ++@ifset M68K ++* M68K:: ld and Motorola 68K family ++@end ifset ++@ifset MIPS ++* MIPS:: ld and MIPS family ++@end ifset ++@ifset POWERPC ++* PowerPC ELF32:: ld and PowerPC 32-bit ELF Support ++@end ifset ++@ifset POWERPC64 ++* PowerPC64 ELF64:: ld and PowerPC64 64-bit ELF Support ++@end ifset ++@ifset S/390 ++* S/390 ELF:: ld and S/390 ELF Support ++@end ifset ++@ifset SPU ++* SPU ELF:: ld and SPU ELF Support ++@end ifset ++@ifset TICOFF ++* TI COFF:: ld and the TI COFF ++@end ifset ++@ifset WIN32 ++* Win32:: ld and WIN32 (cygwin/mingw) ++@end ifset ++@ifset XTENSA ++* Xtensa:: ld and Xtensa Processors ++@end ifset ++@end ifclear ++@ifclear SingleFormat ++* BFD:: BFD ++@end ifclear ++@c Following blank line required for remaining bug in makeinfo conds/menus ++ ++* Reporting Bugs:: Reporting Bugs ++* MRI:: MRI Compatible Script Files ++* GNU Free Documentation License:: GNU Free Documentation License ++* LD Index:: LD Index ++@end menu ++@end ifnottex ++ ++@node Overview ++@chapter Overview ++ ++@cindex @sc{gnu} linker ++@cindex what is this? ++ ++@ifset man ++@c man begin SYNOPSIS ++ld [@b{options}] @var{objfile} @dots{} ++@c man end ++ ++@c man begin SEEALSO ++ar(1), nm(1), objcopy(1), objdump(1), readelf(1) and ++the Info entries for @file{binutils} and ++@file{ld}. ++@c man end ++@end ifset ++ ++@c man begin DESCRIPTION ++ ++@command{ld} combines a number of object and archive files, relocates ++their data and ties up symbol references. Usually the last step in ++compiling a program is to run @command{ld}. ++ ++@command{ld} accepts Linker Command Language files written in ++a superset of AT&T's Link Editor Command Language syntax, ++to provide explicit and total control over the linking process. ++ ++@ifset man ++@c For the man only ++This man page does not describe the command language; see the ++@command{ld} entry in @code{info} for full details on the command ++language and on other aspects of the GNU linker. ++@end ifset ++ ++@ifclear SingleFormat ++This version of @command{ld} uses the general purpose BFD libraries ++to operate on object files. This allows @command{ld} to read, combine, and ++write object files in many different formats---for example, COFF or ++@code{a.out}. Different formats may be linked together to produce any ++available kind of object file. @xref{BFD}, for more information. ++@end ifclear ++ ++Aside from its flexibility, the @sc{gnu} linker is more helpful than other ++linkers in providing diagnostic information. Many linkers abandon ++execution immediately upon encountering an error; whenever possible, ++@command{ld} continues executing, allowing you to identify other errors ++(or, in some cases, to get an output file in spite of the error). ++ ++@c man end ++ ++@node Invocation ++@chapter Invocation ++ ++@c man begin DESCRIPTION ++ ++The @sc{gnu} linker @command{ld} is meant to cover a broad range of situations, ++and to be as compatible as possible with other linkers. As a result, ++you have many choices to control its behavior. ++ ++@c man end ++ ++@ifset UsesEnvVars ++@menu ++* Options:: Command-line Options ++* Environment:: Environment Variables ++@end menu ++ ++@node Options ++@section Command-line Options ++@end ifset ++ ++@cindex command line ++@cindex options ++ ++@c man begin OPTIONS ++ ++The linker supports a plethora of command-line options, but in actual ++practice few of them are used in any particular context. ++@cindex standard Unix system ++For instance, a frequent use of @command{ld} is to link standard Unix ++object files on a standard, supported Unix system. On such a system, to ++link a file @code{hello.o}: ++ ++@smallexample ++ld -o @var{output} /lib/crt0.o hello.o -lc ++@end smallexample ++ ++This tells @command{ld} to produce a file called @var{output} as the ++result of linking the file @code{/lib/crt0.o} with @code{hello.o} and ++the library @code{libc.a}, which will come from the standard search ++directories. (See the discussion of the @samp{-l} option below.) ++ ++Some of the command-line options to @command{ld} may be specified at any ++point in the command line. However, options which refer to files, such ++as @samp{-l} or @samp{-T}, cause the file to be read at the point at ++which the option appears in the command line, relative to the object ++files and other file options. Repeating non-file options with a ++different argument will either have no further effect, or override prior ++occurrences (those further to the left on the command line) of that ++option. Options which may be meaningfully specified more than once are ++noted in the descriptions below. ++ ++@cindex object files ++Non-option arguments are object files or archives which are to be linked ++together. They may follow, precede, or be mixed in with command-line ++options, except that an object file argument may not be placed between ++an option and its argument. ++ ++Usually the linker is invoked with at least one object file, but you can ++specify other forms of binary input files using @samp{-l}, @samp{-R}, ++and the script command language. If @emph{no} binary input files at all ++are specified, the linker does not produce any output, and issues the ++message @samp{No input files}. ++ ++If the linker cannot recognize the format of an object file, it will ++assume that it is a linker script. A script specified in this way ++augments the main linker script used for the link (either the default ++linker script or the one specified by using @samp{-T}). This feature ++permits the linker to link against a file which appears to be an object ++or an archive, but actually merely defines some symbol values, or uses ++@code{INPUT} or @code{GROUP} to load other objects. Specifying a ++script in this way merely augments the main linker script, with the ++extra commands placed after the main script; use the @samp{-T} option ++to replace the default linker script entirely, but note the effect of ++the @code{INSERT} command. @xref{Scripts}. ++ ++For options whose names are a single letter, ++option arguments must either follow the option letter without intervening ++whitespace, or be given as separate arguments immediately following the ++option that requires them. ++ ++For options whose names are multiple letters, either one dash or two can ++precede the option name; for example, @samp{-trace-symbol} and ++@samp{--trace-symbol} are equivalent. Note---there is one exception to ++this rule. Multiple letter options that start with a lower case 'o' can ++only be preceded by two dashes. This is to reduce confusion with the ++@samp{-o} option. So for example @samp{-omagic} sets the output file ++name to @samp{magic} whereas @samp{--omagic} sets the NMAGIC flag on the ++output. ++ ++Arguments to multiple-letter options must either be separated from the ++option name by an equals sign, or be given as separate arguments ++immediately following the option that requires them. For example, ++@samp{--trace-symbol foo} and @samp{--trace-symbol=foo} are equivalent. ++Unique abbreviations of the names of multiple-letter options are ++accepted. ++ ++Note---if the linker is being invoked indirectly, via a compiler driver ++(e.g. @samp{gcc}) then all the linker command-line options should be ++prefixed by @samp{-Wl,} (or whatever is appropriate for the particular ++compiler driver) like this: ++ ++@smallexample ++ gcc -Wl,--start-group foo.o bar.o -Wl,--end-group ++@end smallexample ++ ++This is important, because otherwise the compiler driver program may ++silently drop the linker options, resulting in a bad link. Confusion ++may also arise when passing options that require values through a ++driver, as the use of a space between option and argument acts as ++a separator, and causes the driver to pass only the option to the linker ++and the argument to the compiler. In this case, it is simplest to use ++the joined forms of both single- and multiple-letter options, such as: ++ ++@smallexample ++ gcc foo.o bar.o -Wl,-eENTRY -Wl,-Map=a.map ++@end smallexample ++ ++Here is a table of the generic command-line switches accepted by the GNU ++linker: ++ ++@table @gcctabopt ++@include at-file.texi ++ ++@kindex -a @var{keyword} ++@item -a @var{keyword} ++This option is supported for HP/UX compatibility. The @var{keyword} ++argument must be one of the strings @samp{archive}, @samp{shared}, or ++@samp{default}. @samp{-aarchive} is functionally equivalent to ++@samp{-Bstatic}, and the other two keywords are functionally equivalent ++to @samp{-Bdynamic}. This option may be used any number of times. ++ ++@kindex --audit @var{AUDITLIB} ++@item --audit @var{AUDITLIB} ++Adds @var{AUDITLIB} to the @code{DT_AUDIT} entry of the dynamic section. ++@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME ++specified in the library. If specified multiple times @code{DT_AUDIT} ++will contain a colon separated list of audit interfaces to use. If the linker ++finds an object with an audit entry while searching for shared libraries, ++it will add a corresponding @code{DT_DEPAUDIT} entry in the output file. ++This option is only meaningful on ELF platforms supporting the rtld-audit ++interface. ++ ++@ifclear SingleFormat ++@cindex binary input format ++@kindex -b @var{format} ++@kindex --format=@var{format} ++@cindex input format ++@cindex input format ++@item -b @var{input-format} ++@itemx --format=@var{input-format} ++@command{ld} may be configured to support more than one kind of object ++file. If your @command{ld} is configured this way, you can use the ++@samp{-b} option to specify the binary format for input object files ++that follow this option on the command line. Even when @command{ld} is ++configured to support alternative object formats, you don't usually need ++to specify this, as @command{ld} should be configured to expect as a ++default input format the most usual format on each machine. ++@var{input-format} is a text string, the name of a particular format ++supported by the BFD libraries. (You can list the available binary ++formats with @samp{objdump -i}.) ++@xref{BFD}. ++ ++You may want to use this option if you are linking files with an unusual ++binary format. You can also use @samp{-b} to switch formats explicitly (when ++linking object files of different formats), by including ++@samp{-b @var{input-format}} before each group of object files in a ++particular format. ++ ++The default format is taken from the environment variable ++@code{GNUTARGET}. ++@ifset UsesEnvVars ++@xref{Environment}. ++@end ifset ++You can also define the input format from a script, using the command ++@code{TARGET}; ++@ifclear man ++see @ref{Format Commands}. ++@end ifclear ++@end ifclear ++ ++@kindex -c @var{MRI-cmdfile} ++@kindex --mri-script=@var{MRI-cmdfile} ++@cindex compatibility, MRI ++@item -c @var{MRI-commandfile} ++@itemx --mri-script=@var{MRI-commandfile} ++For compatibility with linkers produced by MRI, @command{ld} accepts script ++files written in an alternate, restricted command language, described in ++@ifclear man ++@ref{MRI,,MRI Compatible Script Files}. ++@end ifclear ++@ifset man ++the MRI Compatible Script Files section of GNU ld documentation. ++@end ifset ++Introduce MRI script files with ++the option @samp{-c}; use the @samp{-T} option to run linker ++scripts written in the general-purpose @command{ld} scripting language. ++If @var{MRI-cmdfile} does not exist, @command{ld} looks for it in the directories ++specified by any @samp{-L} options. ++ ++@cindex common allocation ++@kindex -d ++@kindex -dc ++@kindex -dp ++@item -d ++@itemx -dc ++@itemx -dp ++These three options are equivalent; multiple forms are supported for ++compatibility with other linkers. They assign space to common symbols ++even if a relocatable output file is specified (with @samp{-r}). The ++script command @code{FORCE_COMMON_ALLOCATION} has the same effect. ++@xref{Miscellaneous Commands}. ++ ++@kindex --depaudit @var{AUDITLIB} ++@kindex -P @var{AUDITLIB} ++@item --depaudit @var{AUDITLIB} ++@itemx -P @var{AUDITLIB} ++Adds @var{AUDITLIB} to the @code{DT_DEPAUDIT} entry of the dynamic section. ++@var{AUDITLIB} is not checked for existence, nor will it use the DT_SONAME ++specified in the library. If specified multiple times @code{DT_DEPAUDIT} ++will contain a colon separated list of audit interfaces to use. This ++option is only meaningful on ELF platforms supporting the rtld-audit interface. ++The -P option is provided for Solaris compatibility. ++ ++@kindex --enable-linker-version ++@item --enable-linker-version ++Enables the @code{LINKER_VERSION} linker script directive, described ++in @ref{Output Section Data}. If this directive is used in a linker ++script and this option has been enabled then a string containing the ++linker version will be inserted at the current point. ++ ++Note - this location of this option on the linker command line is ++significant. It will only affect linker scripts that come after it on ++the command line, or which are built into the linker. ++ ++@kindex --disable-linker-version ++@item --disable-linker-version ++Disables the @code{LINKER_VERSION} linker script directive, so that it ++does not insert a version string. This is the default. ++ ++@kindex --enable-non-contiguous-regions ++@item --enable-non-contiguous-regions ++This option avoids generating an error if an input section does not ++fit a matching output section. The linker tries to allocate the input ++section to subseque nt matching output sections, and generates an ++error only if no output section is large enough. This is useful when ++several non-contiguous memory regions are available and the input ++section does not require a particular one. The order in which input ++sections are evaluated does not change, for instance: ++ ++@smallexample ++ MEMORY @{ ++ MEM1 (rwx) : ORIGIN = 0x1000, LENGTH = 0x14 ++ MEM2 (rwx) : ORIGIN = 0x1000, LENGTH = 0x40 ++ MEM3 (rwx) : ORIGIN = 0x2000, LENGTH = 0x40 ++ @} ++ SECTIONS @{ ++ mem1 : @{ *(.data.*); @} > MEM1 ++ mem2 : @{ *(.data.*); @} > MEM2 ++ mem3 : @{ *(.data.*); @} > MEM3 ++ @} ++ ++ with input sections: ++ .data.1: size 8 ++ .data.2: size 0x10 ++ .data.3: size 4 ++ ++ results in .data.1 affected to mem1, and .data.2 and .data.3 ++ affected to mem2, even though .data.3 would fit in mem3. ++@end smallexample ++ ++This option is incompatible with INSERT statements because it changes ++the way input sections are mapped to output sections. ++ ++@kindex --enable-non-contiguous-regions-warnings ++@item --enable-non-contiguous-regions-warnings ++This option enables warnings when ++@code{--enable-non-contiguous-regions} allows possibly unexpected ++matches in sections mapping, potentially leading to silently ++discarding a section instead of failing because it does not fit any ++output region. ++ ++@cindex entry point, from command line ++@kindex -e @var{entry} ++@kindex --entry=@var{entry} ++@item -e @var{entry} ++@itemx --entry=@var{entry} ++Use @var{entry} as the explicit symbol for beginning execution of your ++program, rather than the default entry point. If there is no symbol ++named @var{entry}, the linker will try to parse @var{entry} as a number, ++and use that as the entry address (the number will be interpreted in ++base 10; you may use a leading @samp{0x} for base 16, or a leading ++@samp{0} for base 8). @xref{Entry Point}, for a discussion of defaults ++and other ways of specifying the entry point. ++ ++@kindex --exclude-libs ++@item --exclude-libs @var{lib},@var{lib},... ++Specifies a list of archive libraries from which symbols should not be automatically ++exported. The library names may be delimited by commas or colons. Specifying ++@code{--exclude-libs ALL} excludes symbols in all archive libraries from ++automatic export. This option is available only for the i386 PE targeted ++port of the linker and for ELF targeted ports. For i386 PE, symbols ++explicitly listed in a .def file are still exported, regardless of this ++option. For ELF targeted ports, symbols affected by this option will ++be treated as hidden. ++ ++@kindex --exclude-modules-for-implib ++@item --exclude-modules-for-implib @var{module},@var{module},... ++Specifies a list of object files or archive members, from which symbols ++should not be automatically exported, but which should be copied wholesale ++into the import library being generated during the link. The module names ++may be delimited by commas or colons, and must match exactly the filenames ++used by @command{ld} to open the files; for archive members, this is simply ++the member name, but for object files the name listed must include and ++match precisely any path used to specify the input file on the linker's ++command-line. This option is available only for the i386 PE targeted port ++of the linker. Symbols explicitly listed in a .def file are still exported, ++regardless of this option. ++ ++@cindex dynamic symbol table ++@kindex -E ++@kindex --export-dynamic ++@kindex --no-export-dynamic ++@item -E ++@itemx --export-dynamic ++@itemx --no-export-dynamic ++When creating a dynamically linked executable, using the @option{-E} ++option or the @option{--export-dynamic} option causes the linker to add ++all symbols to the dynamic symbol table. The dynamic symbol table is the ++set of symbols which are visible from dynamic objects at run time. ++ ++If you do not use either of these options (or use the ++@option{--no-export-dynamic} option to restore the default behavior), the ++dynamic symbol table will normally contain only those symbols which are ++referenced by some dynamic object mentioned in the link. ++ ++If you use @code{dlopen} to load a dynamic object which needs to refer ++back to the symbols defined by the program, rather than some other ++dynamic object, then you will probably need to use this option when ++linking the program itself. ++ ++You can also use the dynamic list to control what symbols should ++be added to the dynamic symbol table if the output format supports it. ++See the description of @samp{--dynamic-list}. ++ ++Note that this option is specific to ELF targeted ports. PE targets ++support a similar function to export all symbols from a DLL or EXE; see ++the description of @samp{--export-all-symbols} below. ++ ++@kindex --export-dynamic-symbol=@var{glob} ++@cindex export dynamic symbol ++@item --export-dynamic-symbol=@var{glob} ++When creating a dynamically linked executable, symbols matching ++@var{glob} will be added to the dynamic symbol table. When creating a ++shared library, references to symbols matching @var{glob} will not be ++bound to the definitions within the shared library. This option is a ++no-op when creating a shared library and @samp{-Bsymbolic} or ++@samp{--dynamic-list} are not specified. This option is only meaningful ++on ELF platforms which support shared libraries. ++ ++@kindex --export-dynamic-symbol-list=@var{file} ++@cindex export dynamic symbol list ++@item --export-dynamic-symbol-list=@var{file} ++Specify a @samp{--export-dynamic-symbol} for each pattern in the file. ++The format of the file is the same as the version node without ++scope and node name. See @ref{VERSION} for more information. ++ ++@ifclear SingleFormat ++@cindex big-endian objects ++@cindex endianness ++@kindex -EB ++@item -EB ++Link big-endian objects. This affects the default output format. ++ ++@cindex little-endian objects ++@kindex -EL ++@item -EL ++Link little-endian objects. This affects the default output format. ++@end ifclear ++ ++@kindex -f @var{name} ++@kindex --auxiliary=@var{name} ++@item -f @var{name} ++@itemx --auxiliary=@var{name} ++When creating an ELF shared object, set the internal DT_AUXILIARY field ++to the specified name. This tells the dynamic linker that the symbol ++table of the shared object should be used as an auxiliary filter on the ++symbol table of the shared object @var{name}. ++ ++If you later link a program against this filter object, then, when you ++run the program, the dynamic linker will see the DT_AUXILIARY field. If ++the dynamic linker resolves any symbols from the filter object, it will ++first check whether there is a definition in the shared object ++@var{name}. If there is one, it will be used instead of the definition ++in the filter object. The shared object @var{name} need not exist. ++Thus the shared object @var{name} may be used to provide an alternative ++implementation of certain functions, perhaps for debugging or for ++machine-specific performance. ++ ++This option may be specified more than once. The DT_AUXILIARY entries ++will be created in the order in which they appear on the command line. ++ ++@kindex -F @var{name} ++@kindex --filter=@var{name} ++@item -F @var{name} ++@itemx --filter=@var{name} ++When creating an ELF shared object, set the internal DT_FILTER field to ++the specified name. This tells the dynamic linker that the symbol table ++of the shared object which is being created should be used as a filter ++on the symbol table of the shared object @var{name}. ++ ++If you later link a program against this filter object, then, when you ++run the program, the dynamic linker will see the DT_FILTER field. The ++dynamic linker will resolve symbols according to the symbol table of the ++filter object as usual, but it will actually link to the definitions ++found in the shared object @var{name}. Thus the filter object can be ++used to select a subset of the symbols provided by the object ++@var{name}. ++ ++Some older linkers used the @option{-F} option throughout a compilation ++toolchain for specifying object-file format for both input and output ++object files. ++@ifclear SingleFormat ++The @sc{gnu} linker uses other mechanisms for this purpose: the ++@option{-b}, @option{--format}, @option{--oformat} options, the ++@code{TARGET} command in linker scripts, and the @code{GNUTARGET} ++environment variable. ++@end ifclear ++The @sc{gnu} linker will ignore the @option{-F} option when not ++creating an ELF shared object. ++ ++@cindex finalization function ++@kindex -fini=@var{name} ++@item -fini=@var{name} ++When creating an ELF executable or shared object, call NAME when the ++executable or shared object is unloaded, by setting DT_FINI to the ++address of the function. By default, the linker uses @code{_fini} as ++the function to call. ++ ++@kindex -g ++@item -g ++Ignored. Provided for compatibility with other tools. ++ ++@kindex -G @var{value} ++@kindex --gpsize=@var{value} ++@cindex object size ++@item -G @var{value} ++@itemx --gpsize=@var{value} ++Set the maximum size of objects to be optimized using the GP register to ++@var{size}. This is only meaningful for object file formats such as ++MIPS ELF that support putting large and small objects into different ++sections. This is ignored for other object file formats. ++ ++@cindex runtime library name ++@kindex -h @var{name} ++@kindex -soname=@var{name} ++@item -h @var{name} ++@itemx -soname=@var{name} ++When creating an ELF shared object, set the internal DT_SONAME field to ++the specified name. When an executable is linked with a shared object ++which has a DT_SONAME field, then when the executable is run the dynamic ++linker will attempt to load the shared object specified by the DT_SONAME ++field rather than using the file name given to the linker. ++ ++@kindex -i ++@cindex incremental link ++@item -i ++Perform an incremental link (same as option @samp{-r}). ++ ++@cindex initialization function ++@kindex -init=@var{name} ++@item -init=@var{name} ++When creating an ELF executable or shared object, call NAME when the ++executable or shared object is loaded, by setting DT_INIT to the address ++of the function. By default, the linker uses @code{_init} as the ++function to call. ++ ++@cindex archive files, from cmd line ++@kindex -l @var{namespec} ++@kindex --library=@var{namespec} ++@item -l @var{namespec} ++@itemx --library=@var{namespec} ++Add the archive or object file specified by @var{namespec} to the ++list of files to link. This option may be used any number of times. ++If @var{namespec} is of the form @file{:@var{filename}}, @command{ld} ++will search the library path for a file called @var{filename}, otherwise it ++will search the library path for a file called @file{lib@var{namespec}.a}. ++ ++On systems which support shared libraries, @command{ld} may also search for ++files other than @file{lib@var{namespec}.a}. Specifically, on ELF ++and SunOS systems, @command{ld} will search a directory for a library ++called @file{lib@var{namespec}.so} before searching for one called ++@file{lib@var{namespec}.a}. (By convention, a @code{.so} extension ++indicates a shared library.) Note that this behavior does not apply ++to @file{:@var{filename}}, which always specifies a file called ++@var{filename}. ++ ++The linker will search an archive only once, at the location where it is ++specified on the command line. If the archive defines a symbol which ++was undefined in some object which appeared before the archive on the ++command line, the linker will include the appropriate file(s) from the ++archive. However, an undefined symbol in an object appearing later on ++the command line will not cause the linker to search the archive again. ++ ++See the @option{-(} option for a way to force the linker to search ++archives multiple times. ++ ++You may list the same archive multiple times on the command line. ++ ++@ifset GENERIC ++This type of archive searching is standard for Unix linkers. However, ++if you are using @command{ld} on AIX, note that it is different from the ++behaviour of the AIX linker. ++@end ifset ++ ++@cindex search directory, from cmd line ++@kindex -L @var{dir} ++@kindex --library-path=@var{dir} ++@item -L @var{searchdir} ++@itemx --library-path=@var{searchdir} ++Add path @var{searchdir} to the list of paths that @command{ld} will search ++for archive libraries and @command{ld} control scripts. You may use this ++option any number of times. The directories are searched in the order ++in which they are specified on the command line. Directories specified ++on the command line are searched before the default directories. All ++@option{-L} options apply to all @option{-l} options, regardless of the ++order in which the options appear. @option{-L} options do not affect ++how @command{ld} searches for a linker script unless @option{-T} ++option is specified. ++ ++If @var{searchdir} begins with @code{=} or @code{$SYSROOT}, then this ++prefix will be replaced by the @dfn{sysroot prefix}, controlled by the ++@samp{--sysroot} option, or specified when the linker is configured. ++ ++@ifset UsesEnvVars ++The default set of paths searched (without being specified with ++@samp{-L}) depends on which emulation mode @command{ld} is using, and in ++some cases also on how it was configured. @xref{Environment}. ++@end ifset ++ ++The paths can also be specified in a link script with the ++@code{SEARCH_DIR} command. Directories specified this way are searched ++at the point in which the linker script appears in the command line. ++ ++@cindex emulation ++@kindex -m @var{emulation} ++@item -m @var{emulation} ++Emulate the @var{emulation} linker. You can list the available ++emulations with the @samp{--verbose} or @samp{-V} options. ++ ++If the @samp{-m} option is not used, the emulation is taken from the ++@code{LDEMULATION} environment variable, if that is defined. ++ ++Otherwise, the default emulation depends upon how the linker was ++configured. ++ ++@cindex remapping inputs ++@kindex --remap-inputs=@file{pattern}=@file{filename} ++@kindex --remap-inputs-file=@file{file} ++@item --remap-inputs=@file{pattern}=@file{filename} ++@itemx --remap-inputs-file=@file{file} ++These options allow the names of input files to be changed before the ++linker attempts to open them. The option ++@option{--remap-inputs=foo.o=bar.o} will cause any attempt to load a ++file called @file{foo.o} to instead try to load a file called ++@file{bar.o}. Wildcard patterns are permitted in the first filename, ++so @option{--remap-inputs=foo*.o=bar.o} will rename any input file that ++matches @file{foo*.o} to @file{bar.o}. ++ ++An alternative form of the option ++@option{--remap-inputs-file=filename} allows the remappings to be read ++from a file. Each line in the file can contain a single remapping. ++Blank lines are ignored. Anything from a hash character (@samp{#}) to ++the end of a line is considered to be a comment and is also ignored. ++The mapping pattern can be separated from the filename by whitespace ++or an equals (@samp{=}) character. ++ ++The options can be specified multiple times. Their contents ++accumulate. The remappings will be processed in the order in which ++they occur on the command line, and if they come from a file, in the ++order in which they occur in the file. If a match is made, no further ++checking for that filename will be performed. ++ ++If the replacement filename is @file{/dev/null} or just @file{NUL} ++then the remapping will actually cause the input file to be ignored. ++This can be a convenient way to experiment with removing input files ++from a complicated build environment. ++ ++Note that this option is position dependent and only affects filenames ++that come after it on the command line. Thus: ++ ++@smallexample ++ ld foo.o --remap-inputs=foo.o=bar.o ++@end smallexample ++ ++Will have no effect, whereas: ++ ++@smallexample ++ ld --remap-inputs=foo.o=bar.o foo.o ++@end smallexample ++ ++Will rename the input file @file{foo.o} to @file{bar.o}. ++ ++Note - these options also affect files referenced by @emph{INPUT} ++statements in linker scripts. But since linker scripts are processed ++after the entire command line is read, the position of the remap ++options on the command line is not significant. ++ ++If the @option{verbose} option is enabled then any mappings that match ++will be reported, although again the @option{verbose} option needs to ++be enabled on the command line @emph{before} the remaped filenames ++appear. ++ ++If the @option{-Map} or @option{--print-map} options are enabled then ++the remapping list will be included in the map output. ++ ++@cindex link map ++@kindex -M ++@kindex --print-map ++@item -M ++@itemx --print-map ++Print a link map to the standard output. A link map provides ++information about the link, including the following: ++ ++@itemize @bullet ++@item ++Where object files are mapped into memory. ++@item ++How common symbols are allocated. ++@item ++All archive members included in the link, with a mention of the symbol ++which caused the archive member to be brought in. ++@item ++The values assigned to symbols. ++ ++Note - symbols whose values are computed by an expression which ++involves a reference to a previous value of the same symbol may not ++have correct result displayed in the link map. This is because the ++linker discards intermediate results and only retains the final value ++of an expression. Under such circumstances the linker will display ++the final value enclosed by square brackets. Thus for example a ++linker script containing: ++ ++@smallexample ++ foo = 1 ++ foo = foo * 4 ++ foo = foo + 8 ++@end smallexample ++ ++will produce the following output in the link map if the @option{-M} ++option is used: ++ ++@smallexample ++ 0x00000001 foo = 0x1 ++ [0x0000000c] foo = (foo * 0x4) ++ [0x0000000c] foo = (foo + 0x8) ++@end smallexample ++ ++See @ref{Expressions} for more information about expressions in linker ++scripts. ++ ++@item ++How GNU properties are merged. ++ ++When the linker merges input .note.gnu.property sections into one output ++.note.gnu.property section, some properties are removed or updated. ++These actions are reported in the link map. For example: ++ ++@smallexample ++Removed property 0xc0000002 to merge foo.o (0x1) and bar.o (not found) ++@end smallexample ++ ++This indicates that property 0xc0000002 is removed from output when ++merging properties in @file{foo.o}, whose property 0xc0000002 value ++is 0x1, and @file{bar.o}, which doesn't have property 0xc0000002. ++ ++@smallexample ++Updated property 0xc0010001 (0x1) to merge foo.o (0x1) and bar.o (0x1) ++@end smallexample ++ ++This indicates that property 0xc0010001 value is updated to 0x1 in output ++when merging properties in @file{foo.o}, whose 0xc0010001 property value ++is 0x1, and @file{bar.o}, whose 0xc0010001 property value is 0x1. ++@end itemize ++ ++@cindex link map discarded ++@kindex --print-map-discarded ++@kindex --no-print-map-discarded ++@item --print-map-discarded ++@itemx --no-print-map-discarded ++Print (or do not print) the list of discarded and garbage collected sections ++in the link map. Enabled by default. ++ ++@kindex --print-map-locals ++@kindex --no-print-map-locals ++@item --print-map-locals ++@itemx --no-print-map-locals ++Print (or do not print) local symbols in the link map. Local symbols ++will have the text @samp{(local)} printed before their name, and will ++be listed after all of the global symbols in a given section. ++Temporary local symbols (typically those that start with @samp{.L}) ++will not be included in the output. Disabled by default. ++ ++@kindex -n ++@cindex read-only text ++@cindex NMAGIC ++@kindex --nmagic ++@item -n ++@itemx --nmagic ++Turn off page alignment of sections, and disable linking against shared ++libraries. If the output format supports Unix style magic numbers, ++mark the output as @code{NMAGIC}. ++ ++@kindex -N ++@kindex --omagic ++@cindex read/write from cmd line ++@cindex OMAGIC ++@item -N ++@itemx --omagic ++Set the text and data sections to be readable and writable. Also, do ++not page-align the data segment, and disable linking against shared ++libraries. If the output format supports Unix style magic numbers, ++mark the output as @code{OMAGIC}. Note: Although a writable text section ++is allowed for PE-COFF targets, it does not conform to the format ++specification published by Microsoft. ++ ++@kindex --no-omagic ++@cindex OMAGIC ++@item --no-omagic ++This option negates most of the effects of the @option{-N} option. It ++sets the text section to be read-only, and forces the data segment to ++be page-aligned. Note - this option does not enable linking against ++shared libraries. Use @option{-Bdynamic} for this. ++ ++@kindex -o @var{output} ++@kindex --output=@var{output} ++@cindex naming the output file ++@item -o @var{output} ++@itemx --output=@var{output} ++Use @var{output} as the name for the program produced by @command{ld}; if this ++option is not specified, the name @file{a.out} is used by default. The ++script command @code{OUTPUT} can also specify the output file name. ++ ++@kindex --dependency-file=@var{depfile} ++@cindex dependency file ++@item --dependency-file=@var{depfile} ++Write a @dfn{dependency file} to @var{depfile}. This file contains a rule ++suitable for @code{make} describing the output file and all the input files ++that were read to produce it. The output is similar to the compiler's ++output with @samp{-M -MP} (@pxref{Preprocessor Options,, Options ++Controlling the Preprocessor, gcc.info, Using the GNU Compiler ++Collection}). Note that there is no option like the compiler's @samp{-MM}, ++to exclude ``system files'' (which is not a well-specified concept in the ++linker, unlike ``system headers'' in the compiler). So the output from ++@samp{--dependency-file} is always specific to the exact state of the ++installation where it was produced, and should not be copied into ++distributed makefiles without careful editing. ++ ++@kindex -O @var{level} ++@cindex generating optimized output ++@item -O @var{level} ++If @var{level} is a numeric values greater than zero @command{ld} optimizes ++the output. This might take significantly longer and therefore probably ++should only be enabled for the final binary. At the moment this ++option only affects ELF shared library generation. Future releases of ++the linker may make more use of this option. Also currently there is ++no difference in the linker's behaviour for different non-zero values ++of this option. Again this may change with future releases. ++ ++@kindex -plugin @var{name} ++@item -plugin @var{name} ++Involve a plugin in the linking process. The @var{name} parameter is ++the absolute filename of the plugin. Usually this parameter is ++automatically added by the complier, when using link time ++optimization, but users can also add their own plugins if they so ++wish. ++ ++Note that the location of the compiler originated plugins is different ++from the place where the @command{ar}, @command{nm} and ++@command{ranlib} programs search for their plugins. In order for ++those commands to make use of a compiler based plugin it must first be ++copied into the @file{$@{libdir@}/bfd-plugins} directory. All gcc ++based linker plugins are backward compatible, so it is sufficient to ++just copy in the newest one. ++ ++@kindex --push-state ++@cindex push state governing input file handling ++@item --push-state ++The @option{--push-state} allows one to preserve the current state of the ++flags which govern the input file handling so that they can all be ++restored with one corresponding @option{--pop-state} option. ++ ++The option which are covered are: @option{-Bdynamic}, @option{-Bstatic}, ++@option{-dn}, @option{-dy}, @option{-call_shared}, @option{-non_shared}, ++@option{-static}, @option{-N}, @option{-n}, @option{--whole-archive}, ++@option{--no-whole-archive}, @option{-r}, @option{-Ur}, ++@option{--copy-dt-needed-entries}, @option{--no-copy-dt-needed-entries}, ++@option{--as-needed}, @option{--no-as-needed}, and @option{-a}. ++ ++One target for this option are specifications for @file{pkg-config}. When ++used with the @option{--libs} option all possibly needed libraries are ++listed and then possibly linked with all the time. It is better to return ++something as follows: ++ ++@smallexample ++-Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state ++@end smallexample ++ ++@kindex --pop-state ++@cindex pop state governing input file handling ++@item --pop-state ++Undoes the effect of --push-state, restores the previous values of the ++flags governing input file handling. ++ ++@kindex -q ++@kindex --emit-relocs ++@cindex retain relocations in final executable ++@item -q ++@itemx --emit-relocs ++Leave relocation sections and contents in fully linked executables. ++Post link analysis and optimization tools may need this information in ++order to perform correct modifications of executables. This results ++in larger executables. ++ ++This option is currently only supported on ELF platforms. ++ ++@kindex --force-dynamic ++@cindex forcing the creation of dynamic sections ++@item --force-dynamic ++Force the output file to have dynamic sections. This option is specific ++to VxWorks targets. ++ ++@cindex partial link ++@cindex relocatable output ++@kindex -r ++@kindex --relocatable ++@item -r ++@itemx --relocatable ++Generate relocatable output---i.e., generate an output file that can in ++turn serve as input to @command{ld}. This is often called @dfn{partial ++linking}. As a side effect, in environments that support standard Unix ++magic numbers, this option also sets the output file's magic number to ++@code{OMAGIC}. ++@c ; see @option{-N}. ++If this option is not specified, an absolute file is produced. When ++linking C++ programs, this option @emph{will not} resolve references to ++constructors; to do that, use @samp{-Ur}. ++ ++When an input file does not have the same format as the output file, ++partial linking is only supported if that input file does not contain any ++relocations. Different output formats can have further restrictions; for ++example some @code{a.out}-based formats do not support partial linking ++with input files in other formats at all. ++ ++This option does the same thing as @samp{-i}. ++ ++@kindex -R @var{file} ++@kindex --just-symbols=@var{file} ++@cindex symbol-only input ++@item -R @var{filename} ++@itemx --just-symbols=@var{filename} ++Read symbol names and their addresses from @var{filename}, but do not ++relocate it or include it in the output. This allows your output file ++to refer symbolically to absolute locations of memory defined in other ++programs. You may use this option more than once. ++ ++For compatibility with other ELF linkers, if the @option{-R} option is ++followed by a directory name, rather than a file name, it is treated as ++the @option{-rpath} option. ++ ++@kindex -s ++@kindex --strip-all ++@cindex strip all symbols ++@item -s ++@itemx --strip-all ++Omit all symbol information from the output file. ++ ++@kindex -S ++@kindex --strip-debug ++@cindex strip debugger symbols ++@item -S ++@itemx --strip-debug ++Omit debugger symbol information (but not all symbols) from the output file. ++ ++@kindex --strip-discarded ++@kindex --no-strip-discarded ++@item --strip-discarded ++@itemx --no-strip-discarded ++Omit (or do not omit) global symbols defined in discarded sections. ++Enabled by default. ++ ++@kindex -t ++@kindex --trace ++@cindex input files, displaying ++@item -t ++@itemx --trace ++Print the names of the input files as @command{ld} processes them. If ++@samp{-t} is given twice then members within archives are also printed. ++@samp{-t} output is useful to generate a list of all the object files ++and scripts involved in linking, for example, when packaging files for ++a linker bug report. ++ ++@kindex -T @var{script} ++@kindex --script=@var{script} ++@cindex script files ++@item -T @var{scriptfile} ++@itemx --script=@var{scriptfile} ++Use @var{scriptfile} as the linker script. This script replaces ++@command{ld}'s default linker script (rather than adding to it), ++unless the script contains @code{INSERT}, so ++@var{commandfile} must specify everything necessary to describe the ++output file. @xref{Scripts}. If @var{scriptfile} does not exist in ++the current directory, @code{ld} looks for it in the directories ++specified by any preceding @samp{-L} options. Multiple @samp{-T} ++options accumulate. ++ ++@kindex -dT @var{script} ++@kindex --default-script=@var{script} ++@cindex script files ++@item -dT @var{scriptfile} ++@itemx --default-script=@var{scriptfile} ++Use @var{scriptfile} as the default linker script. @xref{Scripts}. ++ ++This option is similar to the @option{--script} option except that ++processing of the script is delayed until after the rest of the ++command line has been processed. This allows options placed after the ++@option{--default-script} option on the command line to affect the ++behaviour of the linker script, which can be important when the linker ++command line cannot be directly controlled by the user. (eg because ++the command line is being constructed by another tool, such as ++@samp{gcc}). ++ ++@kindex -u @var{symbol} ++@kindex --undefined=@var{symbol} ++@cindex undefined symbol ++@item -u @var{symbol} ++@itemx --undefined=@var{symbol} ++Force @var{symbol} to be entered in the output file as an undefined ++symbol. Doing this may, for example, trigger linking of additional ++modules from standard libraries. @samp{-u} may be repeated with ++different option arguments to enter additional undefined symbols. This ++option is equivalent to the @code{EXTERN} linker script command. ++ ++If this option is being used to force additional modules to be pulled ++into the link, and if it is an error for the symbol to remain ++undefined, then the option @option{--require-defined} should be used ++instead. ++ ++@kindex --require-defined=@var{symbol} ++@cindex symbols, require defined ++@cindex defined symbol ++@item --require-defined=@var{symbol} ++Require that @var{symbol} is defined in the output file. This option ++is the same as option @option{--undefined} except that if @var{symbol} ++is not defined in the output file then the linker will issue an error ++and exit. The same effect can be achieved in a linker script by using ++@code{EXTERN}, @code{ASSERT} and @code{DEFINED} together. This option ++can be used multiple times to require additional symbols. ++ ++@kindex -Ur ++@cindex constructors ++@item -Ur ++ ++For programs that do not use constructors or destructors, or for ELF ++based systems this option is equivalent to @option{-r}: it generates ++relocatable output---i.e., an output file that can in turn serve as ++input to @command{ld}. For other binaries however the @option{-Ur} ++option is similar to @option{-r} but it also resolves references to ++constructors and destructors. ++ ++For those systems where @option{-r} and @option{-Ur} behave ++differently, it does not work to use @option{-Ur} on files that were ++themselves linked with @option{-Ur}; once the constructor table has ++been built, it cannot be added to. Use @option{-Ur} only for the last ++partial link, and @option{-r} for the others. ++ ++@kindex --orphan-handling=@var{MODE} ++@cindex orphan sections ++@cindex sections, orphan ++@item --orphan-handling=@var{MODE} ++Control how orphan sections are handled. An orphan section is one not ++specifically mentioned in a linker script. @xref{Orphan Sections}. ++ ++@var{MODE} can have any of the following values: ++ ++@table @code ++@item place ++Orphan sections are placed into a suitable output section following ++the strategy described in @ref{Orphan Sections}. The option ++@samp{--unique} also affects how sections are placed. ++ ++@item discard ++All orphan sections are discarded, by placing them in the ++@samp{/DISCARD/} section (@pxref{Output Section Discarding}). ++ ++@item warn ++The linker will place the orphan section as for @code{place} and also ++issue a warning. ++ ++@item error ++The linker will exit with an error if any orphan section is found. ++@end table ++ ++The default if @samp{--orphan-handling} is not given is @code{place}. ++ ++@kindex --unique[=@var{SECTION}] ++@item --unique[=@var{SECTION}] ++Creates a separate output section for every input section matching ++@var{SECTION}, or if the optional wildcard @var{SECTION} argument is ++missing, for every orphan input section. An orphan section is one not ++specifically mentioned in a linker script. You may use this option ++multiple times on the command line; It prevents the normal merging of ++input sections with the same name, overriding output section assignments ++in a linker script. ++ ++@kindex -v ++@kindex -V ++@kindex --version ++@cindex version ++@item -v ++@itemx --version ++@itemx -V ++Display the version number for @command{ld}. The @option{-V} option also ++lists the supported emulations. See also the description of the ++@option{--enable-linker-version} in @ref{Options,,Command-line Options} ++which can be used to insert the linker version string into a binary. ++ ++@kindex -x ++@kindex --discard-all ++@cindex deleting local symbols ++@item -x ++@itemx --discard-all ++Delete all local symbols. ++ ++@kindex -X ++@kindex --discard-locals ++@cindex local symbols, deleting ++@item -X ++@itemx --discard-locals ++Delete all temporary local symbols. (These symbols start with ++system-specific local label prefixes, typically @samp{.L} for ELF systems ++or @samp{L} for traditional a.out systems.) ++ ++@kindex -y @var{symbol} ++@kindex --trace-symbol=@var{symbol} ++@cindex symbol tracing ++@item -y @var{symbol} ++@itemx --trace-symbol=@var{symbol} ++Print the name of each linked file in which @var{symbol} appears. This ++option may be given any number of times. On many systems it is necessary ++to prepend an underscore. ++ ++This option is useful when you have an undefined symbol in your link but ++don't know where the reference is coming from. ++ ++@kindex -Y @var{path} ++@item -Y @var{path} ++Add @var{path} to the default library search path. This option exists ++for Solaris compatibility. ++ ++@kindex -z @var{keyword} ++@item -z @var{keyword} ++The recognized keywords are: ++@table @samp ++ ++@item call-nop=prefix-addr ++@itemx call-nop=suffix-nop ++@itemx call-nop=prefix-@var{byte} ++@itemx call-nop=suffix-@var{byte} ++Specify the 1-byte @code{NOP} padding when transforming indirect call ++to a locally defined function, foo, via its GOT slot. ++@option{call-nop=prefix-addr} generates @code{0x67 call foo}. ++@option{call-nop=suffix-nop} generates @code{call foo 0x90}. ++@option{call-nop=prefix-@var{byte}} generates @code{@var{byte} call foo}. ++@option{call-nop=suffix-@var{byte}} generates @code{call foo @var{byte}}. ++Supported for i386 and x86_64. ++ ++@item cet-report=none ++@itemx cet-report=warning ++@itemx cet-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_IBT and ++GNU_PROPERTY_X86_FEATURE_1_SHSTK properties in input .note.gnu.property ++section. @option{cet-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{cet-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{cet-report=error} will make ++the linker issue an error for missing properties in input files. ++Note that @option{ibt} will turn off the missing ++GNU_PROPERTY_X86_FEATURE_1_IBT property report and @option{shstk} will ++turn off the missing GNU_PROPERTY_X86_FEATURE_1_SHSTK property report. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item combreloc ++@itemx nocombreloc ++Combine multiple dynamic relocation sections and sort to improve ++dynamic symbol lookup caching. Do not do this if @samp{nocombreloc}. ++ ++@item common ++@itemx nocommon ++Generate common symbols with STT_COMMON type during a relocatable ++link. Use STT_OBJECT type if @samp{nocommon}. ++ ++@item common-page-size=@var{value} ++Set the page size most commonly used to @var{value}. Memory image ++layout will be optimized to minimize memory pages if the system is ++using pages of this size. ++ ++@item defs ++Report unresolved symbol references from regular object files. This ++is done even if the linker is creating a non-symbolic shared library. ++This option is the inverse of @samp{-z undefs}. ++ ++@item dynamic-undefined-weak ++@itemx nodynamic-undefined-weak ++Make undefined weak symbols dynamic when building a dynamic object, ++if they are referenced from a regular object file and not forced local ++by symbol visibility or versioning. Do not make them dynamic if ++@samp{nodynamic-undefined-weak}. If neither option is given, a target ++may default to either option being in force, or make some other ++selection of undefined weak symbols dynamic. Not all targets support ++these options. ++ ++@item execstack ++Marks the object as requiring executable stack. ++ ++@item global ++This option is only meaningful when building a shared object. It makes ++the symbols defined by this shared object available for symbol resolution ++of subsequently loaded libraries. ++ ++@item globalaudit ++This option is only meaningful when building a dynamic executable. ++This option marks the executable as requiring global auditing by ++setting the @code{DF_1_GLOBAUDIT} bit in the @code{DT_FLAGS_1} dynamic ++tag. Global auditing requires that any auditing library defined via ++the @option{--depaudit} or @option{-P} command-line options be run for ++all dynamic objects loaded by the application. ++ ++@item ibtplt ++Generate Intel Indirect Branch Tracking (IBT) enabled PLT entries. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item ibt ++Generate GNU_PROPERTY_X86_FEATURE_1_IBT in .note.gnu.property section ++to indicate compatibility with IBT. This also implies @option{ibtplt}. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@item indirect-extern-access ++@itemx noindirect-extern-access ++Generate GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS in ++.note.gnu.property section to indicate that object file requires ++canonical function pointers and cannot be used with copy relocation. ++This option also implies @option{noextern-protected-data} and ++@option{nocopyreloc}. Supported for i386 and x86-64. ++ ++@option{noindirect-extern-access} removes ++GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS from .note.gnu.property ++section. ++ ++@item initfirst ++This option is only meaningful when building a shared object. ++It marks the object so that its runtime initialization will occur ++before the runtime initialization of any other objects brought into ++the process at the same time. Similarly the runtime finalization of ++the object will occur after the runtime finalization of any other ++objects. ++ ++@item interpose ++Specify that the dynamic loader should modify its symbol search order ++so that symbols in this shared library interpose all other shared ++libraries not so marked. ++ ++@item unique ++@itemx nounique ++When generating a shared library or other dynamically loadable ELF ++object mark it as one that should (by default) only ever be loaded once, ++and only in the main namespace (when using @code{dlmopen}). This is ++primarily used to mark fundamental libraries such as libc, libpthread et ++al which do not usually function correctly unless they are the sole instances ++of themselves. This behaviour can be overridden by the @code{dlmopen} caller ++and does not apply to certain loading mechanisms (such as audit libraries). ++ ++@item lam-u48 ++Generate GNU_PROPERTY_X86_FEATURE_1_LAM_U48 in .note.gnu.property section ++to indicate compatibility with Intel LAM_U48. Supported for Linux/x86_64. ++ ++@item lam-u57 ++Generate GNU_PROPERTY_X86_FEATURE_1_LAM_U57 in .note.gnu.property section ++to indicate compatibility with Intel LAM_U57. Supported for Linux/x86_64. ++ ++@item lam-u48-report=none ++@itemx lam-u48-report=warning ++@itemx lam-u48-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U48 ++property in input .note.gnu.property section. ++@option{lam-u48-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-u48-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-u48-report=error} will ++make the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lam-u57-report=none ++@itemx lam-u57-report=warning ++@itemx lam-u57-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U57 ++property in input .note.gnu.property section. ++@option{lam-u57-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-u57-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-u57-report=error} will ++make the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lam-report=none ++@itemx lam-report=warning ++@itemx lam-report=error ++Specify how to report the missing GNU_PROPERTY_X86_FEATURE_1_LAM_U48 and ++GNU_PROPERTY_X86_FEATURE_1_LAM_U57 properties in input .note.gnu.property ++section. @option{lam-report=none}, which is the default, will make the ++linker not report missing properties in input files. ++@option{lam-report=warning} will make the linker issue a warning for ++missing properties in input files. @option{lam-report=error} will make ++the linker issue an error for missing properties in input files. ++Supported for Linux/x86_64. ++ ++@item lazy ++When generating an executable or shared library, mark it to tell the ++dynamic linker to defer function call resolution to the point when ++the function is called (lazy binding), rather than at load time. ++Lazy binding is the default. ++ ++@item loadfltr ++Specify that the object's filters be processed immediately at runtime. ++ ++@item max-page-size=@var{value} ++Set the maximum memory page size supported to @var{value}. ++ ++@item muldefs ++Allow multiple definitions. ++ ++@item nocopyreloc ++Disable linker generated .dynbss variables used in place of variables ++defined in shared libraries. May result in dynamic text relocations. ++ ++@item nodefaultlib ++Specify that the dynamic loader search for dependencies of this object ++should ignore any default library search paths. ++ ++@item nodelete ++Specify that the object shouldn't be unloaded at runtime. ++ ++@item nodlopen ++Specify that the object is not available to @code{dlopen}. ++ ++@item nodump ++Specify that the object can not be dumped by @code{dldump}. ++ ++@item noexecstack ++Marks the object as not requiring executable stack. ++ ++@item noextern-protected-data ++Don't treat protected data symbols as external when building a shared ++library. This option overrides the linker backend default. It can be ++used to work around incorrect relocations against protected data symbols ++generated by compiler. Updates on protected data symbols by another ++module aren't visible to the resulting shared library. Supported for ++i386 and x86-64. ++ ++@item noreloc-overflow ++Disable relocation overflow check. This can be used to disable ++relocation overflow check if there will be no dynamic relocation ++overflow at run-time. Supported for x86_64. ++ ++@item now ++When generating an executable or shared library, mark it to tell the ++dynamic linker to resolve all symbols when the program is started, or ++when the shared library is loaded by dlopen, instead of deferring ++function call resolution to the point when the function is first ++called. ++ ++@item origin ++Specify that the object requires @samp{$ORIGIN} handling in paths. ++ ++@item pack-relative-relocs ++@itemx nopack-relative-relocs ++Generate compact relative relocation in position-independent executable ++and shared library. It adds @code{DT_RELR}, @code{DT_RELRSZ} and ++@code{DT_RELRENT} entries to the dynamic section. It is ignored when ++building position-dependent executable and relocatable output. ++@option{nopack-relative-relocs} is the default, which disables compact ++relative relocation. When linked against the GNU C Library, a ++GLIBC_ABI_DT_RELR symbol version dependency on the shared C Library is ++added to the output. Supported for i386 and x86-64. ++ ++@item relro ++@itemx norelro ++Create an ELF @code{PT_GNU_RELRO} segment header in the object. This ++specifies a memory segment that should be made read-only after ++relocation, if supported. Specifying @samp{common-page-size} smaller ++than the system page size will render this protection ineffective. ++Don't create an ELF @code{PT_GNU_RELRO} segment if @samp{norelro}. ++ ++@item report-relative-reloc ++Report dynamic relative relocations generated by linker. Supported for ++Linux/i386 and Linux/x86_64. ++ ++@item sectionheader ++@itemx nosectionheader ++Generate section header. Don't generate section header if ++@samp{nosectionheader} is used. @option{sectionheader} is the default. ++ ++@item separate-code ++@itemx noseparate-code ++Create separate code @code{PT_LOAD} segment header in the object. This ++specifies a memory segment that should contain only instructions and must ++be in wholly disjoint pages from any other data. Don't create separate ++code @code{PT_LOAD} segment if @samp{noseparate-code} is used. ++ ++@item shstk ++Generate GNU_PROPERTY_X86_FEATURE_1_SHSTK in .note.gnu.property section ++to indicate compatibility with Intel Shadow Stack. Supported for ++Linux/i386 and Linux/x86_64. ++ ++@item stack-size=@var{value} ++Specify a stack size for an ELF @code{PT_GNU_STACK} segment. ++Specifying zero will override any default non-zero sized ++@code{PT_GNU_STACK} segment creation. ++ ++@item start-stop-gc ++@itemx nostart-stop-gc ++@cindex start-stop-gc ++When @samp{--gc-sections} is in effect, a reference from a retained ++section to @code{__start_SECNAME} or @code{__stop_SECNAME} causes all ++input sections named @code{SECNAME} to also be retained, if ++@code{SECNAME} is representable as a C identifier and either ++@code{__start_SECNAME} or @code{__stop_SECNAME} is synthesized by the ++linker. @samp{-z start-stop-gc} disables this effect, allowing ++sections to be garbage collected as if the special synthesized symbols ++were not defined. @samp{-z start-stop-gc} has no effect on a ++definition of @code{__start_SECNAME} or @code{__stop_SECNAME} in an ++object file or linker script. Such a definition will prevent the ++linker providing a synthesized @code{__start_SECNAME} or ++@code{__stop_SECNAME} respectively, and therefore the special ++treatment by garbage collection for those references. ++ ++@item start-stop-visibility=@var{value} ++@cindex visibility ++@cindex ELF symbol visibility ++Specify the ELF symbol visibility for synthesized ++@code{__start_SECNAME} and @code{__stop_SECNAME} symbols (@pxref{Input ++Section Example}). @var{value} must be exactly @samp{default}, ++@samp{internal}, @samp{hidden}, or @samp{protected}. If no @samp{-z ++start-stop-visibility} option is given, @samp{protected} is used for ++compatibility with historical practice. However, it's highly ++recommended to use @samp{-z start-stop-visibility=hidden} in new ++programs and shared libraries so that these symbols are not exported ++between shared objects, which is not usually what's intended. ++ ++@item text ++@itemx notext ++@itemx textoff ++Report an error if DT_TEXTREL is set, i.e., if the position-independent ++or shared object has dynamic relocations in read-only sections. Don't ++report an error if @samp{notext} or @samp{textoff}. ++ ++@item undefs ++Do not report unresolved symbol references from regular object files, ++either when creating an executable, or when creating a shared library. ++This option is the inverse of @samp{-z defs}. ++ ++@item unique-symbol ++@itemx nounique-symbol ++Avoid duplicated local symbol names in the symbol string table. Append ++".@code{number}" to duplicated local symbol names if @samp{unique-symbol} ++is used. @option{nounique-symbol} is the default. ++ ++@item x86-64-baseline ++@item x86-64-v2 ++@item x86-64-v3 ++@itemx x86-64-v4 ++Specify the x86-64 ISA level needed in .note.gnu.property section. ++@option{x86-64-baseline} generates @code{GNU_PROPERTY_X86_ISA_1_BASELINE}. ++@option{x86-64-v2} generates @code{GNU_PROPERTY_X86_ISA_1_V2}. ++@option{x86-64-v3} generates @code{GNU_PROPERTY_X86_ISA_1_V3}. ++@option{x86-64-v4} generates @code{GNU_PROPERTY_X86_ISA_1_V4}. ++Supported for Linux/i386 and Linux/x86_64. ++ ++@end table ++ ++Other keywords are ignored for Solaris compatibility. ++ ++@kindex -( ++@cindex groups of archives ++@item -( @var{archives} -) ++@itemx --start-group @var{archives} --end-group ++The @var{archives} should be a list of archive files. They may be ++either explicit file names, or @samp{-l} options. ++ ++The specified archives are searched repeatedly until no new undefined ++references are created. Normally, an archive is searched only once in ++the order that it is specified on the command line. If a symbol in that ++archive is needed to resolve an undefined symbol referred to by an ++object in an archive that appears later on the command line, the linker ++would not be able to resolve that reference. By grouping the archives, ++they will all be searched repeatedly until all possible references are ++resolved. ++ ++Using this option has a significant performance cost. It is best to use ++it only when there are unavoidable circular references between two or ++more archives. ++ ++@kindex --accept-unknown-input-arch ++@kindex --no-accept-unknown-input-arch ++@item --accept-unknown-input-arch ++@itemx --no-accept-unknown-input-arch ++Tells the linker to accept input files whose architecture cannot be ++recognised. The assumption is that the user knows what they are doing ++and deliberately wants to link in these unknown input files. This was ++the default behaviour of the linker, before release 2.14. The default ++behaviour from release 2.14 onwards is to reject such input files, and ++so the @samp{--accept-unknown-input-arch} option has been added to ++restore the old behaviour. ++ ++@kindex --as-needed ++@kindex --no-as-needed ++@item --as-needed ++@itemx --no-as-needed ++This option affects ELF DT_NEEDED tags for dynamic libraries mentioned ++on the command line after the @option{--as-needed} option. Normally ++the linker will add a DT_NEEDED tag for each dynamic library mentioned ++on the command line, regardless of whether the library is actually ++needed or not. @option{--as-needed} causes a DT_NEEDED tag to only be ++emitted for a library that @emph{at that point in the link} satisfies a ++non-weak undefined symbol reference from a regular object file or, if ++the library is not found in the DT_NEEDED lists of other needed libraries, a ++non-weak undefined symbol reference from another needed dynamic library. ++Object files or libraries appearing on the command line @emph{after} ++the library in question do not affect whether the library is seen as ++needed. This is similar to the rules for extraction of object files ++from archives. @option{--no-as-needed} restores the default behaviour. ++ ++Note: On Linux based systems the @option{--as-needed} option also has ++an affect on the behaviour of the @option{--rpath} and ++@option{--rpath-link} options. See the description of ++@option{--rpath-link} for more details. ++ ++@kindex --add-needed ++@kindex --no-add-needed ++@item --add-needed ++@itemx --no-add-needed ++These two options have been deprecated because of the similarity of ++their names to the @option{--as-needed} and @option{--no-as-needed} ++options. They have been replaced by @option{--copy-dt-needed-entries} ++and @option{--no-copy-dt-needed-entries}. ++ ++@kindex -assert @var{keyword} ++@item -assert @var{keyword} ++This option is ignored for SunOS compatibility. ++ ++@kindex -Bdynamic ++@kindex -dy ++@kindex -call_shared ++@item -Bdynamic ++@itemx -dy ++@itemx -call_shared ++Link against dynamic libraries. This is only meaningful on platforms ++for which shared libraries are supported. This option is normally the ++default on such platforms. The different variants of this option are ++for compatibility with various systems. You may use this option ++multiple times on the command line: it affects library searching for ++@option{-l} options which follow it. ++ ++@kindex -Bgroup ++@item -Bgroup ++Set the @code{DF_1_GROUP} flag in the @code{DT_FLAGS_1} entry in the dynamic ++section. This causes the runtime linker to handle lookups in this ++object and its dependencies to be performed only inside the group. ++@option{--unresolved-symbols=report-all} is implied. This option is ++only meaningful on ELF platforms which support shared libraries. ++ ++@kindex -Bstatic ++@kindex -dn ++@kindex -non_shared ++@kindex -static ++@item -Bstatic ++@itemx -dn ++@itemx -non_shared ++@itemx -static ++Do not link against shared libraries. This is only meaningful on ++platforms for which shared libraries are supported. The different ++variants of this option are for compatibility with various systems. You ++may use this option multiple times on the command line: it affects ++library searching for @option{-l} options which follow it. This ++option also implies @option{--unresolved-symbols=report-all}. This ++option can be used with @option{-shared}. Doing so means that a ++shared library is being created but that all of the library's external ++references must be resolved by pulling in entries from static ++libraries. ++ ++@kindex -Bsymbolic ++@item -Bsymbolic ++When creating a shared library, bind references to global symbols to the ++definition within the shared library, if any. Normally, it is possible ++for a program linked against a shared library to override the definition ++within the shared library. This option is only meaningful on ELF ++platforms which support shared libraries. ++ ++@kindex -Bsymbolic-functions ++@item -Bsymbolic-functions ++When creating a shared library, bind references to global function ++symbols to the definition within the shared library, if any. ++This option is only meaningful on ELF platforms which support shared ++libraries. ++ ++@kindex -Bno-symbolic ++@item -Bno-symbolic ++This option can cancel previously specified @samp{-Bsymbolic} and ++@samp{-Bsymbolic-functions}. ++ ++@kindex --dynamic-list=@var{dynamic-list-file} ++@item --dynamic-list=@var{dynamic-list-file} ++Specify the name of a dynamic list file to the linker. This is ++typically used when creating shared libraries to specify a list of ++global symbols whose references shouldn't be bound to the definition ++within the shared library, or creating dynamically linked executables ++to specify a list of symbols which should be added to the symbol table ++in the executable. This option is only meaningful on ELF platforms ++which support shared libraries. ++ ++The format of the dynamic list is the same as the version node without ++scope and node name. See @ref{VERSION} for more information. ++ ++@kindex --dynamic-list-data ++@item --dynamic-list-data ++Include all global data symbols to the dynamic list. ++ ++@kindex --dynamic-list-cpp-new ++@item --dynamic-list-cpp-new ++Provide the builtin dynamic list for C++ operator new and delete. It ++is mainly useful for building shared libstdc++. ++ ++@kindex --dynamic-list-cpp-typeinfo ++@item --dynamic-list-cpp-typeinfo ++Provide the builtin dynamic list for C++ runtime type identification. ++ ++@kindex --check-sections ++@kindex --no-check-sections ++@item --check-sections ++@itemx --no-check-sections ++Asks the linker @emph{not} to check section addresses after they have ++been assigned to see if there are any overlaps. Normally the linker will ++perform this check, and if it finds any overlaps it will produce ++suitable error messages. The linker does know about, and does make ++allowances for sections in overlays. The default behaviour can be ++restored by using the command-line switch @option{--check-sections}. ++Section overlap is not usually checked for relocatable links. You can ++force checking in that case by using the @option{--check-sections} ++option. ++ ++@kindex --copy-dt-needed-entries ++@kindex --no-copy-dt-needed-entries ++@item --copy-dt-needed-entries ++@itemx --no-copy-dt-needed-entries ++This option affects the treatment of dynamic libraries referred to ++by DT_NEEDED tags @emph{inside} ELF dynamic libraries mentioned on the ++command line. Normally the linker won't add a DT_NEEDED tag to the ++output binary for each library mentioned in a DT_NEEDED tag in an ++input dynamic library. With @option{--copy-dt-needed-entries} ++specified on the command line however any dynamic libraries that ++follow it will have their DT_NEEDED entries added. The default ++behaviour can be restored with @option{--no-copy-dt-needed-entries}. ++ ++This option also has an effect on the resolution of symbols in dynamic ++libraries. With @option{--copy-dt-needed-entries} dynamic libraries ++mentioned on the command line will be recursively searched, following ++their DT_NEEDED tags to other libraries, in order to resolve symbols ++required by the output binary. With the default setting however ++the searching of dynamic libraries that follow it will stop with the ++dynamic library itself. No DT_NEEDED links will be traversed to resolve ++symbols. ++ ++@cindex cross reference table ++@kindex --cref ++@item --cref ++Output a cross reference table. If a linker map file is being ++generated, the cross reference table is printed to the map file. ++Otherwise, it is printed on the standard output. ++ ++The format of the table is intentionally simple, so that it may be ++easily processed by a script if necessary. The symbols are printed out, ++sorted by name. For each symbol, a list of file names is given. If the ++symbol is defined, the first file listed is the location of the ++definition. If the symbol is defined as a common value then any files ++where this happens appear next. Finally any files that reference the ++symbol are listed. ++ ++@cindex ctf variables ++@kindex --ctf-variables ++@kindex --no-ctf-variables ++@item --ctf-variables ++@item --no-ctf-variables ++The CTF debuginfo format supports a section which encodes the names and ++types of variables found in the program which do not appear in any symbol ++table. These variables clearly cannot be looked up by address by ++conventional debuggers, so the space used for their types and names is ++usually wasted: the types are usually small but the names are often not. ++@option{--ctf-variables} causes the generation of such a section. ++The default behaviour can be restored with @option{--no-ctf-variables}. ++ ++@cindex ctf type sharing ++@kindex --ctf-share-types ++@item --ctf-share-types=@var{method} ++Adjust the method used to share types between translation units in CTF. ++ ++@table @samp ++@item share-unconflicted ++Put all types that do not have ambiguous definitions into the shared dictionary, ++where debuggers can easily access them, even if they only occur in one ++translation unit. This is the default. ++ ++@item share-duplicated ++Put only types that occur in multiple translation units into the shared ++dictionary: types with only one definition go into per-translation-unit ++dictionaries. Types with ambiguous definitions in multiple translation units ++always go into per-translation-unit dictionaries. This tends to make the CTF ++larger, but may reduce the amount of CTF in the shared dictionary. For very ++large projects this may speed up opening the CTF and save memory in the CTF ++consumer at runtime. ++@end table ++ ++@cindex common allocation ++@kindex --no-define-common ++@item --no-define-common ++This option inhibits the assignment of addresses to common symbols. ++The script command @code{INHIBIT_COMMON_ALLOCATION} has the same effect. ++@xref{Miscellaneous Commands}. ++ ++The @samp{--no-define-common} option allows decoupling ++the decision to assign addresses to Common symbols from the choice ++of the output file type; otherwise a non-Relocatable output type ++forces assigning addresses to Common symbols. ++Using @samp{--no-define-common} allows Common symbols that are referenced ++from a shared library to be assigned addresses only in the main program. ++This eliminates the unused duplicate space in the shared library, ++and also prevents any possible confusion over resolving to the wrong ++duplicate when there are many dynamic modules with specialized search ++paths for runtime symbol resolution. ++ ++@cindex group allocation in linker script ++@cindex section groups ++@cindex COMDAT ++@kindex --force-group-allocation ++@item --force-group-allocation ++This option causes the linker to place section group members like ++normal input sections, and to delete the section groups. This is the ++default behaviour for a final link but this option can be used to ++change the behaviour of a relocatable link (@samp{-r}). The script ++command @code{FORCE_GROUP_ALLOCATION} has the same ++effect. @xref{Miscellaneous Commands}. ++ ++@cindex symbols, from command line ++@kindex --defsym=@var{symbol}=@var{exp} ++@item --defsym=@var{symbol}=@var{expression} ++Create a global symbol in the output file, containing the absolute ++address given by @var{expression}. You may use this option as many ++times as necessary to define multiple symbols in the command line. A ++limited form of arithmetic is supported for the @var{expression} in this ++context: you may give a hexadecimal constant or the name of an existing ++symbol, or use @code{+} and @code{-} to add or subtract hexadecimal ++constants or symbols. If you need more elaborate expressions, consider ++using the linker command language from a script (@pxref{Assignments}). ++@emph{Note:} there should be no white space between @var{symbol}, the ++equals sign (``@key{=}''), and @var{expression}. ++ ++The linker processes @samp{--defsym} arguments and @samp{-T} arguments ++in order, placing @samp{--defsym} before @samp{-T} will define the ++symbol before the linker script from @samp{-T} is processed, while ++placing @samp{--defsym} after @samp{-T} will define the symbol after ++the linker script has been processed. This difference has ++consequences for expressions within the linker script that use the ++@samp{--defsym} symbols, which order is correct will depend on what ++you are trying to achieve. ++ ++@cindex demangling, from command line ++@kindex --demangle[=@var{style}] ++@kindex --no-demangle ++@item --demangle[=@var{style}] ++@itemx --no-demangle ++These options control whether to demangle symbol names in error messages ++and other output. When the linker is told to demangle, it tries to ++present symbol names in a readable fashion: it strips leading ++underscores if they are used by the object file format, and converts C++ ++mangled symbol names into user readable names. Different compilers have ++different mangling styles. The optional demangling style argument can be used ++to choose an appropriate demangling style for your compiler. The linker will ++demangle by default unless the environment variable @samp{COLLECT_NO_DEMANGLE} ++is set. These options may be used to override the default. ++ ++@cindex dynamic linker, from command line ++@kindex -I@var{file} ++@kindex --dynamic-linker=@var{file} ++@item -I@var{file} ++@itemx --dynamic-linker=@var{file} ++Set the name of the dynamic linker. This is only meaningful when ++generating dynamically linked ELF executables. The default dynamic ++linker is normally correct; don't use this unless you know what you are ++doing. ++ ++@kindex --no-dynamic-linker ++@item --no-dynamic-linker ++When producing an executable file, omit the request for a dynamic ++linker to be used at load-time. This is only meaningful for ELF ++executables that contain dynamic relocations, and usually requires ++entry point code that is capable of processing these relocations. ++ ++@kindex --embedded-relocs ++@item --embedded-relocs ++This option is similar to the @option{--emit-relocs} option except ++that the relocs are stored in a target-specific section. This option ++is only supported by the @samp{BFIN}, @samp{CR16} and @emph{M68K} ++targets. ++ ++@kindex --disable-multiple-abs-defs ++@item --disable-multiple-abs-defs ++Do not allow multiple definitions with symbols included ++in filename invoked by -R or --just-symbols ++ ++@kindex --fatal-warnings ++@kindex --no-fatal-warnings ++@item --fatal-warnings ++@itemx --no-fatal-warnings ++Treat all warnings as errors. The default behaviour can be restored ++with the option @option{--no-fatal-warnings}. ++ ++@kindex -w ++@kindex --no-warnings ++@item -w ++@itemx --no-warnings ++Do not display any warning or error messages. This overrides ++@option{--fatal-warnings} if it has been enabled. This option can be ++used when it is known that the output binary will not work, but there ++is still a need to create it. ++ ++@kindex --force-exe-suffix ++@item --force-exe-suffix ++Make sure that an output file has a .exe suffix. ++ ++If a successfully built fully linked output file does not have a ++@code{.exe} or @code{.dll} suffix, this option forces the linker to copy ++the output file to one of the same name with a @code{.exe} suffix. This ++option is useful when using unmodified Unix makefiles on a Microsoft ++Windows host, since some versions of Windows won't run an image unless ++it ends in a @code{.exe} suffix. ++ ++@kindex --gc-sections ++@kindex --no-gc-sections ++@cindex garbage collection ++@item --gc-sections ++@itemx --no-gc-sections ++Enable garbage collection of unused input sections. It is ignored on ++targets that do not support this option. The default behaviour (of not ++performing this garbage collection) can be restored by specifying ++@samp{--no-gc-sections} on the command line. Note that garbage ++collection for COFF and PE format targets is supported, but the ++implementation is currently considered to be experimental. ++ ++@samp{--gc-sections} decides which input sections are used by ++examining symbols and relocations. The section containing the entry ++symbol and all sections containing symbols undefined on the ++command-line will be kept, as will sections containing symbols ++referenced by dynamic objects. Note that when building shared ++libraries, the linker must assume that any visible symbol is ++referenced. Once this initial set of sections has been determined, ++the linker recursively marks as used any section referenced by their ++relocations. See @samp{--entry}, @samp{--undefined}, and ++@samp{--gc-keep-exported}. ++ ++This option can be set when doing a partial link (enabled with option ++@samp{-r}). In this case the root of symbols kept must be explicitly ++specified either by one of the options @samp{--entry}, ++@samp{--undefined}, or @samp{--gc-keep-exported} or by a @code{ENTRY} ++command in the linker script. ++ ++As a GNU extension, ELF input sections marked with the ++@code{SHF_GNU_RETAIN} flag will not be garbage collected. ++ ++@kindex --print-gc-sections ++@kindex --no-print-gc-sections ++@cindex garbage collection ++@item --print-gc-sections ++@itemx --no-print-gc-sections ++List all sections removed by garbage collection. The listing is ++printed on stderr. This option is only effective if garbage ++collection has been enabled via the @samp{--gc-sections}) option. The ++default behaviour (of not listing the sections that are removed) can ++be restored by specifying @samp{--no-print-gc-sections} on the command ++line. ++ ++@kindex --gc-keep-exported ++@cindex garbage collection ++@item --gc-keep-exported ++When @samp{--gc-sections} is enabled, this option prevents garbage ++collection of unused input sections that contain global symbols having ++default or protected visibility. This option is intended to be used for ++executables where unreferenced sections would otherwise be garbage ++collected regardless of the external visibility of contained symbols. ++Note that this option has no effect when linking shared objects since ++it is already the default behaviour. This option is only supported for ++ELF format targets. ++ ++@kindex --print-output-format ++@cindex output format ++@item --print-output-format ++Print the name of the default output format (perhaps influenced by ++other command-line options). This is the string that would appear ++in an @code{OUTPUT_FORMAT} linker script command (@pxref{File Commands}). ++ ++@kindex --print-memory-usage ++@cindex memory usage ++@item --print-memory-usage ++Print used size, total size and used size of memory regions created with ++the @ref{MEMORY} command. This is useful on embedded targets to have a ++quick view of amount of free memory. The format of the output has one ++headline and one line per region. It is both human readable and easily ++parsable by tools. Here is an example of an output: ++ ++@smallexample ++Memory region Used Size Region Size %age Used ++ ROM: 256 KB 1 MB 25.00% ++ RAM: 32 B 2 GB 0.00% ++@end smallexample ++ ++@cindex help ++@cindex usage ++@kindex --help ++@item --help ++Print a summary of the command-line options on the standard output and exit. ++ ++@kindex --target-help ++@item --target-help ++Print a summary of all target-specific options on the standard output and exit. ++ ++@kindex -Map=@var{mapfile} ++@item -Map=@var{mapfile} ++Print a link map to the file @var{mapfile}. See the description of the ++@option{-M} option, above. If @var{mapfile} is just the character ++@code{-} then the map will be written to stdout. ++ ++Specifying a directory as @var{mapfile} causes the linker map to be ++written as a file inside the directory. Normally name of the file ++inside the directory is computed as the basename of the @var{output} ++file with @code{.map} appended. If however the special character ++@code{%} is used then this will be replaced by the full path of the ++output file. Additionally if there are any characters after the ++@var{%} symbol then @code{.map} will no longer be appended. ++ ++@smallexample ++ -o foo.exe -Map=bar [Creates ./bar] ++ -o ../dir/foo.exe -Map=bar [Creates ./bar] ++ -o foo.exe -Map=../dir [Creates ../dir/foo.exe.map] ++ -o ../dir2/foo.exe -Map=../dir [Creates ../dir/foo.exe.map] ++ -o foo.exe -Map=% [Creates ./foo.exe.map] ++ -o ../dir/foo.exe -Map=% [Creates ../dir/foo.exe.map] ++ -o foo.exe -Map=%.bar [Creates ./foo.exe.bar] ++ -o ../dir/foo.exe -Map=%.bar [Creates ../dir/foo.exe.bar] ++ -o ../dir2/foo.exe -Map=../dir/% [Creates ../dir/../dir2/foo.exe.map] ++ -o ../dir2/foo.exe -Map=../dir/%.bar [Creates ../dir/../dir2/foo.exe.bar] ++@end smallexample ++ ++It is an error to specify more than one @code{%} character. ++ ++If the map file already exists then it will be overwritten by this ++operation. ++ ++@cindex memory usage ++@kindex --no-keep-memory ++@item --no-keep-memory ++@command{ld} normally optimizes for speed over memory usage by caching the ++symbol tables of input files in memory. This option tells @command{ld} to ++instead optimize for memory usage, by rereading the symbol tables as ++necessary. This may be required if @command{ld} runs out of memory space ++while linking a large executable. ++ ++@kindex --no-undefined ++@kindex -z defs ++@kindex -z undefs ++@item --no-undefined ++@itemx -z defs ++Report unresolved symbol references from regular object files. This ++is done even if the linker is creating a non-symbolic shared library. ++The switch @option{--[no-]allow-shlib-undefined} controls the ++behaviour for reporting unresolved references found in shared ++libraries being linked in. ++ ++The effects of this option can be reverted by using @code{-z undefs}. ++ ++@kindex --allow-multiple-definition ++@kindex -z muldefs ++@item --allow-multiple-definition ++@itemx -z muldefs ++Normally when a symbol is defined multiple times, the linker will ++report a fatal error. These options allow multiple definitions and the ++first definition will be used. ++ ++@kindex --allow-shlib-undefined ++@kindex --no-allow-shlib-undefined ++@item --allow-shlib-undefined ++@itemx --no-allow-shlib-undefined ++Allows or disallows undefined symbols in shared libraries. ++This switch is similar to @option{--no-undefined} except that it ++determines the behaviour when the undefined symbols are in a ++shared library rather than a regular object file. It does not affect ++how undefined symbols in regular object files are handled. ++ ++The default behaviour is to report errors for any undefined symbols ++referenced in shared libraries if the linker is being used to create ++an executable, but to allow them if the linker is being used to create ++a shared library. ++ ++The reasons for allowing undefined symbol references in shared ++libraries specified at link time are that: ++ ++@itemize @bullet ++@item ++A shared library specified at link time may not be the same as the one ++that is available at load time, so the symbol might actually be ++resolvable at load time. ++@item ++There are some operating systems, eg BeOS and HPPA, where undefined ++symbols in shared libraries are normal. ++ ++The BeOS kernel for example patches shared libraries at load time to ++select whichever function is most appropriate for the current ++architecture. This is used, for example, to dynamically select an ++appropriate memset function. ++@end itemize ++ ++@kindex --error-handling-script=@var{scriptname} ++@item --error-handling-script=@var{scriptname} ++If this option is provided then the linker will invoke ++@var{scriptname} whenever an error is encountered. Currently however ++only two kinds of error are supported: missing symbols and missing ++libraries. Two arguments will be passed to script: the keyword ++``undefined-symbol'' or `missing-lib'' and the @var{name} of the ++undefined symbol or missing library. The intention is that the script ++will provide suggestions to the user as to where the symbol or library ++might be found. After the script has finished then the normal linker ++error message will be displayed. ++ ++The availability of this option is controlled by a configure time ++switch, so it may not be present in specific implementations. ++ ++@kindex --no-undefined-version ++@item --no-undefined-version ++Normally when a symbol has an undefined version, the linker will ignore ++it. This option disallows symbols with undefined version and a fatal error ++will be issued instead. ++ ++@kindex --default-symver ++@item --default-symver ++Create and use a default symbol version (the soname) for unversioned ++exported symbols. ++ ++@kindex --default-imported-symver ++@item --default-imported-symver ++Create and use a default symbol version (the soname) for unversioned ++imported symbols. ++ ++@kindex --no-warn-mismatch ++@item --no-warn-mismatch ++Normally @command{ld} will give an error if you try to link together input ++files that are mismatched for some reason, perhaps because they have ++been compiled for different processors or for different endiannesses. ++This option tells @command{ld} that it should silently permit such possible ++errors. This option should only be used with care, in cases when you ++have taken some special action that ensures that the linker errors are ++inappropriate. ++ ++@kindex --no-warn-search-mismatch ++@item --no-warn-search-mismatch ++Normally @command{ld} will give a warning if it finds an incompatible ++library during a library search. This option silences the warning. ++ ++@kindex --no-whole-archive ++@item --no-whole-archive ++Turn off the effect of the @option{--whole-archive} option for subsequent ++archive files. ++ ++@cindex output file after errors ++@kindex --noinhibit-exec ++@item --noinhibit-exec ++Retain the executable output file whenever it is still usable. ++Normally, the linker will not produce an output file if it encounters ++errors during the link process; it exits without writing an output file ++when it issues any error whatsoever. ++ ++@kindex -nostdlib ++@item -nostdlib ++Only search library directories explicitly specified on the ++command line. Library directories specified in linker scripts ++(including linker scripts specified on the command line) are ignored. ++ ++@ifclear SingleFormat ++@kindex --oformat=@var{output-format} ++@item --oformat=@var{output-format} ++@command{ld} may be configured to support more than one kind of object ++file. If your @command{ld} is configured this way, you can use the ++@samp{--oformat} option to specify the binary format for the output ++object file. Even when @command{ld} is configured to support alternative ++object formats, you don't usually need to specify this, as @command{ld} ++should be configured to produce as a default output format the most ++usual format on each machine. @var{output-format} is a text string, the ++name of a particular format supported by the BFD libraries. (You can ++list the available binary formats with @samp{objdump -i}.) The script ++command @code{OUTPUT_FORMAT} can also specify the output format, but ++this option overrides it. @xref{BFD}. ++@end ifclear ++ ++@kindex --out-implib ++@item --out-implib @var{file} ++Create an import library in @var{file} corresponding to the executable ++the linker is generating (eg. a DLL or ELF program). This import ++library (which should be called @code{*.dll.a} or @code{*.a} for DLLs) ++may be used to link clients against the generated executable; this ++behaviour makes it possible to skip a separate import library creation ++step (eg. @code{dlltool} for DLLs). This option is only available for ++the i386 PE and ELF targetted ports of the linker. ++ ++@kindex -pie ++@kindex --pic-executable ++@item -pie ++@itemx --pic-executable ++@cindex position independent executables ++Create a position independent executable. This is currently only supported on ++ELF platforms. Position independent executables are similar to shared ++libraries in that they are relocated by the dynamic linker to the virtual ++address the OS chooses for them (which can vary between invocations). Like ++normal dynamically linked executables they can be executed and symbols ++defined in the executable cannot be overridden by shared libraries. ++ ++@kindex -no-pie ++@item -no-pie ++@cindex position dependent executables ++Create a position dependent executable. This is the default. ++ ++@kindex -qmagic ++@item -qmagic ++This option is ignored for Linux compatibility. ++ ++@kindex -Qy ++@item -Qy ++This option is ignored for SVR4 compatibility. ++ ++@kindex --relax ++@cindex synthesizing linker ++@cindex relaxing addressing modes ++@cindex --no-relax ++@item --relax ++@itemx --no-relax ++An option with machine dependent effects. ++@ifset GENERIC ++This option is only supported on a few targets. ++@end ifset ++@ifset H8300 ++@xref{H8/300,,@command{ld} and the H8/300}. ++@end ifset ++@ifset XTENSA ++@xref{Xtensa,, @command{ld} and Xtensa Processors}. ++@end ifset ++@ifset M68HC11 ++@xref{M68HC11/68HC12,,@command{ld} and the 68HC11 and 68HC12}. ++@end ifset ++@ifset NIOSII ++@xref{Nios II,,@command{ld} and the Altera Nios II}. ++@end ifset ++@ifset POWERPC ++@xref{PowerPC ELF32,,@command{ld} and PowerPC 32-bit ELF Support}. ++@end ifset ++ ++On some platforms the @option{--relax} option performs target specific, ++global optimizations that become possible when the linker resolves ++addressing in the program, such as relaxing address modes, ++synthesizing new instructions, selecting shorter version of current ++instructions, and combining constant values. ++ ++On some platforms these link time global optimizations may make symbolic ++debugging of the resulting executable impossible. ++@ifset GENERIC ++This is known to be the case for the Matsushita MN10200 and MN10300 ++family of processors. ++@end ifset ++ ++On platforms where the feature is supported, the option ++@option{--no-relax} will disable it. ++ ++On platforms where the feature is not supported, both @option{--relax} ++and @option{--no-relax} are accepted, but ignored. ++ ++@cindex retaining specified symbols ++@cindex stripping all but some symbols ++@cindex symbols, retaining selectively ++@kindex --retain-symbols-file=@var{filename} ++@item --retain-symbols-file=@var{filename} ++Retain @emph{only} the symbols listed in the file @var{filename}, ++discarding all others. @var{filename} is simply a flat file, with one ++symbol name per line. This option is especially useful in environments ++@ifset GENERIC ++(such as VxWorks) ++@end ifset ++where a large global symbol table is accumulated gradually, to conserve ++run-time memory. ++ ++@samp{--retain-symbols-file} does @emph{not} discard undefined symbols, ++or symbols needed for relocations. ++ ++You may only specify @samp{--retain-symbols-file} once in the command ++line. It overrides @samp{-s} and @samp{-S}. ++ ++@ifset GENERIC ++@item -rpath=@var{dir} ++@cindex runtime library search path ++@kindex -rpath=@var{dir} ++Add a directory to the runtime library search path. This is used when ++linking an ELF executable with shared objects. All @option{-rpath} ++arguments are concatenated and passed to the runtime linker, which uses ++them to locate shared objects at runtime. ++ ++The @option{-rpath} option is also used when locating shared objects which ++are needed by shared objects explicitly included in the link; see the ++description of the @option{-rpath-link} option. Searching @option{-rpath} ++in this way is only supported by native linkers and cross linkers which ++have been configured with the @option{--with-sysroot} option. ++ ++If @option{-rpath} is not used when linking an ELF executable, the ++contents of the environment variable @code{LD_RUN_PATH} will be used if it ++is defined. ++ ++The @option{-rpath} option may also be used on SunOS. By default, on ++SunOS, the linker will form a runtime search path out of all the ++@option{-L} options it is given. If a @option{-rpath} option is used, the ++runtime search path will be formed exclusively using the @option{-rpath} ++options, ignoring the @option{-L} options. This can be useful when using ++gcc, which adds many @option{-L} options which may be on NFS mounted ++file systems. ++ ++For compatibility with other ELF linkers, if the @option{-R} option is ++followed by a directory name, rather than a file name, it is treated as ++the @option{-rpath} option. ++@end ifset ++ ++@ifset GENERIC ++@cindex link-time runtime library search path ++@kindex -rpath-link=@var{dir} ++@item -rpath-link=@var{dir} ++When using ELF or SunOS, one shared library may require another. This ++happens when an @code{ld -shared} link includes a shared library as one ++of the input files. ++ ++When the linker encounters such a dependency when doing a non-shared, ++non-relocatable link, it will automatically try to locate the required ++shared library and include it in the link, if it is not included ++explicitly. In such a case, the @option{-rpath-link} option ++specifies the first set of directories to search. The ++@option{-rpath-link} option may specify a sequence of directory names ++either by specifying a list of names separated by colons, or by ++appearing multiple times. ++ ++The tokens @var{$ORIGIN} and @var{$LIB} can appear in these search ++directories. They will be replaced by the full path to the directory ++containing the program or shared object in the case of @var{$ORIGIN} ++and either @samp{lib} - for 32-bit binaries - or @samp{lib64} - for ++64-bit binaries - in the case of @var{$LIB}. ++ ++The alternative form of these tokens - @var{$@{ORIGIN@}} and ++@var{$@{LIB@}} can also be used. The token @var{$PLATFORM} is not ++supported. ++ ++This option should be used with caution as it overrides the search path ++that may have been hard compiled into a shared library. In such a case it ++is possible to use unintentionally a different search path than the ++runtime linker would do. ++ ++The linker uses the following search paths to locate required shared ++libraries: ++ ++@enumerate ++@item ++Any directories specified by @option{-rpath-link} options. ++@item ++Any directories specified by @option{-rpath} options. The difference ++between @option{-rpath} and @option{-rpath-link} is that directories ++specified by @option{-rpath} options are included in the executable and ++used at runtime, whereas the @option{-rpath-link} option is only effective ++at link time. Searching @option{-rpath} in this way is only supported ++by native linkers and cross linkers which have been configured with ++the @option{--with-sysroot} option. ++@item ++On an ELF system, for native linkers, if the @option{-rpath} and ++@option{-rpath-link} options were not used, search the contents of the ++environment variable @code{LD_RUN_PATH}. ++@item ++On SunOS, if the @option{-rpath} option was not used, search any ++directories specified using @option{-L} options. ++@item ++For a native linker, search the contents of the environment ++variable @code{LD_LIBRARY_PATH}. ++@item ++For a native ELF linker, the directories in @code{DT_RUNPATH} or ++@code{DT_RPATH} of a shared library are searched for shared ++libraries needed by it. The @code{DT_RPATH} entries are ignored if ++@code{DT_RUNPATH} entries exist. ++@item ++For a linker for a Linux system, if the file @file{/etc/ld.so.conf} ++exists, the list of directories found in that file. Note: the path ++to this file is prefixed with the @code{sysroot} value, if that is ++defined, and then any @code{prefix} string if the linker was ++configured with the @command{--prefix=} option. ++@item ++For a native linker on a FreeBSD system, any directories specified by ++the @code{_PATH_ELF_HINTS} macro defined in the @file{elf-hints.h} ++header file. ++@item ++Any directories specified by a @code{SEARCH_DIR} command in a ++linker script given on the command line, including scripts specified ++by @option{-T} (but not @option{-dT}). ++@item ++The default directories, normally @file{/lib} and @file{/usr/lib}. ++@item ++Any directories specified by a plugin LDPT_SET_EXTRA_LIBRARY_PATH. ++@item ++Any directories specified by a @code{SEARCH_DIR} command in a default ++linker script. ++@end enumerate ++ ++Note however on Linux based systems there is an additional caveat: If ++the @option{--as-needed} option is active @emph{and} a shared library ++is located which would normally satisfy the search @emph{and} this ++library does not have DT_NEEDED tag for @file{libc.so} ++@emph{and} there is a shared library later on in the set of search ++directories which also satisfies the search @emph{and} ++this second shared library does have a DT_NEEDED tag for ++@file{libc.so} @emph{then} the second library will be selected instead ++of the first. ++ ++If the required shared library is not found, the linker will issue a ++warning and continue with the link. ++ ++@end ifset ++ ++@kindex -shared ++@kindex -Bshareable ++@item -shared ++@itemx -Bshareable ++@cindex shared libraries ++Create a shared library. This is currently only supported on ELF, XCOFF ++and SunOS platforms. On SunOS, the linker will automatically create a ++shared library if the @option{-e} option is not used and there are ++undefined symbols in the link. ++ ++@kindex --sort-common ++@item --sort-common ++@itemx --sort-common=ascending ++@itemx --sort-common=descending ++This option tells @command{ld} to sort the common symbols by alignment in ++ascending or descending order when it places them in the appropriate output ++sections. The symbol alignments considered are sixteen-byte or larger, ++eight-byte, four-byte, two-byte, and one-byte. This is to prevent gaps ++between symbols due to alignment constraints. If no sorting order is ++specified, then descending order is assumed. ++ ++@kindex --sort-section=name ++@item --sort-section=name ++This option will apply @code{SORT_BY_NAME} to all wildcard section ++patterns in the linker script. ++ ++@kindex --sort-section=alignment ++@item --sort-section=alignment ++This option will apply @code{SORT_BY_ALIGNMENT} to all wildcard section ++patterns in the linker script. ++ ++@kindex --spare-dynamic-tags ++@item --spare-dynamic-tags=@var{count} ++This option specifies the number of empty slots to leave in the ++.dynamic section of ELF shared objects. Empty slots may be needed by ++post processing tools, such as the prelinker. The default is 5. ++ ++@kindex --split-by-file ++@item --split-by-file[=@var{size}] ++Similar to @option{--split-by-reloc} but creates a new output section for ++each input file when @var{size} is reached. @var{size} defaults to a ++size of 1 if not given. ++ ++@kindex --split-by-reloc ++@item --split-by-reloc[=@var{count}] ++Tries to creates extra sections in the output file so that no single ++output section in the file contains more than @var{count} relocations. ++This is useful when generating huge relocatable files for downloading into ++certain real time kernels with the COFF object file format; since COFF ++cannot represent more than 65535 relocations in a single section. Note ++that this will fail to work with object file formats which do not ++support arbitrary sections. The linker will not split up individual ++input sections for redistribution, so if a single input section contains ++more than @var{count} relocations one output section will contain that ++many relocations. @var{count} defaults to a value of 32768. ++ ++@kindex --stats ++@item --stats ++Compute and display statistics about the operation of the linker, such ++as execution time and memory usage. ++ ++@kindex --sysroot=@var{directory} ++@item --sysroot=@var{directory} ++Use @var{directory} as the location of the sysroot, overriding the ++configure-time default. This option is only supported by linkers ++that were configured using @option{--with-sysroot}. ++ ++@kindex --task-link ++@item --task-link ++This is used by COFF/PE based targets to create a task-linked object ++file where all of the global symbols have been converted to statics. ++ ++@kindex --traditional-format ++@cindex traditional format ++@item --traditional-format ++For some targets, the output of @command{ld} is different in some ways from ++the output of some existing linker. This switch requests @command{ld} to ++use the traditional format instead. ++ ++@cindex dbx ++For example, on SunOS, @command{ld} combines duplicate entries in the ++symbol string table. This can reduce the size of an output file with ++full debugging information by over 30 percent. Unfortunately, the SunOS ++@code{dbx} program can not read the resulting program (@code{gdb} has no ++trouble). The @samp{--traditional-format} switch tells @command{ld} to not ++combine duplicate entries. ++ ++@kindex --section-start=@var{sectionname}=@var{org} ++@item --section-start=@var{sectionname}=@var{org} ++Locate a section in the output file at the absolute ++address given by @var{org}. You may use this option as many ++times as necessary to locate multiple sections in the command ++line. ++@var{org} must be a single hexadecimal integer; ++for compatibility with other linkers, you may omit the leading ++@samp{0x} usually associated with hexadecimal values. @emph{Note:} there ++should be no white space between @var{sectionname}, the equals ++sign (``@key{=}''), and @var{org}. ++ ++@kindex -Tbss=@var{org} ++@kindex -Tdata=@var{org} ++@kindex -Ttext=@var{org} ++@cindex segment origins, cmd line ++@item -Tbss=@var{org} ++@itemx -Tdata=@var{org} ++@itemx -Ttext=@var{org} ++Same as @option{--section-start}, with @code{.bss}, @code{.data} or ++@code{.text} as the @var{sectionname}. ++ ++@kindex -Ttext-segment=@var{org} ++@item -Ttext-segment=@var{org} ++@cindex text segment origin, cmd line ++When creating an ELF executable, it will set the address of the first ++byte of the text segment. ++ ++@kindex -Trodata-segment=@var{org} ++@item -Trodata-segment=@var{org} ++@cindex rodata segment origin, cmd line ++When creating an ELF executable or shared object for a target where ++the read-only data is in its own segment separate from the executable ++text, it will set the address of the first byte of the read-only data segment. ++ ++@kindex -Tldata-segment=@var{org} ++@item -Tldata-segment=@var{org} ++@cindex ldata segment origin, cmd line ++When creating an ELF executable or shared object for x86-64 medium memory ++model, it will set the address of the first byte of the ldata segment. ++ ++@kindex --unresolved-symbols ++@item --unresolved-symbols=@var{method} ++Determine how to handle unresolved symbols. There are four possible ++values for @samp{method}: ++ ++@table @samp ++@item ignore-all ++Do not report any unresolved symbols. ++ ++@item report-all ++Report all unresolved symbols. This is the default. ++ ++@item ignore-in-object-files ++Report unresolved symbols that are contained in shared libraries, but ++ignore them if they come from regular object files. ++ ++@item ignore-in-shared-libs ++Report unresolved symbols that come from regular object files, but ++ignore them if they come from shared libraries. This can be useful ++when creating a dynamic binary and it is known that all the shared ++libraries that it should be referencing are included on the linker's ++command line. ++@end table ++ ++The behaviour for shared libraries on their own can also be controlled ++by the @option{--[no-]allow-shlib-undefined} option. ++ ++Normally the linker will generate an error message for each reported ++unresolved symbol but the option @option{--warn-unresolved-symbols} ++can change this to a warning. ++ ++@kindex --verbose[=@var{NUMBER}] ++@cindex verbose[=@var{NUMBER}] ++@item --dll-verbose ++@itemx --verbose[=@var{NUMBER}] ++Display the version number for @command{ld} and list the linker emulations ++supported. Display which input files can and cannot be opened. Display ++the linker script being used by the linker. If the optional @var{NUMBER} ++argument > 1, plugin symbol status will also be displayed. ++ ++@kindex --version-script=@var{version-scriptfile} ++@cindex version script, symbol versions ++@item --version-script=@var{version-scriptfile} ++Specify the name of a version script to the linker. This is typically ++used when creating shared libraries to specify additional information ++about the version hierarchy for the library being created. This option ++is only fully supported on ELF platforms which support shared libraries; ++see @ref{VERSION}. It is partially supported on PE platforms, which can ++use version scripts to filter symbol visibility in auto-export mode: any ++symbols marked @samp{local} in the version script will not be exported. ++@xref{WIN32}. ++ ++@kindex --warn-common ++@cindex warnings, on combining symbols ++@cindex combining symbols, warnings on ++@item --warn-common ++Warn when a common symbol is combined with another common symbol or with ++a symbol definition. Unix linkers allow this somewhat sloppy practice, ++but linkers on some other operating systems do not. This option allows ++you to find potential problems from combining global symbols. ++Unfortunately, some C libraries use this practice, so you may get some ++warnings about symbols in the libraries as well as in your programs. ++ ++There are three kinds of global symbols, illustrated here by C examples: ++ ++@table @samp ++@item int i = 1; ++A definition, which goes in the initialized data section of the output ++file. ++ ++@item extern int i; ++An undefined reference, which does not allocate space. ++There must be either a definition or a common symbol for the ++variable somewhere. ++ ++@item int i; ++A common symbol. If there are only (one or more) common symbols for a ++variable, it goes in the uninitialized data area of the output file. ++The linker merges multiple common symbols for the same variable into a ++single symbol. If they are of different sizes, it picks the largest ++size. The linker turns a common symbol into a declaration, if there is ++a definition of the same variable. ++@end table ++ ++The @samp{--warn-common} option can produce five kinds of warnings. ++Each warning consists of a pair of lines: the first describes the symbol ++just encountered, and the second describes the previous symbol ++encountered with the same name. One or both of the two symbols will be ++a common symbol. ++ ++@enumerate ++@item ++Turning a common symbol into a reference, because there is already a ++definition for the symbol. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overridden by definition ++@var{file}(@var{section}): warning: defined here ++@end smallexample ++ ++@item ++Turning a common symbol into a reference, because a later definition for ++the symbol is encountered. This is the same as the previous case, ++except that the symbols are encountered in a different order. ++@smallexample ++@var{file}(@var{section}): warning: definition of `@var{symbol}' ++ overriding common ++@var{file}(@var{section}): warning: common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous same-sized common symbol. ++@smallexample ++@var{file}(@var{section}): warning: multiple common ++ of `@var{symbol}' ++@var{file}(@var{section}): warning: previous common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous larger common symbol. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overridden by larger common ++@var{file}(@var{section}): warning: larger common is here ++@end smallexample ++ ++@item ++Merging a common symbol with a previous smaller common symbol. This is ++the same as the previous case, except that the symbols are ++encountered in a different order. ++@smallexample ++@var{file}(@var{section}): warning: common of `@var{symbol}' ++ overriding smaller common ++@var{file}(@var{section}): warning: smaller common is here ++@end smallexample ++@end enumerate ++ ++@kindex --warn-constructors ++@item --warn-constructors ++Warn if any global constructors are used. This is only useful for a few ++object file formats. For formats like COFF or ELF, the linker can not ++detect the use of global constructors. ++ ++@kindex --warn-execstack ++@cindex warnings, on executable stack ++@cindex executable stack, warnings on ++@item --warn-execstack ++@itemx --warn-execstack-objects ++@itemx --no-warn-execstack ++On ELF platforms the linker may generate warning messages if it is ++asked to create an output file that contains an executable stack. ++There are three possible states: ++@enumerate ++@item ++Do not generate any warnings. ++@item ++Always generate warnings, even if the executable stack is requested ++via the @option{-z execstack} command line option. ++@item ++Only generate a warning if an object file requests an executable ++stack, but not if the @option{-z execstack} option is used. ++@end enumerate ++ ++The default state depends upon how the linker was configured when it ++was built. The @option{--no-warn-execstack} option always puts the ++linker into the no-warnings state. The @option{--warn-execstack} ++option puts the linker into the warn-always state. The ++@option{--warn-execstack-objects} option puts the linker into the ++warn-for-object-files-only state. ++ ++Note: ELF format input files can specify that they need an executable ++stack by having a @var{.note.GNU-stack} section with the executable ++bit set in its section flags. They can specify that they do not need ++an executable stack by having the same section, but without the ++executable flag bit set. If an input file does not have a ++@var{.note.GNU-stack} section then the default behaviour is target ++specific. For some targets, then absence of such a section implies ++that an executable stack @emph{is} required. This is often a problem ++for hand crafted assembler files. ++ ++@kindex --error-execstack ++@item --error-execstack ++@itemx --no-error-execstack ++If the linker is going to generate a warning message about an ++executable stack then the @option{--error-execstack} option will ++instead change that warning into an error. Note - this option does ++not change the linker's execstack warning generation state. Use ++@option{--warn-execstack} or @option{--warn-execstack-objects} to set ++a specific warning state. ++ ++The @option{--no-error-execstack} option will restore the default ++behaviour of generating warning messages. ++ ++@kindex --warn-multiple-gp ++@item --warn-multiple-gp ++Warn if multiple global pointer values are required in the output file. ++This is only meaningful for certain processors, such as the Alpha. ++Specifically, some processors put large-valued constants in a special ++section. A special register (the global pointer) points into the middle ++of this section, so that constants can be loaded efficiently via a ++base-register relative addressing mode. Since the offset in ++base-register relative mode is fixed and relatively small (e.g., 16 ++bits), this limits the maximum size of the constant pool. Thus, in ++large programs, it is often necessary to use multiple global pointer ++values in order to be able to address all possible constants. This ++option causes a warning to be issued whenever this case occurs. ++ ++@kindex --warn-once ++@cindex warnings, on undefined symbols ++@cindex undefined symbols, warnings on ++@item --warn-once ++Only warn once for each undefined symbol, rather than once per module ++which refers to it. ++ ++@kindex --warn-rwx-segments ++@cindex warnings, on writeable and exectuable segments ++@cindex executable segments, warnings on ++@item --warn-rwx-segments ++@itemx --no-warn-rwx-segments ++Warn if the linker creates a loadable, non-zero sized segment that has ++all three of the read, write and execute permission flags set. Such a ++segment represents a potential security vulnerability. In addition ++warnings will be generated if a thread local storage segment is ++created with the execute permission flag set, regardless of whether or ++not it has the read and/or write flags set. ++ ++These warnings are enabled by default. They can be disabled via the ++@option{--no-warn-rwx-segments} option and re-enabled via the ++@option{--warn-rwx-segments} option. ++ ++@kindex --error-rwx-segments ++@item --error-rwx-segments ++@itemx --no-error-rwx-segments ++If the linker is going to generate a warning message about an ++executable, writeable segment, or an executable TLS segment, then the ++@option{--error-rwx-segments} option will turn this warning into an ++error instead. The @option{--no-error-rwx-segments} option will ++restore the default behaviour of just generating a warning message. ++ ++Note - the @option{--error-rwx-segments} option does not by itself ++turn on warnings about these segments. These warnings are either ++enabled by default, if the linker was configured that way, or via the ++@option{--warn-rwx-segments} command line option. ++ ++@kindex --warn-section-align ++@cindex warnings, on section alignment ++@cindex section alignment, warnings on ++@item --warn-section-align ++Warn if the address of an output section is changed because of ++alignment. Typically, the alignment will be set by an input section. ++The address will only be changed if it not explicitly specified; that ++is, if the @code{SECTIONS} command does not specify a start address for ++the section (@pxref{SECTIONS}). ++ ++@kindex --warn-textrel ++@item --warn-textrel ++Warn if the linker adds DT_TEXTREL to a position-independent executable ++or shared object. ++ ++@kindex --warn-alternate-em ++@item --warn-alternate-em ++Warn if an object has alternate ELF machine code. ++ ++@kindex --warn-unresolved-symbols ++@item --warn-unresolved-symbols ++If the linker is going to report an unresolved symbol (see the option ++@option{--unresolved-symbols}) it will normally generate an error. ++This option makes it generate a warning instead. ++ ++@kindex --error-unresolved-symbols ++@item --error-unresolved-symbols ++This restores the linker's default behaviour of generating errors when ++it is reporting unresolved symbols. ++ ++@kindex --whole-archive ++@cindex including an entire archive ++@item --whole-archive ++For each archive mentioned on the command line after the ++@option{--whole-archive} option, include every object file in the archive ++in the link, rather than searching the archive for the required object ++files. This is normally used to turn an archive file into a shared ++library, forcing every object to be included in the resulting shared ++library. This option may be used more than once. ++ ++Two notes when using this option from gcc: First, gcc doesn't know ++about this option, so you have to use @option{-Wl,-whole-archive}. ++Second, don't forget to use @option{-Wl,-no-whole-archive} after your ++list of archives, because gcc will add its own list of archives to ++your link and you may not want this flag to affect those as well. ++ ++@kindex --wrap=@var{symbol} ++@item --wrap=@var{symbol} ++Use a wrapper function for @var{symbol}. Any undefined reference to ++@var{symbol} will be resolved to @code{__wrap_@var{symbol}}. Any ++undefined reference to @code{__real_@var{symbol}} will be resolved to ++@var{symbol}. ++ ++This can be used to provide a wrapper for a system function. The ++wrapper function should be called @code{__wrap_@var{symbol}}. If it ++wishes to call the system function, it should call ++@code{__real_@var{symbol}}. ++ ++Here is a trivial example: ++ ++@smallexample ++void * ++__wrap_malloc (size_t c) ++@{ ++ printf ("malloc called with %zu\n", c); ++ return __real_malloc (c); ++@} ++@end smallexample ++ ++If you link other code with this file using @option{--wrap malloc}, then ++all calls to @code{malloc} will call the function @code{__wrap_malloc} ++instead. The call to @code{__real_malloc} in @code{__wrap_malloc} will ++call the real @code{malloc} function. ++ ++You may wish to provide a @code{__real_malloc} function as well, so that ++links without the @option{--wrap} option will succeed. If you do this, ++you should not put the definition of @code{__real_malloc} in the same ++file as @code{__wrap_malloc}; if you do, the assembler may resolve the ++call before the linker has a chance to wrap it to @code{malloc}. ++ ++Only undefined references are replaced by the linker. So, translation unit ++internal references to @var{symbol} are not resolved to ++@code{__wrap_@var{symbol}}. In the next example, the call to @code{f} in ++@code{g} is not resolved to @code{__wrap_f}. ++ ++@smallexample ++int ++f (void) ++@{ ++ return 123; ++@} ++ ++int ++g (void) ++@{ ++ return f(); ++@} ++@end smallexample ++ ++@kindex --eh-frame-hdr ++@kindex --no-eh-frame-hdr ++@item --eh-frame-hdr ++@itemx --no-eh-frame-hdr ++Request (@option{--eh-frame-hdr}) or suppress ++(@option{--no-eh-frame-hdr}) the creation of @code{.eh_frame_hdr} ++section and ELF @code{PT_GNU_EH_FRAME} segment header. ++ ++@kindex --ld-generated-unwind-info ++@item --no-ld-generated-unwind-info ++Request creation of @code{.eh_frame} unwind info for linker ++generated code sections like PLT. This option is on by default ++if linker generated unwind info is supported. This option also ++controls the generation of @code{.sframe} stack trace info for linker ++generated code sections like PLT. ++ ++@kindex --enable-new-dtags ++@kindex --disable-new-dtags ++@item --enable-new-dtags ++@itemx --disable-new-dtags ++This linker can create the new dynamic tags in ELF. But the older ELF ++systems may not understand them. If you specify ++@option{--enable-new-dtags}, the new dynamic tags will be created as needed ++and older dynamic tags will be omitted. ++If you specify @option{--disable-new-dtags}, no new dynamic tags will be ++created. By default, the new dynamic tags are created. Note that ++those options are only available for ELF systems. ++ ++@kindex --hash-size=@var{number} ++@item --hash-size=@var{number} ++Set the default size of the linker's hash tables to a prime number ++close to @var{number}. Increasing this value can reduce the length of ++time it takes the linker to perform its tasks, at the expense of ++increasing the linker's memory requirements. Similarly reducing this ++value can reduce the memory requirements at the expense of speed. ++ ++@kindex --hash-style=@var{style} ++@item --hash-style=@var{style} ++Set the type of linker's hash table(s). @var{style} can be either ++@code{sysv} for classic ELF @code{.hash} section, @code{gnu} for ++new style GNU @code{.gnu.hash} section or @code{both} for both ++the classic ELF @code{.hash} and new style GNU @code{.gnu.hash} ++hash tables. The default depends upon how the linker was configured, ++but for most Linux based systems it will be @code{both}. ++ ++@kindex --compress-debug-sections=none ++@kindex --compress-debug-sections=zlib ++@kindex --compress-debug-sections=zlib-gnu ++@kindex --compress-debug-sections=zlib-gabi ++@kindex --compress-debug-sections=zstd ++@item --compress-debug-sections=none ++@itemx --compress-debug-sections=zlib ++@itemx --compress-debug-sections=zlib-gnu ++@itemx --compress-debug-sections=zlib-gabi ++@itemx --compress-debug-sections=zstd ++On ELF platforms, these options control how DWARF debug sections are ++compressed using zlib. ++ ++@option{--compress-debug-sections=none} doesn't compress DWARF debug ++sections. @option{--compress-debug-sections=zlib-gnu} compresses ++DWARF debug sections and renames them to begin with @samp{.zdebug} ++instead of @samp{.debug}. @option{--compress-debug-sections=zlib-gabi} ++also compresses DWARF debug sections, but rather than renaming them it ++sets the SHF_COMPRESSED flag in the sections' headers. ++ ++The @option{--compress-debug-sections=zlib} option is an alias for ++@option{--compress-debug-sections=zlib-gabi}. ++ ++@option{--compress-debug-sections=zstd} compresses DWARF debug sections using ++zstd. ++ ++Note that this option overrides any compression in input debug ++sections, so if a binary is linked with @option{--compress-debug-sections=none} ++for example, then any compressed debug sections in input files will be ++uncompressed before they are copied into the output binary. ++ ++The default compression behaviour varies depending upon the target ++involved and the configure options used to build the toolchain. The ++default can be determined by examining the output from the linker's ++@option{--help} option. ++ ++@kindex --reduce-memory-overheads ++@item --reduce-memory-overheads ++This option reduces memory requirements at ld runtime, at the expense of ++linking speed. This was introduced to select the old O(n^2) algorithm ++for link map file generation, rather than the new O(n) algorithm which uses ++about 40% more memory for symbol storage. ++ ++Another effect of the switch is to set the default hash table size to ++1021, which again saves memory at the cost of lengthening the linker's ++run time. This is not done however if the @option{--hash-size} switch ++has been used. ++ ++The @option{--reduce-memory-overheads} switch may be also be used to ++enable other tradeoffs in future versions of the linker. ++ ++@kindex --max-cache-size=@var{size} ++@item --max-cache-size=@var{size} ++@command{ld} normally caches the relocation information and symbol tables ++of input files in memory with the unlimited size. This option sets the ++maximum cache size to @var{size}. ++ ++@kindex --build-id ++@kindex --build-id=@var{style} ++@item --build-id ++@itemx --build-id=@var{style} ++Request the creation of a @code{.note.gnu.build-id} ELF note section ++or a @code{.buildid} COFF section. The contents of the note are ++unique bits identifying this linked file. @var{style} can be ++@code{uuid} to use 128 random bits, @code{sha1} to use a 160-bit ++@sc{SHA1} hash on the normative parts of the output contents, ++@code{md5} to use a 128-bit @sc{MD5} hash on the normative parts of ++the output contents, or @code{0x@var{hexstring}} to use a chosen bit ++string specified as an even number of hexadecimal digits (@code{-} and ++@code{:} characters between digit pairs are ignored). If @var{style} ++is omitted, @code{sha1} is used. ++ ++The @code{md5} and @code{sha1} styles produces an identifier ++that is always the same in an identical output file, but will be ++unique among all nonidentical output files. It is not intended ++to be compared as a checksum for the file's contents. A linked ++file may be changed later by other tools, but the build ID bit ++string identifying the original linked file does not change. ++ ++Passing @code{none} for @var{style} disables the setting from any ++@code{--build-id} options earlier on the command line. ++ ++@kindex --package-metadata=@var{JSON} ++@item --package-metadata=@var{JSON} ++Request the creation of a @code{.note.package} ELF note section. The ++contents of the note are in JSON format, as per the package metadata ++specification. For more information see: ++https://systemd.io/ELF_PACKAGE_METADATA/ ++If the JSON argument is missing/empty then this will disable the ++creation of the metadata note, if one had been enabled by an earlier ++occurrence of the --package-metdata option. ++If the linker has been built with libjansson, then the JSON string ++will be validated. ++@end table ++ ++@c man end ++ ++@subsection Options Specific to i386 PE Targets ++ ++@c man begin OPTIONS ++ ++The i386 PE linker supports the @option{-shared} option, which causes ++the output to be a dynamically linked library (DLL) instead of a ++normal executable. You should name the output @code{*.dll} when you ++use this option. In addition, the linker fully supports the standard ++@code{*.def} files, which may be specified on the linker command line ++like an object file (in fact, it should precede archives it exports ++symbols from, to ensure that they get linked in, just like a normal ++object file). ++ ++In addition to the options common to all targets, the i386 PE linker ++support additional command-line options that are specific to the i386 ++PE target. Options that take values may be separated from their ++values by either a space or an equals sign. ++ ++@table @gcctabopt ++ ++@kindex --add-stdcall-alias ++@item --add-stdcall-alias ++If given, symbols with a stdcall suffix (@@@var{nn}) will be exported ++as-is and also with the suffix stripped. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --base-file ++@item --base-file @var{file} ++Use @var{file} as the name of a file in which to save the base ++addresses of all the relocations needed for generating DLLs with ++@file{dlltool}. ++[This is an i386 PE specific option] ++ ++@kindex --dll ++@item --dll ++Create a DLL instead of a regular executable. You may also use ++@option{-shared} or specify a @code{LIBRARY} in a given @code{.def} ++file. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-long-section-names ++@kindex --disable-long-section-names ++@item --enable-long-section-names ++@itemx --disable-long-section-names ++The PE variants of the COFF object format add an extension that permits ++the use of section names longer than eight characters, the normal limit ++for COFF. By default, these names are only allowed in object files, as ++fully-linked executable images do not carry the COFF string table required ++to support the longer names. As a GNU extension, it is possible to ++allow their use in executable images as well, or to (probably pointlessly!) ++disallow it in object files, by using these two options. Executable images ++generated with these long section names are slightly non-standard, carrying ++as they do a string table, and may generate confusing output when examined ++with non-GNU PE-aware tools, such as file viewers and dumpers. However, ++GDB relies on the use of PE long section names to find Dwarf-2 debug ++information sections in an executable image at runtime, and so if neither ++option is specified on the command-line, @command{ld} will enable long ++section names, overriding the default and technically correct behaviour, ++when it finds the presence of debug information while linking an executable ++image and not stripping symbols. ++[This option is valid for all PE targeted ports of the linker] ++ ++@kindex --enable-stdcall-fixup ++@kindex --disable-stdcall-fixup ++@item --enable-stdcall-fixup ++@itemx --disable-stdcall-fixup ++If the link finds a symbol that it cannot resolve, it will attempt to ++do ``fuzzy linking'' by looking for another defined symbol that differs ++only in the format of the symbol name (cdecl vs stdcall) and will ++resolve that symbol by linking to the match. For example, the ++undefined symbol @code{_foo} might be linked to the function ++@code{_foo@@12}, or the undefined symbol @code{_bar@@16} might be linked ++to the function @code{_bar}. When the linker does this, it prints a ++warning, since it normally should have failed to link, but sometimes ++import libraries generated from third-party dlls may need this feature ++to be usable. If you specify @option{--enable-stdcall-fixup}, this ++feature is fully enabled and warnings are not printed. If you specify ++@option{--disable-stdcall-fixup}, this feature is disabled and such ++mismatches are considered to be errors. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --leading-underscore ++@kindex --no-leading-underscore ++@item --leading-underscore ++@itemx --no-leading-underscore ++For most targets default symbol-prefix is an underscore and is defined ++in target's description. By this option it is possible to ++disable/enable the default underscore symbol-prefix. ++ ++@cindex DLLs, creating ++@kindex --export-all-symbols ++@item --export-all-symbols ++If given, all global symbols in the objects used to build a DLL will ++be exported by the DLL. Note that this is the default if there ++otherwise wouldn't be any exported symbols. When symbols are ++explicitly exported via DEF files or implicitly exported via function ++attributes, the default is to not export anything else unless this ++option is given. Note that the symbols @code{DllMain@@12}, ++@code{DllEntryPoint@@0}, @code{DllMainCRTStartup@@12}, and ++@code{impure_ptr} will not be automatically ++exported. Also, symbols imported from other DLLs will not be ++re-exported, nor will symbols specifying the DLL's internal layout ++such as those beginning with @code{_head_} or ending with ++@code{_iname}. In addition, no symbols from @code{libgcc}, ++@code{libstd++}, @code{libmingw32}, or @code{crtX.o} will be exported. ++Symbols whose names begin with @code{__rtti_} or @code{__builtin_} will ++not be exported, to help with C++ DLLs. Finally, there is an ++extensive list of cygwin-private symbols that are not exported ++(obviously, this applies on when building DLLs for cygwin targets). ++These cygwin-excludes are: @code{_cygwin_dll_entry@@12}, ++@code{_cygwin_crt0_common@@8}, @code{_cygwin_noncygwin_dll_entry@@12}, ++@code{_fmode}, @code{_impure_ptr}, @code{cygwin_attach_dll}, ++@code{cygwin_premain0}, @code{cygwin_premain1}, @code{cygwin_premain2}, ++@code{cygwin_premain3}, and @code{environ}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --exclude-symbols ++@item --exclude-symbols @var{symbol},@var{symbol},... ++Specifies a list of symbols which should not be automatically ++exported. The symbol names may be delimited by commas or colons. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --exclude-all-symbols ++@item --exclude-all-symbols ++Specifies no symbols should be automatically exported. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --file-alignment ++@item --file-alignment ++Specify the file alignment. Sections in the file will always begin at ++file offsets which are multiples of this number. This defaults to ++512. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex heap size ++@kindex --heap ++@item --heap @var{reserve} ++@itemx --heap @var{reserve},@var{commit} ++Specify the number of bytes of memory to reserve (and optionally commit) ++to be used as heap for this program. The default is 1MB reserved, 4K ++committed. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex image base ++@kindex --image-base ++@item --image-base @var{value} ++Use @var{value} as the base address of your program or dll. This is ++the lowest memory location that will be used when your program or dll ++is loaded. To reduce the need to relocate and improve performance of ++your dlls, each should have a unique base address and not overlap any ++other dlls. The default is 0x400000 for executables, and 0x10000000 ++for dlls. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --kill-at ++@item --kill-at ++If given, the stdcall suffixes (@@@var{nn}) will be stripped from ++symbols before they are exported. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --large-address-aware ++@item --large-address-aware ++If given, the appropriate bit in the ``Characteristics'' field of the COFF ++header is set to indicate that this executable supports virtual addresses ++greater than 2 gigabytes. This should be used in conjunction with the /3GB ++or /USERVA=@var{value} megabytes switch in the ``[operating systems]'' ++section of the BOOT.INI. Otherwise, this bit has no effect. ++[This option is specific to PE targeted ports of the linker] ++ ++@kindex --disable-large-address-aware ++@item --disable-large-address-aware ++Reverts the effect of a previous @samp{--large-address-aware} option. ++This is useful if @samp{--large-address-aware} is always set by the compiler ++driver (e.g. Cygwin gcc) and the executable does not support virtual ++addresses greater than 2 gigabytes. ++[This option is specific to PE targeted ports of the linker] ++ ++@kindex --major-image-version ++@item --major-image-version @var{value} ++Sets the major number of the ``image version''. Defaults to 1. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --major-os-version ++@item --major-os-version @var{value} ++Sets the major number of the ``os version''. Defaults to 4. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --major-subsystem-version ++@item --major-subsystem-version @var{value} ++Sets the major number of the ``subsystem version''. Defaults to 4. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-image-version ++@item --minor-image-version @var{value} ++Sets the minor number of the ``image version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-os-version ++@item --minor-os-version @var{value} ++Sets the minor number of the ``os version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --minor-subsystem-version ++@item --minor-subsystem-version @var{value} ++Sets the minor number of the ``subsystem version''. Defaults to 0. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DEF files, creating ++@cindex DLLs, creating ++@kindex --output-def ++@item --output-def @var{file} ++The linker will create the file @var{file} which will contain a DEF ++file corresponding to the DLL the linker is generating. This DEF file ++(which should be called @code{*.def}) may be used to create an import ++library with @code{dlltool} or may be used as a reference to ++automatically or implicitly exported symbols. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DLLs, creating ++@kindex --enable-auto-image-base ++@item --enable-auto-image-base ++@itemx --enable-auto-image-base=@var{value} ++Automatically choose the image base for DLLs, optionally starting with base ++@var{value}, unless one is specified using the @code{--image-base} argument. ++By using a hash generated from the dllname to create unique image bases ++for each DLL, in-memory collisions and relocations which can delay program ++execution are avoided. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --disable-auto-image-base ++@item --disable-auto-image-base ++Do not automatically generate a unique image base. If there is no ++user-specified image base (@code{--image-base}) then use the platform ++default. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex DLLs, linking to ++@kindex --dll-search-prefix ++@item --dll-search-prefix @var{string} ++When linking dynamically to a dll without an import library, ++search for @code{.dll} in preference to ++@code{lib.dll}. This behaviour allows easy distinction ++between DLLs built for the various "subplatforms": native, cygwin, ++uwin, pw, etc. For instance, cygwin DLLs typically use ++@code{--dll-search-prefix=cyg}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-auto-import ++@item --enable-auto-import ++Do sophisticated linking of @code{_symbol} to @code{__imp__symbol} for ++DATA imports from DLLs, thus making it possible to bypass the dllimport ++mechanism on the user side and to reference unmangled symbol names. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++The following remarks pertain to the original implementation of the ++feature and are obsolete nowadays for Cygwin and MinGW targets. ++ ++Note: Use of the 'auto-import' extension will cause the text section ++of the image file to be made writable. This does not conform to the ++PE-COFF format specification published by Microsoft. ++ ++Note - use of the 'auto-import' extension will also cause read only ++data which would normally be placed into the .rdata section to be ++placed into the .data section instead. This is in order to work ++around a problem with consts that is described here: ++http://www.cygwin.com/ml/cygwin/2004-09/msg01101.html ++ ++Using 'auto-import' generally will 'just work' -- but sometimes you may ++see this message: ++ ++"variable '' can't be auto-imported. Please read the ++documentation for ld's @code{--enable-auto-import} for details." ++ ++This message occurs when some (sub)expression accesses an address ++ultimately given by the sum of two constants (Win32 import tables only ++allow one). Instances where this may occur include accesses to member ++fields of struct variables imported from a DLL, as well as using a ++constant index into an array variable imported from a DLL. Any ++multiword variable (arrays, structs, long long, etc) may trigger ++this error condition. However, regardless of the exact data type ++of the offending exported variable, ld will always detect it, issue ++the warning, and exit. ++ ++There are several ways to address this difficulty, regardless of the ++data type of the exported variable: ++ ++One way is to use --enable-runtime-pseudo-reloc switch. This leaves the task ++of adjusting references in your client code for runtime environment, so ++this method works only when runtime environment supports this feature. ++ ++A second solution is to force one of the 'constants' to be a variable -- ++that is, unknown and un-optimizable at compile time. For arrays, ++there are two possibilities: a) make the indexee (the array's address) ++a variable, or b) make the 'constant' index a variable. Thus: ++ ++@example ++extern type extern_array[]; ++extern_array[1] --> ++ @{ volatile type *t=extern_array; t[1] @} ++@end example ++ ++or ++ ++@example ++extern type extern_array[]; ++extern_array[1] --> ++ @{ volatile int t=1; extern_array[t] @} ++@end example ++ ++For structs (and most other multiword data types) the only option ++is to make the struct itself (or the long long, or the ...) variable: ++ ++@example ++extern struct s extern_struct; ++extern_struct.field --> ++ @{ volatile struct s *t=&extern_struct; t->field @} ++@end example ++ ++or ++ ++@example ++extern long long extern_ll; ++extern_ll --> ++ @{ volatile long long * local_ll=&extern_ll; *local_ll @} ++@end example ++ ++A third method of dealing with this difficulty is to abandon ++'auto-import' for the offending symbol and mark it with ++@code{__declspec(dllimport)}. However, in practice that ++requires using compile-time #defines to indicate whether you are ++building a DLL, building client code that will link to the DLL, or ++merely building/linking to a static library. In making the choice ++between the various methods of resolving the 'direct address with ++constant offset' problem, you should consider typical real-world usage: ++ ++Original: ++@example ++--foo.h ++extern int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ printf("%d\n",arr[1]); ++@} ++@end example ++ ++Solution 1: ++@example ++--foo.h ++extern int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ /* This workaround is for win32 and cygwin; do not "optimize" */ ++ volatile int *parr = arr; ++ printf("%d\n",parr[1]); ++@} ++@end example ++ ++Solution 2: ++@example ++--foo.h ++/* Note: auto-export is assumed (no __declspec(dllexport)) */ ++#if (defined(_WIN32) || defined(__CYGWIN__)) && \ ++ !(defined(FOO_BUILD_DLL) || defined(FOO_STATIC)) ++#define FOO_IMPORT __declspec(dllimport) ++#else ++#define FOO_IMPORT ++#endif ++extern FOO_IMPORT int arr[]; ++--foo.c ++#include "foo.h" ++void main(int argc, char **argv)@{ ++ printf("%d\n",arr[1]); ++@} ++@end example ++ ++A fourth way to avoid this problem is to re-code your ++library to use a functional interface rather than a data interface ++for the offending variables (e.g. set_foo() and get_foo() accessor ++functions). ++ ++@kindex --disable-auto-import ++@item --disable-auto-import ++Do not attempt to do sophisticated linking of @code{_symbol} to ++@code{__imp__symbol} for DATA imports from DLLs. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-runtime-pseudo-reloc ++@item --enable-runtime-pseudo-reloc ++If your code contains expressions described in --enable-auto-import section, ++that is, DATA imports from DLL with non-zero offset, this switch will create ++a vector of 'runtime pseudo relocations' which can be used by runtime ++environment to adjust references to such data in your client code. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --disable-runtime-pseudo-reloc ++@item --disable-runtime-pseudo-reloc ++Do not create pseudo relocations for non-zero offset DATA imports from DLLs. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --enable-extra-pe-debug ++@item --enable-extra-pe-debug ++Show additional debug info related to auto-import symbol thunking. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --section-alignment ++@item --section-alignment ++Sets the section alignment. Sections in memory will always begin at ++addresses which are a multiple of this number. Defaults to 0x1000. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@cindex stack size ++@kindex --stack ++@item --stack @var{reserve} ++@itemx --stack @var{reserve},@var{commit} ++Specify the number of bytes of memory to reserve (and optionally commit) ++to be used as stack for this program. The default is 2MB reserved, 4K ++committed. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++@kindex --subsystem ++@item --subsystem @var{which} ++@itemx --subsystem @var{which}:@var{major} ++@itemx --subsystem @var{which}:@var{major}.@var{minor} ++Specifies the subsystem under which your program will execute. The ++legal values for @var{which} are @code{native}, @code{windows}, ++@code{console}, @code{posix}, and @code{xbox}. You may optionally set ++the subsystem version also. Numeric values are also accepted for ++@var{which}. ++[This option is specific to the i386 PE targeted port of the linker] ++ ++The following options set flags in the @code{DllCharacteristics} field ++of the PE file header: ++[These options are specific to PE targeted ports of the linker] ++ ++@kindex --high-entropy-va ++@item --high-entropy-va ++@itemx --disable-high-entropy-va ++Image is compatible with 64-bit address space layout randomization ++(ASLR). This option is enabled by default for 64-bit PE images. ++ ++This option also implies @option{--dynamicbase} and ++@option{--enable-reloc-section}. ++ ++@kindex --dynamicbase ++@item --dynamicbase ++@itemx --disable-dynamicbase ++The image base address may be relocated using address space layout ++randomization (ASLR). This feature was introduced with MS Windows ++Vista for i386 PE targets. This option is enabled by default but ++can be disabled via the @option{--disable-dynamicbase} option. ++This option also implies @option{--enable-reloc-section}. ++ ++@kindex --forceinteg ++@item --forceinteg ++@itemx --disable-forceinteg ++Code integrity checks are enforced. This option is disabled by ++default. ++ ++@kindex --nxcompat ++@item --nxcompat ++@item --disable-nxcompat ++The image is compatible with the Data Execution Prevention. ++This feature was introduced with MS Windows XP SP2 for i386 PE ++targets. The option is enabled by default. ++ ++@kindex --no-isolation ++@item --no-isolation ++@itemx --disable-no-isolation ++Although the image understands isolation, do not isolate the image. ++This option is disabled by default. ++ ++@kindex --no-seh ++@item --no-seh ++@itemx --disable-no-seh ++The image does not use SEH. No SE handler may be called from ++this image. This option is disabled by default. ++ ++@kindex --no-bind ++@item --no-bind ++@itemx --disable-no-bind ++Do not bind this image. This option is disabled by default. ++ ++@kindex --wdmdriver ++@item --wdmdriver ++@itemx --disable-wdmdriver ++The driver uses the MS Windows Driver Model. This option is disabled ++by default. ++ ++@kindex --tsaware ++@item --tsaware ++@itemx --disable-tsaware ++The image is Terminal Server aware. This option is disabled by ++default. ++ ++@kindex --insert-timestamp ++@item --insert-timestamp ++@itemx --no-insert-timestamp ++Insert a real timestamp into the image. This is the default behaviour ++as it matches legacy code and it means that the image will work with ++other, proprietary tools. The problem with this default is that it ++will result in slightly different images being produced each time the ++same sources are linked. The option @option{--no-insert-timestamp} ++can be used to insert a zero value for the timestamp, this ensuring ++that binaries produced from identical sources will compare ++identically. ++ ++@kindex --enable-reloc-section ++@item --enable-reloc-section ++@itemx --disable-reloc-section ++Create the base relocation table, which is necessary if the image ++is loaded at a different image base than specified in the PE header. ++This option is enabled by default. ++@end table ++ ++@c man end ++ ++@ifset C6X ++@subsection Options specific to C6X uClinux targets ++ ++@c man begin OPTIONS ++ ++The C6X uClinux target uses a binary format called DSBT to support shared ++libraries. Each shared library in the system needs to have a unique index; ++all executables use an index of 0. ++ ++@table @gcctabopt ++ ++@kindex --dsbt-size ++@item --dsbt-size @var{size} ++This option sets the number of entries in the DSBT of the current executable ++or shared library to @var{size}. The default is to create a table with 64 ++entries. ++ ++@kindex --dsbt-index ++@item --dsbt-index @var{index} ++This option sets the DSBT index of the current executable or shared library ++to @var{index}. The default is 0, which is appropriate for generating ++executables. If a shared library is generated with a DSBT index of 0, the ++@code{R_C6000_DSBT_INDEX} relocs are copied into the output file. ++ ++@kindex --no-merge-exidx-entries ++The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent ++exidx entries in frame unwind info. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset CSKY ++@subsection Options specific to C-SKY targets ++ ++@c man begin OPTIONS ++ ++@table @gcctabopt ++ ++@kindex --branch-stub on C-SKY ++@item --branch-stub ++This option enables linker branch relaxation by inserting branch stub ++sections when needed to extend the range of branches. This option is ++usually not required since C-SKY supports branch and call instructions that ++can access the full memory range and branch relaxation is normally handled by ++the compiler or assembler. ++ ++@kindex --stub-group-size on C-SKY ++@item --stub-group-size=@var{N} ++This option allows finer control of linker branch stub creation. ++It sets the maximum size of a group of input sections that can ++be handled by one stub section. A negative value of @var{N} locates ++stub sections after their branches, while a positive value allows stub ++sections to appear either before or after the branches. Values of ++@samp{1} or @samp{-1} indicate that the ++linker should choose suitable defaults. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset M68HC11 ++@subsection Options specific to Motorola 68HC11 and 68HC12 targets ++ ++@c man begin OPTIONS ++ ++The 68HC11 and 68HC12 linkers support specific options to control the ++memory bank switching mapping and trampoline code generation. ++ ++@table @gcctabopt ++ ++@kindex --no-trampoline ++@item --no-trampoline ++This option disables the generation of trampoline. By default a trampoline ++is generated for each far function which is called using a @code{jsr} ++instruction (this happens when a pointer to a far function is taken). ++ ++@kindex --bank-window ++@item --bank-window @var{name} ++This option indicates to the linker the name of the memory region in ++the @samp{MEMORY} specification that describes the memory bank window. ++The definition of such region is then used by the linker to compute ++paging and addresses within the memory window. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset M68K ++@subsection Options specific to Motorola 68K target ++ ++@c man begin OPTIONS ++ ++The following options are supported to control handling of GOT generation ++when linking for 68K targets. ++ ++@table @gcctabopt ++ ++@kindex --got ++@item --got=@var{type} ++This option tells the linker which GOT generation scheme to use. ++@var{type} should be one of @samp{single}, @samp{negative}, ++@samp{multigot} or @samp{target}. For more information refer to the ++Info entry for @file{ld}. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset MIPS ++@subsection Options specific to MIPS targets ++ ++@c man begin OPTIONS ++ ++The following options are supported to control microMIPS instruction ++generation and branch relocation checks for ISA mode transitions when ++linking for MIPS targets. ++ ++@table @gcctabopt ++ ++@kindex --insn32 ++@item --insn32 ++@kindex --no-insn32 ++@itemx --no-insn32 ++These options control the choice of microMIPS instructions used in code ++generated by the linker, such as that in the PLT or lazy binding stubs, ++or in relaxation. If @samp{--insn32} is used, then the linker only uses ++32-bit instruction encodings. By default or if @samp{--no-insn32} is ++used, all instruction encodings are used, including 16-bit ones where ++possible. ++ ++@kindex --ignore-branch-isa ++@item --ignore-branch-isa ++@kindex --no-ignore-branch-isa ++@itemx --no-ignore-branch-isa ++These options control branch relocation checks for invalid ISA mode ++transitions. If @samp{--ignore-branch-isa} is used, then the linker ++accepts any branch relocations and any ISA mode transition required ++is lost in relocation calculation, except for some cases of @code{BAL} ++instructions which meet relaxation conditions and are converted to ++equivalent @code{JALX} instructions as the associated relocation is ++calculated. By default or if @samp{--no-ignore-branch-isa} is used ++a check is made causing the loss of an ISA mode transition to produce ++an error. ++ ++@kindex --compact-branches ++@item --compact-branches ++@kindex --no-compact-branches ++@itemx --no-compact-branches ++These options control the generation of compact instructions by the linker ++in the PLT entries for MIPS R6. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++ ++@ifset PDP11 ++@subsection Options specific to PDP11 targets ++ ++@c man begin OPTIONS ++ ++For the pdp11-aout target, three variants of the output format can be ++produced as selected by the following options. The default variant ++for pdp11-aout is the @samp{--omagic} option, whereas for other ++targets @samp{--nmagic} is the default. The @samp{--imagic} option is ++defined only for the pdp11-aout target, while the others are described ++here as they apply to the pdp11-aout target. ++ ++@table @gcctabopt ++ ++@kindex -N ++@item -N ++@kindex --omagic ++@itemx --omagic ++ ++Mark the output as @code{OMAGIC} (0407) in the @file{a.out} header to ++indicate that the text segment is not to be write-protected and ++shared. Since the text and data sections are both readable and ++writable, the data section is allocated immediately contiguous after ++the text segment. This is the oldest format for PDP11 executable ++programs and is the default for @command{ld} on PDP11 Unix systems ++from the beginning through 2.11BSD. ++ ++@kindex -n ++@item -n ++@kindex --nmagic ++@itemx --nmagic ++ ++Mark the output as @code{NMAGIC} (0410) in the @file{a.out} header to ++indicate that when the output file is executed, the text portion will ++be read-only and shareable among all processes executing the same ++file. This involves moving the data areas up to the first possible 8K ++byte page boundary following the end of the text. This option creates ++a @emph{pure executable} format. ++ ++@kindex -z ++@item -z ++@kindex --imagic ++@itemx --imagic ++ ++Mark the output as @code{IMAGIC} (0411) in the @file{a.out} header to ++indicate that when the output file is executed, the program text and ++data areas will be loaded into separate address spaces using the split ++instruction and data space feature of the memory management unit in ++larger models of the PDP11. This doubles the address space available ++to the program. The text segment is again pure, write-protected, and ++shareable. The only difference in the output format between this ++option and the others, besides the magic number, is that both the text ++and data sections start at location 0. The @samp{-z} option selected ++this format in 2.11BSD. This option creates a @emph{separate ++executable} format. ++ ++@kindex --no-omagic ++@item --no-omagic ++ ++Equivalent to @samp{--nmagic} for pdp11-aout. ++ ++@end table ++ ++@c man end ++@end ifset ++ ++@ifset UsesEnvVars ++@node Environment ++@section Environment Variables ++ ++@c man begin ENVIRONMENT ++ ++You can change the behaviour of @command{ld} with the environment variables ++@ifclear SingleFormat ++@code{GNUTARGET}, ++@end ifclear ++@code{LDEMULATION} and @code{COLLECT_NO_DEMANGLE}. ++ ++@ifclear SingleFormat ++@kindex GNUTARGET ++@cindex default input format ++@code{GNUTARGET} determines the input-file object format if you don't ++use @samp{-b} (or its synonym @samp{--format}). Its value should be one ++of the BFD names for an input format (@pxref{BFD}). If there is no ++@code{GNUTARGET} in the environment, @command{ld} uses the natural format ++of the target. If @code{GNUTARGET} is set to @code{default} then BFD ++attempts to discover the input format by examining binary input files; ++this method often succeeds, but there are potential ambiguities, since ++there is no method of ensuring that the magic number used to specify ++object-file formats is unique. However, the configuration procedure for ++BFD on each system places the conventional format for that system first ++in the search-list, so ambiguities are resolved in favor of convention. ++@end ifclear ++ ++@kindex LDEMULATION ++@cindex default emulation ++@cindex emulation, default ++@code{LDEMULATION} determines the default emulation if you don't use the ++@samp{-m} option. The emulation can affect various aspects of linker ++behaviour, particularly the default linker script. You can list the ++available emulations with the @samp{--verbose} or @samp{-V} options. If ++the @samp{-m} option is not used, and the @code{LDEMULATION} environment ++variable is not defined, the default emulation depends upon how the ++linker was configured. ++ ++@kindex COLLECT_NO_DEMANGLE ++@cindex demangling, default ++Normally, the linker will default to demangling symbols. However, if ++@code{COLLECT_NO_DEMANGLE} is set in the environment, then it will ++default to not demangling symbols. This environment variable is used in ++a similar fashion by the @code{gcc} linker wrapper program. The default ++may be overridden by the @samp{--demangle} and @samp{--no-demangle} ++options. ++ ++@c man end ++@end ifset ++ ++@node Scripts ++@chapter Linker Scripts ++ ++@cindex scripts ++@cindex linker scripts ++@cindex command files ++Every link is controlled by a @dfn{linker script}. This script is ++written in the linker command language. ++ ++The main purpose of the linker script is to describe how the sections in ++the input files should be mapped into the output file, and to control ++the memory layout of the output file. Most linker scripts do nothing ++more than this. However, when necessary, the linker script can also ++direct the linker to perform many other operations, using the commands ++described below. ++ ++The linker always uses a linker script. If you do not supply one ++yourself, the linker will use a default script that is compiled into the ++linker executable. You can use the @samp{--verbose} command-line option ++to display the default linker script. Certain command-line options, ++such as @samp{-r} or @samp{-N}, will affect the default linker script. ++ ++You may supply your own linker script by using the @samp{-T} command ++line option. When you do this, your linker script will replace the ++default linker script. ++ ++You may also use linker scripts implicitly by naming them as input files ++to the linker, as though they were files to be linked. @xref{Implicit ++Linker Scripts}. ++ ++@menu ++* Basic Script Concepts:: Basic Linker Script Concepts ++* Script Format:: Linker Script Format ++* Simple Example:: Simple Linker Script Example ++* Simple Commands:: Simple Linker Script Commands ++* Assignments:: Assigning Values to Symbols ++* SECTIONS:: SECTIONS Command ++* MEMORY:: MEMORY Command ++* PHDRS:: PHDRS Command ++* VERSION:: VERSION Command ++* Expressions:: Expressions in Linker Scripts ++* Implicit Linker Scripts:: Implicit Linker Scripts ++@end menu ++ ++@node Basic Script Concepts ++@section Basic Linker Script Concepts ++@cindex linker script concepts ++We need to define some basic concepts and vocabulary in order to ++describe the linker script language. ++ ++The linker combines input files into a single output file. The output ++file and each input file are in a special data format known as an ++@dfn{object file format}. Each file is called an @dfn{object file}. ++The output file is often called an @dfn{executable}, but for our ++purposes we will also call it an object file. Each object file has, ++among other things, a list of @dfn{sections}. We sometimes refer to a ++section in an input file as an @dfn{input section}; similarly, a section ++in the output file is an @dfn{output section}. ++ ++Each section in an object file has a name and a size. Most sections ++also have an associated block of data, known as the @dfn{section ++contents}. A section may be marked as @dfn{loadable}, which means that ++the contents should be loaded into memory when the output file is run. ++A section with no contents may be @dfn{allocatable}, which means that an ++area in memory should be set aside, but nothing in particular should be ++loaded there (in some cases this memory must be zeroed out). A section ++which is neither loadable nor allocatable typically contains some sort ++of debugging information. ++ ++Every loadable or allocatable output section has two addresses. The ++first is the @dfn{VMA}, or virtual memory address. This is the address ++the section will have when the output file is run. The second is the ++@dfn{LMA}, or load memory address. This is the address at which the ++section will be loaded. In most cases the two addresses will be the ++same. An example of when they might be different is when a data section ++is loaded into ROM, and then copied into RAM when the program starts up ++(this technique is often used to initialize global variables in a ROM ++based system). In this case the ROM address would be the LMA, and the ++RAM address would be the VMA. ++ ++You can see the sections in an object file by using the @code{objdump} ++program with the @samp{-h} option. ++ ++Every object file also has a list of @dfn{symbols}, known as the ++@dfn{symbol table}. A symbol may be defined or undefined. Each symbol ++has a name, and each defined symbol has an address, among other ++information. If you compile a C or C++ program into an object file, you ++will get a defined symbol for every defined function and global or ++static variable. Every undefined function or global variable which is ++referenced in the input file will become an undefined symbol. ++ ++You can see the symbols in an object file by using the @code{nm} ++program, or by using the @code{objdump} program with the @samp{-t} ++option. ++ ++@node Script Format ++@section Linker Script Format ++@cindex linker script format ++Linker scripts are text files. ++ ++You write a linker script as a series of commands. Each command is ++either a keyword, possibly followed by arguments, or an assignment to a ++symbol. You may separate commands using semicolons. Whitespace is ++generally ignored. ++ ++Strings such as file or format names can normally be entered directly. ++If the file name contains a character such as a comma which would ++otherwise serve to separate file names, you may put the file name in ++double quotes. There is no way to use a double quote character in a ++file name. ++ ++You may include comments in linker scripts just as in C, delimited by ++@samp{/*} and @samp{*/}. As in C, comments are syntactically equivalent ++to whitespace. ++ ++@node Simple Example ++@section Simple Linker Script Example ++@cindex linker script example ++@cindex example of linker script ++Many linker scripts are fairly simple. ++ ++The simplest possible linker script has just one command: ++@samp{SECTIONS}. You use the @samp{SECTIONS} command to describe the ++memory layout of the output file. ++ ++The @samp{SECTIONS} command is a powerful command. Here we will ++describe a simple use of it. Let's assume your program consists only of ++code, initialized data, and uninitialized data. These will be in the ++@samp{.text}, @samp{.data}, and @samp{.bss} sections, respectively. ++Let's assume further that these are the only sections which appear in ++your input files. ++ ++For this example, let's say that the code should be loaded at address ++0x10000, and that the data should start at address 0x8000000. Here is a ++linker script which will do that: ++@smallexample ++SECTIONS ++@{ ++ . = 0x10000; ++ .text : @{ *(.text) @} ++ . = 0x8000000; ++ .data : @{ *(.data) @} ++ .bss : @{ *(.bss) @} ++@} ++@end smallexample ++ ++You write the @samp{SECTIONS} command as the keyword @samp{SECTIONS}, ++followed by a series of symbol assignments and output section ++descriptions enclosed in curly braces. ++ ++The first line inside the @samp{SECTIONS} command of the above example ++sets the value of the special symbol @samp{.}, which is the location ++counter. If you do not specify the address of an output section in some ++other way (other ways are described later), the address is set from the ++current value of the location counter. The location counter is then ++incremented by the size of the output section. At the start of the ++@samp{SECTIONS} command, the location counter has the value @samp{0}. ++ ++The second line defines an output section, @samp{.text}. The colon is ++required syntax which may be ignored for now. Within the curly braces ++after the output section name, you list the names of the input sections ++which should be placed into this output section. The @samp{*} is a ++wildcard which matches any file name. The expression @samp{*(.text)} ++means all @samp{.text} input sections in all input files. ++ ++Since the location counter is @samp{0x10000} when the output section ++@samp{.text} is defined, the linker will set the address of the ++@samp{.text} section in the output file to be @samp{0x10000}. ++ ++The remaining lines define the @samp{.data} and @samp{.bss} sections in ++the output file. The linker will place the @samp{.data} output section ++at address @samp{0x8000000}. After the linker places the @samp{.data} ++output section, the value of the location counter will be ++@samp{0x8000000} plus the size of the @samp{.data} output section. The ++effect is that the linker will place the @samp{.bss} output section ++immediately after the @samp{.data} output section in memory. ++ ++The linker will ensure that each output section has the required ++alignment, by increasing the location counter if necessary. In this ++example, the specified addresses for the @samp{.text} and @samp{.data} ++sections will probably satisfy any alignment constraints, but the linker ++may have to create a small gap between the @samp{.data} and @samp{.bss} ++sections. ++ ++That's it! That's a simple and complete linker script. ++ ++@node Simple Commands ++@section Simple Linker Script Commands ++@cindex linker script simple commands ++In this section we describe the simple linker script commands. ++ ++@menu ++* Entry Point:: Setting the entry point ++* File Commands:: Commands dealing with files ++@ifclear SingleFormat ++* Format Commands:: Commands dealing with object file formats ++@end ifclear ++ ++* REGION_ALIAS:: Assign alias names to memory regions ++* Miscellaneous Commands:: Other linker script commands ++@end menu ++ ++@node Entry Point ++@subsection Setting the Entry Point ++@kindex ENTRY(@var{symbol}) ++@cindex start of execution ++@cindex first instruction ++@cindex entry point ++The first instruction to execute in a program is called the @dfn{entry ++point}. You can use the @code{ENTRY} linker script command to set the ++entry point. The argument is a symbol name: ++@smallexample ++ENTRY(@var{symbol}) ++@end smallexample ++ ++There are several ways to set the entry point. The linker will set the ++entry point by trying each of the following methods in order, and ++stopping when one of them succeeds: ++@itemize @bullet ++@item ++the @samp{-e} @var{entry} command-line option; ++@item ++the @code{ENTRY(@var{symbol})} command in a linker script; ++@item ++the value of a target-specific symbol, if it is defined; For many ++targets this is @code{start}, but PE- and BeOS-based systems for example ++check a list of possible entry symbols, matching the first one found. ++@item ++the address of the first byte of the code section, if present and an ++executable is being created - the code section is usually ++@samp{.text}, but can be something else; ++@item ++The address @code{0}. ++@end itemize ++ ++@node File Commands ++@subsection Commands Dealing with Files ++@cindex linker script file commands ++Several linker script commands deal with files. ++ ++@table @code ++@item INCLUDE @var{filename} ++@kindex INCLUDE @var{filename} ++@cindex including a linker script ++Include the linker script @var{filename} at this point. The file will ++be searched for in the current directory, and in any directory specified ++with the @option{-L} option. You can nest calls to @code{INCLUDE} up to ++10 levels deep. ++ ++You can place @code{INCLUDE} directives at the top level, in @code{MEMORY} or ++@code{SECTIONS} commands, or in output section descriptions. ++ ++@item INPUT(@var{file}, @var{file}, @dots{}) ++@itemx INPUT(@var{file} @var{file} @dots{}) ++@kindex INPUT(@var{files}) ++@cindex input files in linker scripts ++@cindex input object files in linker scripts ++@cindex linker script input object files ++The @code{INPUT} command directs the linker to include the named files ++in the link, as though they were named on the command line. ++ ++For example, if you always want to include @file{subr.o} any time you do ++a link, but you can't be bothered to put it on every link command line, ++then you can put @samp{INPUT (subr.o)} in your linker script. ++ ++In fact, if you like, you can list all of your input files in the linker ++script, and then invoke the linker with nothing but a @samp{-T} option. ++ ++In case a @dfn{sysroot prefix} is configured, and the filename starts ++with the @samp{/} character, and the script being processed was ++located inside the @dfn{sysroot prefix}, the filename will be looked ++for in the @dfn{sysroot prefix}. The @dfn{sysroot prefix} can also be forced by specifying ++@code{=} as the first character in the filename path, or prefixing the ++filename path with @code{$SYSROOT}. See also the description of ++@samp{-L} in @ref{Options,,Command-line Options}. ++ ++If a @dfn{sysroot prefix} is not used then the linker will try to open ++the file in the directory containing the linker script. If it is not ++found the linker will then search the current directory. If it is still ++not found the linker will search through the archive library search ++path. ++ ++If you use @samp{INPUT (-l@var{file})}, @command{ld} will transform the ++name to @code{lib@var{file}.a}, as with the command-line argument ++@samp{-l}. ++ ++When you use the @code{INPUT} command in an implicit linker script, the ++files will be included in the link at the point at which the linker ++script file is included. This can affect archive searching. ++ ++@item GROUP(@var{file}, @var{file}, @dots{}) ++@itemx GROUP(@var{file} @var{file} @dots{}) ++@kindex GROUP(@var{files}) ++@cindex grouping input files ++The @code{GROUP} command is like @code{INPUT}, except that the named ++files should all be archives, and they are searched repeatedly until no ++new undefined references are created. See the description of @samp{-(} ++in @ref{Options,,Command-line Options}. ++ ++@item AS_NEEDED(@var{file}, @var{file}, @dots{}) ++@itemx AS_NEEDED(@var{file} @var{file} @dots{}) ++@kindex AS_NEEDED(@var{files}) ++This construct can appear only inside of the @code{INPUT} or @code{GROUP} ++commands, among other filenames. The files listed will be handled ++as if they appear directly in the @code{INPUT} or @code{GROUP} commands, ++with the exception of ELF shared libraries, that will be added only ++when they are actually needed. This construct essentially enables ++@option{--as-needed} option for all the files listed inside of it ++and restores previous @option{--as-needed} resp. @option{--no-as-needed} ++setting afterwards. ++ ++@item OUTPUT(@var{filename}) ++@kindex OUTPUT(@var{filename}) ++@cindex output file name in linker script ++The @code{OUTPUT} command names the output file. Using ++@code{OUTPUT(@var{filename})} in the linker script is exactly like using ++@samp{-o @var{filename}} on the command line (@pxref{Options,,Command ++Line Options}). If both are used, the command-line option takes ++precedence. ++ ++You can use the @code{OUTPUT} command to define a default name for the ++output file other than the usual default of @file{a.out}. ++ ++@item SEARCH_DIR(@var{path}) ++@kindex SEARCH_DIR(@var{path}) ++@cindex library search path in linker script ++@cindex archive search path in linker script ++@cindex search path in linker script ++The @code{SEARCH_DIR} command adds @var{path} to the list of paths where ++@command{ld} looks for archive libraries. Using ++@code{SEARCH_DIR(@var{path})} is exactly like using @samp{-L @var{path}} ++on the command line (@pxref{Options,,Command-line Options}). If both ++are used, then the linker will search both paths. Paths specified using ++the command-line option are searched first. ++ ++@item STARTUP(@var{filename}) ++@kindex STARTUP(@var{filename}) ++@cindex first input file ++The @code{STARTUP} command is just like the @code{INPUT} command, except ++that @var{filename} will become the first input file to be linked, as ++though it were specified first on the command line. This may be useful ++when using a system in which the entry point is always the start of the ++first file. ++@end table ++ ++@ifclear SingleFormat ++@node Format Commands ++@subsection Commands Dealing with Object File Formats ++A couple of linker script commands deal with object file formats. ++ ++@table @code ++@item OUTPUT_FORMAT(@var{bfdname}) ++@itemx OUTPUT_FORMAT(@var{default}, @var{big}, @var{little}) ++@kindex OUTPUT_FORMAT(@var{bfdname}) ++@cindex output file format in linker script ++The @code{OUTPUT_FORMAT} command names the BFD format to use for the ++output file (@pxref{BFD}). Using @code{OUTPUT_FORMAT(@var{bfdname})} is ++exactly like using @samp{--oformat @var{bfdname}} on the command line ++(@pxref{Options,,Command-line Options}). If both are used, the command ++line option takes precedence. ++ ++You can use @code{OUTPUT_FORMAT} with three arguments to use different ++formats based on the @samp{-EB} and @samp{-EL} command-line options. ++This permits the linker script to set the output format based on the ++desired endianness. ++ ++If neither @samp{-EB} nor @samp{-EL} are used, then the output format ++will be the first argument, @var{default}. If @samp{-EB} is used, the ++output format will be the second argument, @var{big}. If @samp{-EL} is ++used, the output format will be the third argument, @var{little}. ++ ++For example, the default linker script for the MIPS ELF target uses this ++command: ++@smallexample ++OUTPUT_FORMAT(elf32-bigmips, elf32-bigmips, elf32-littlemips) ++@end smallexample ++This says that the default format for the output file is ++@samp{elf32-bigmips}, but if the user uses the @samp{-EL} command-line ++option, the output file will be created in the @samp{elf32-littlemips} ++format. ++ ++@item TARGET(@var{bfdname}) ++@kindex TARGET(@var{bfdname}) ++@cindex input file format in linker script ++The @code{TARGET} command names the BFD format to use when reading input ++files. It affects subsequent @code{INPUT} and @code{GROUP} commands. ++This command is like using @samp{-b @var{bfdname}} on the command line ++(@pxref{Options,,Command-line Options}). If the @code{TARGET} command ++is used but @code{OUTPUT_FORMAT} is not, then the last @code{TARGET} ++command is also used to set the format for the output file. @xref{BFD}. ++@end table ++@end ifclear ++ ++@node REGION_ALIAS ++@subsection Assign alias names to memory regions ++@kindex REGION_ALIAS(@var{alias}, @var{region}) ++@cindex region alias ++@cindex region names ++ ++Alias names can be added to existing memory regions created with the ++@ref{MEMORY} command. Each name corresponds to at most one memory region. ++ ++@smallexample ++REGION_ALIAS(@var{alias}, @var{region}) ++@end smallexample ++ ++The @code{REGION_ALIAS} function creates an alias name @var{alias} for the ++memory region @var{region}. This allows a flexible mapping of output sections ++to memory regions. An example follows. ++ ++Suppose we have an application for embedded systems which come with various ++memory storage devices. All have a general purpose, volatile memory @code{RAM} ++that allows code execution or data storage. Some may have a read-only, ++non-volatile memory @code{ROM} that allows code execution and read-only data ++access. The last variant is a read-only, non-volatile memory @code{ROM2} with ++read-only data access and no code execution capability. We have four output ++sections: ++ ++@itemize @bullet ++@item ++@code{.text} program code; ++@item ++@code{.rodata} read-only data; ++@item ++@code{.data} read-write initialized data; ++@item ++@code{.bss} read-write zero initialized data. ++@end itemize ++ ++The goal is to provide a linker command file that contains a system independent ++part defining the output sections and a system dependent part mapping the ++output sections to the memory regions available on the system. Our embedded ++systems come with three different memory setups @code{A}, @code{B} and ++@code{C}: ++@multitable @columnfractions .25 .25 .25 .25 ++@item Section @tab Variant A @tab Variant B @tab Variant C ++@item .text @tab RAM @tab ROM @tab ROM ++@item .rodata @tab RAM @tab ROM @tab ROM2 ++@item .data @tab RAM @tab RAM/ROM @tab RAM/ROM2 ++@item .bss @tab RAM @tab RAM @tab RAM ++@end multitable ++The notation @code{RAM/ROM} or @code{RAM/ROM2} means that this section is ++loaded into region @code{ROM} or @code{ROM2} respectively. Please note that ++the load address of the @code{.data} section starts in all three variants at ++the end of the @code{.rodata} section. ++ ++The base linker script that deals with the output sections follows. It ++includes the system dependent @code{linkcmds.memory} file that describes the ++memory layout: ++@smallexample ++INCLUDE linkcmds.memory ++ ++SECTIONS ++ @{ ++ .text : ++ @{ ++ *(.text) ++ @} > REGION_TEXT ++ .rodata : ++ @{ ++ *(.rodata) ++ rodata_end = .; ++ @} > REGION_RODATA ++ .data : AT (rodata_end) ++ @{ ++ data_start = .; ++ *(.data) ++ @} > REGION_DATA ++ data_size = SIZEOF(.data); ++ data_load_start = LOADADDR(.data); ++ .bss : ++ @{ ++ *(.bss) ++ @} > REGION_BSS ++ @} ++@end smallexample ++ ++Now we need three different @code{linkcmds.memory} files to define memory ++regions and alias names. The content of @code{linkcmds.memory} for the three ++variants @code{A}, @code{B} and @code{C}: ++@table @code ++@item A ++Here everything goes into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ RAM : ORIGIN = 0, LENGTH = 4M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", RAM); ++REGION_ALIAS("REGION_RODATA", RAM); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@item B ++Program code and read-only data go into the @code{ROM}. Read-write data goes ++into the @code{RAM}. An image of the initialized data is loaded into the ++@code{ROM} and will be copied during system start into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ ROM : ORIGIN = 0, LENGTH = 3M ++ RAM : ORIGIN = 0x10000000, LENGTH = 1M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", ROM); ++REGION_ALIAS("REGION_RODATA", ROM); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@item C ++Program code goes into the @code{ROM}. Read-only data goes into the ++@code{ROM2}. Read-write data goes into the @code{RAM}. An image of the ++initialized data is loaded into the @code{ROM2} and will be copied during ++system start into the @code{RAM}. ++@smallexample ++MEMORY ++ @{ ++ ROM : ORIGIN = 0, LENGTH = 2M ++ ROM2 : ORIGIN = 0x10000000, LENGTH = 1M ++ RAM : ORIGIN = 0x20000000, LENGTH = 1M ++ @} ++ ++REGION_ALIAS("REGION_TEXT", ROM); ++REGION_ALIAS("REGION_RODATA", ROM2); ++REGION_ALIAS("REGION_DATA", RAM); ++REGION_ALIAS("REGION_BSS", RAM); ++@end smallexample ++@end table ++ ++It is possible to write a common system initialization routine to copy the ++@code{.data} section from @code{ROM} or @code{ROM2} into the @code{RAM} if ++necessary: ++@smallexample ++#include ++ ++extern char data_start []; ++extern char data_size []; ++extern char data_load_start []; ++ ++void copy_data(void) ++@{ ++ if (data_start != data_load_start) ++ @{ ++ memcpy(data_start, data_load_start, (size_t) data_size); ++ @} ++@} ++@end smallexample ++ ++@node Miscellaneous Commands ++@subsection Other Linker Script Commands ++There are a few other linker scripts commands. ++ ++@table @code ++@item ASSERT(@var{exp}, @var{message}) ++@kindex ASSERT ++@cindex assertion in linker script ++Ensure that @var{exp} is non-zero. If it is zero, then exit the linker ++with an error code, and print @var{message}. ++ ++Note that assertions are checked before the final stages of linking ++take place. This means that expressions involving symbols PROVIDEd ++inside section definitions will fail if the user has not set values ++for those symbols. The only exception to this rule is PROVIDEd ++symbols that just reference dot. Thus an assertion like this: ++ ++@smallexample ++ .stack : ++ @{ ++ PROVIDE (__stack = .); ++ PROVIDE (__stack_size = 0x100); ++ ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); ++ @} ++@end smallexample ++ ++will fail if @code{__stack_size} is not defined elsewhere. Symbols ++PROVIDEd outside of section definitions are evaluated earlier, so they ++can be used inside ASSERTions. Thus: ++ ++@smallexample ++ PROVIDE (__stack_size = 0x100); ++ .stack : ++ @{ ++ PROVIDE (__stack = .); ++ ASSERT ((__stack > (_end + __stack_size)), "Error: No room left for the stack"); ++ @} ++@end smallexample ++ ++will work. ++ ++@item EXTERN(@var{symbol} @var{symbol} @dots{}) ++@kindex EXTERN ++@cindex undefined symbol in linker script ++Force @var{symbol} to be entered in the output file as an undefined ++symbol. Doing this may, for example, trigger linking of additional ++modules from standard libraries. You may list several @var{symbol}s for ++each @code{EXTERN}, and you may use @code{EXTERN} multiple times. This ++command has the same effect as the @samp{-u} command-line option. ++ ++@item FORCE_COMMON_ALLOCATION ++@kindex FORCE_COMMON_ALLOCATION ++@cindex common allocation in linker script ++This command has the same effect as the @samp{-d} command-line option: ++to make @command{ld} assign space to common symbols even if a relocatable ++output file is specified (@samp{-r}). ++ ++@item INHIBIT_COMMON_ALLOCATION ++@kindex INHIBIT_COMMON_ALLOCATION ++@cindex common allocation in linker script ++This command has the same effect as the @samp{--no-define-common} ++command-line option: to make @code{ld} omit the assignment of addresses ++to common symbols even for a non-relocatable output file. ++ ++@item FORCE_GROUP_ALLOCATION ++@kindex FORCE_GROUP_ALLOCATION ++@cindex group allocation in linker script ++@cindex section groups ++@cindex COMDAT ++This command has the same effect as the ++@samp{--force-group-allocation} command-line option: to make ++@command{ld} place section group members like normal input sections, ++and to delete the section groups even if a relocatable output file is ++specified (@samp{-r}). ++ ++@item INSERT [ AFTER | BEFORE ] @var{output_section} ++@kindex INSERT ++@cindex insert user script into default script ++This command is typically used in a script specified by @samp{-T} to ++augment the default @code{SECTIONS} with, for example, overlays. It ++inserts all prior linker script statements after (or before) ++@var{output_section}, and also causes @samp{-T} to not override the ++default linker script. The exact insertion point is as for orphan ++sections. @xref{Location Counter}. The insertion happens after the ++linker has mapped input sections to output sections. Prior to the ++insertion, since @samp{-T} scripts are parsed before the default ++linker script, statements in the @samp{-T} script occur before the ++default linker script statements in the internal linker representation ++of the script. In particular, input section assignments will be made ++to @samp{-T} output sections before those in the default script. Here ++is an example of how a @samp{-T} script using @code{INSERT} might look: ++ ++@smallexample ++SECTIONS ++@{ ++ OVERLAY : ++ @{ ++ .ov1 @{ ov1*(.text) @} ++ .ov2 @{ ov2*(.text) @} ++ @} ++@} ++INSERT AFTER .text; ++@end smallexample ++ ++Note that when @samp{-T} is used twice, once to override the default ++script and once to augment that script using @code{INSERT} the order ++of parsing and section assignments apply as for the default script. ++The script with @code{INSERT} should be specified @emph{first} on the ++command line. ++ ++@item NOCROSSREFS(@var{section} @var{section} @dots{}) ++@kindex NOCROSSREFS(@var{sections}) ++@cindex cross references ++This command may be used to tell @command{ld} to issue an error about any ++references among certain output sections. ++ ++In certain types of programs, particularly on embedded systems when ++using overlays, when one section is loaded into memory, another section ++will not be. Any direct references between the two sections would be ++errors. For example, it would be an error if code in one section called ++a function defined in the other section. ++ ++The @code{NOCROSSREFS} command takes a list of output section names. If ++@command{ld} detects any cross references between the sections, it reports ++an error and returns a non-zero exit status. Note that the ++@code{NOCROSSREFS} command uses output section names, not input section ++names. ++ ++@item NOCROSSREFS_TO(@var{tosection} @var{fromsection} @dots{}) ++@kindex NOCROSSREFS_TO(@var{tosection} @var{fromsections}) ++@cindex cross references ++This command may be used to tell @command{ld} to issue an error about any ++references to one section from a list of other sections. ++ ++The @code{NOCROSSREFS} command is useful when ensuring that two or more ++output sections are entirely independent but there are situations where ++a one-way dependency is needed. For example, in a multi-core application ++there may be shared code that can be called from each core but for safety ++must never call back. ++ ++The @code{NOCROSSREFS_TO} command takes a list of output section names. ++The first section can not be referenced from any of the other sections. ++If @command{ld} detects any references to the first section from any of ++the other sections, it reports an error and returns a non-zero exit ++status. Note that the @code{NOCROSSREFS_TO} command uses output section ++names, not input section names. ++ ++@ifclear SingleFormat ++@item OUTPUT_ARCH(@var{bfdarch}) ++@kindex OUTPUT_ARCH(@var{bfdarch}) ++@cindex machine architecture ++@cindex architecture ++Specify a particular output machine architecture. The argument is one ++of the names used by the BFD library (@pxref{BFD}). You can see the ++architecture of an object file by using the @code{objdump} program with ++the @samp{-f} option. ++@end ifclear ++ ++@item LD_FEATURE(@var{string}) ++@kindex LD_FEATURE(@var{string}) ++This command may be used to modify @command{ld} behavior. If ++@var{string} is @code{"SANE_EXPR"} then absolute symbols and numbers ++in a script are simply treated as numbers everywhere. ++@xref{Expression Section}. ++@end table ++ ++@node Assignments ++@section Assigning Values to Symbols ++@cindex assignment in scripts ++@cindex symbol definition, scripts ++@cindex variables, defining ++You may assign a value to a symbol in a linker script. This will define ++the symbol and place it into the symbol table with a global scope. ++ ++@menu ++* Simple Assignments:: Simple Assignments ++* HIDDEN:: HIDDEN ++* PROVIDE:: PROVIDE ++* PROVIDE_HIDDEN:: PROVIDE_HIDDEN ++* Source Code Reference:: How to use a linker script defined symbol in source code ++@end menu ++ ++@node Simple Assignments ++@subsection Simple Assignments ++ ++You may assign to a symbol using any of the C assignment operators: ++ ++@table @code ++@item @var{symbol} = @var{expression} ; ++@itemx @var{symbol} += @var{expression} ; ++@itemx @var{symbol} -= @var{expression} ; ++@itemx @var{symbol} *= @var{expression} ; ++@itemx @var{symbol} /= @var{expression} ; ++@itemx @var{symbol} <<= @var{expression} ; ++@itemx @var{symbol} >>= @var{expression} ; ++@itemx @var{symbol} &= @var{expression} ; ++@itemx @var{symbol} |= @var{expression} ; ++@end table ++ ++The first case will define @var{symbol} to the value of ++@var{expression}. In the other cases, @var{symbol} must already be ++defined, and the value will be adjusted accordingly. ++ ++The special symbol name @samp{.} indicates the location counter. You ++may only use this within a @code{SECTIONS} command. @xref{Location Counter}. ++ ++The semicolon after @var{expression} is required. ++ ++Expressions are defined below; see @ref{Expressions}. ++ ++You may write symbol assignments as commands in their own right, or as ++statements within a @code{SECTIONS} command, or as part of an output ++section description in a @code{SECTIONS} command. ++ ++The section of the symbol will be set from the section of the ++expression; for more information, see @ref{Expression Section}. ++ ++Here is an example showing the three different places that symbol ++assignments may be used: ++ ++@smallexample ++floating_point = 0; ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ _etext = .; ++ @} ++ _bdata = (. + 3) & ~ 3; ++ .data : @{ *(.data) @} ++@} ++@end smallexample ++@noindent ++In this example, the symbol @samp{floating_point} will be defined as ++zero. The symbol @samp{_etext} will be defined as the address following ++the last @samp{.text} input section. The symbol @samp{_bdata} will be ++defined as the address following the @samp{.text} output section aligned ++upward to a 4 byte boundary. ++ ++@node HIDDEN ++@subsection HIDDEN ++@cindex HIDDEN ++For ELF targeted ports, define a symbol that will be hidden and won't be ++exported. The syntax is @code{HIDDEN(@var{symbol} = @var{expression})}. ++ ++Here is the example from @ref{Simple Assignments}, rewritten to use ++@code{HIDDEN}: ++ ++@smallexample ++HIDDEN(floating_point = 0); ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ HIDDEN(_etext = .); ++ @} ++ HIDDEN(_bdata = (. + 3) & ~ 3); ++ .data : @{ *(.data) @} ++@} ++@end smallexample ++@noindent ++In this case none of the three symbols will be visible outside this module. ++ ++@node PROVIDE ++@subsection PROVIDE ++@cindex PROVIDE ++In some cases, it is desirable for a linker script to define a symbol ++only if it is referenced and is not defined by any object included in ++the link. For example, traditional linkers defined the symbol ++@samp{etext}. However, ANSI C requires that the user be able to use ++@samp{etext} as a function name without encountering an error. The ++@code{PROVIDE} keyword may be used to define a symbol, such as ++@samp{etext}, only if it is referenced but not defined. The syntax is ++@code{PROVIDE(@var{symbol} = @var{expression})}. ++ ++Here is an example of using @code{PROVIDE} to define @samp{etext}: ++@smallexample ++SECTIONS ++@{ ++ .text : ++ @{ ++ *(.text) ++ _etext = .; ++ PROVIDE(etext = .); ++ @} ++@} ++@end smallexample ++ ++In this example, if the program defines @samp{_etext} (with a leading ++underscore), the linker will give a multiple definition diagnostic. If, ++on the other hand, the program defines @samp{etext} (with no leading ++underscore), the linker will silently use the definition in the program. ++If the program references @samp{etext} but does not define it, the ++linker will use the definition in the linker script. ++ ++Note - the @code{PROVIDE} directive considers a common symbol to be ++defined, even though such a symbol could be combined with the symbol ++that the @code{PROVIDE} would create. This is particularly important ++when considering constructor and destructor list symbols such as ++@samp{__CTOR_LIST__} as these are often defined as common symbols. ++ ++@node PROVIDE_HIDDEN ++@subsection PROVIDE_HIDDEN ++@cindex PROVIDE_HIDDEN ++Similar to @code{PROVIDE}. For ELF targeted ports, the symbol will be ++hidden and won't be exported. ++ ++@node Source Code Reference ++@subsection Source Code Reference ++ ++Accessing a linker script defined variable from source code is not ++intuitive. In particular a linker script symbol is not equivalent to ++a variable declaration in a high level language, it is instead a ++symbol that does not have a value. ++ ++Before going further, it is important to note that compilers often ++transform names in the source code into different names when they are ++stored in the symbol table. For example, Fortran compilers commonly ++prepend or append an underscore, and C++ performs extensive @samp{name ++mangling}. Therefore there might be a discrepancy between the name ++of a variable as it is used in source code and the name of the same ++variable as it is defined in a linker script. For example in C a ++linker script variable might be referred to as: ++ ++@smallexample ++ extern int foo; ++@end smallexample ++ ++But in the linker script it might be defined as: ++ ++@smallexample ++ _foo = 1000; ++@end smallexample ++ ++In the remaining examples however it is assumed that no name ++transformation has taken place. ++ ++When a symbol is declared in a high level language such as C, two ++things happen. The first is that the compiler reserves enough space ++in the program's memory to hold the @emph{value} of the symbol. The ++second is that the compiler creates an entry in the program's symbol ++table which holds the symbol's @emph{address}. ie the symbol table ++contains the address of the block of memory holding the symbol's ++value. So for example the following C declaration, at file scope: ++ ++@smallexample ++ int foo = 1000; ++@end smallexample ++ ++creates an entry called @samp{foo} in the symbol table. This entry ++holds the address of an @samp{int} sized block of memory where the ++number 1000 is initially stored. ++ ++When a program references a symbol the compiler generates code that ++first accesses the symbol table to find the address of the symbol's ++memory block and then code to read the value from that memory block. ++So: ++ ++@smallexample ++ foo = 1; ++@end smallexample ++ ++looks up the symbol @samp{foo} in the symbol table, gets the address ++associated with this symbol and then writes the value 1 into that ++address. Whereas: ++ ++@smallexample ++ int * a = & foo; ++@end smallexample ++ ++looks up the symbol @samp{foo} in the symbol table, gets its address ++and then copies this address into the block of memory associated with ++the variable @samp{a}. ++ ++Linker scripts symbol declarations, by contrast, create an entry in ++the symbol table but do not assign any memory to them. Thus they are ++an address without a value. So for example the linker script definition: ++ ++@smallexample ++ foo = 1000; ++@end smallexample ++ ++creates an entry in the symbol table called @samp{foo} which holds ++the address of memory location 1000, but nothing special is stored at ++address 1000. This means that you cannot access the @emph{value} of a ++linker script defined symbol - it has no value - all you can do is ++access the @emph{address} of a linker script defined symbol. ++ ++Hence when you are using a linker script defined symbol in source code ++you should always take the address of the symbol, and never attempt to ++use its value. For example suppose you want to copy the contents of a ++section of memory called .ROM into a section called .FLASH and the ++linker script contains these declarations: ++ ++@smallexample ++@group ++ start_of_ROM = .ROM; ++ end_of_ROM = .ROM + sizeof (.ROM); ++ start_of_FLASH = .FLASH; ++@end group ++@end smallexample ++ ++Then the C source code to perform the copy would be: ++ ++@smallexample ++@group ++ extern char start_of_ROM, end_of_ROM, start_of_FLASH; ++ ++ memcpy (& start_of_FLASH, & start_of_ROM, & end_of_ROM - & start_of_ROM); ++@end group ++@end smallexample ++ ++Note the use of the @samp{&} operators. These are correct. ++Alternatively the symbols can be treated as the names of vectors or ++arrays and then the code will again work as expected: ++ ++@smallexample ++@group ++ extern char start_of_ROM[], end_of_ROM[], start_of_FLASH[]; ++ ++ memcpy (start_of_FLASH, start_of_ROM, end_of_ROM - start_of_ROM); ++@end group ++@end smallexample ++ ++Note how using this method does not require the use of @samp{&} ++operators. ++ ++@node SECTIONS ++@section SECTIONS Command ++@kindex SECTIONS ++The @code{SECTIONS} command tells the linker how to map input sections ++into output sections, and how to place the output sections in memory. ++ ++The format of the @code{SECTIONS} command is: ++@smallexample ++SECTIONS ++@{ ++ @var{sections-command} ++ @var{sections-command} ++ @dots{} ++@} ++@end smallexample ++ ++Each @var{sections-command} may of be one of the following: ++ ++@itemize @bullet ++@item ++an @code{ENTRY} command (@pxref{Entry Point,,Entry command}) ++@item ++a symbol assignment (@pxref{Assignments}) ++@item ++an output section description ++@item ++an overlay description ++@end itemize ++ ++The @code{ENTRY} command and symbol assignments are permitted inside the ++@code{SECTIONS} command for convenience in using the location counter in ++those commands. This can also make the linker script easier to ++understand because you can use those commands at meaningful points in ++the layout of the output file. ++ ++Output section descriptions and overlay descriptions are described ++below. ++ ++If you do not use a @code{SECTIONS} command in your linker script, the ++linker will place each input section into an identically named output ++section in the order that the sections are first encountered in the ++input files. If all input sections are present in the first file, for ++example, the order of sections in the output file will match the order ++in the first input file. The first section will be at address zero. ++ ++@menu ++* Output Section Description:: Output section description ++* Output Section Name:: Output section name ++* Output Section Address:: Output section address ++* Input Section:: Input section description ++* Output Section Data:: Output section data ++* Output Section Keywords:: Output section keywords ++* Output Section Discarding:: Output section discarding ++* Output Section Attributes:: Output section attributes ++* Overlay Description:: Overlay description ++@end menu ++ ++@node Output Section Description ++@subsection Output Section Description ++The full description of an output section looks like this: ++@smallexample ++@group ++@var{section} [@var{address}] [(@var{type})] : ++ [AT(@var{lma})] ++ [ALIGN(@var{section_align}) | ALIGN_WITH_INPUT] ++ [SUBALIGN(@var{subsection_align})] ++ [@var{constraint}] ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] [,] ++@end group ++@end smallexample ++ ++Most output sections do not use most of the optional section attributes. ++ ++The whitespace around @var{section} is required, so that the section ++name is unambiguous. The colon and the curly braces are also required. ++The comma at the end may be required if a @var{fillexp} is used and ++the next @var{sections-command} looks like a continuation of the expression. ++The line breaks and other white space are optional. ++ ++Each @var{output-section-command} may be one of the following: ++ ++@itemize @bullet ++@item ++a symbol assignment (@pxref{Assignments}) ++@item ++an input section description (@pxref{Input Section}) ++@item ++data values to include directly (@pxref{Output Section Data}) ++@item ++a special output section keyword (@pxref{Output Section Keywords}) ++@end itemize ++ ++@node Output Section Name ++@subsection Output Section Name ++@cindex name, section ++@cindex section name ++The name of the output section is @var{section}. @var{section} must ++meet the constraints of your output format. In formats which only ++support a limited number of sections, such as @code{a.out}, the name ++must be one of the names supported by the format (@code{a.out}, for ++example, allows only @samp{.text}, @samp{.data} or @samp{.bss}). If the ++output format supports any number of sections, but with numbers and not ++names (as is the case for Oasys), the name should be supplied as a ++quoted numeric string. A section name may consist of any sequence of ++characters, but a name which contains any unusual characters such as ++commas must be quoted. ++ ++The output section name @samp{/DISCARD/} is special; @ref{Output Section ++Discarding}. ++ ++@node Output Section Address ++@subsection Output Section Address ++@cindex address, section ++@cindex section address ++The @var{address} is an expression for the VMA (the virtual memory ++address) of the output section. This address is optional, but if it ++is provided then the output address will be set exactly as specified. ++ ++If the output address is not specified then one will be chosen for the ++section, based on the heuristic below. This address will be adjusted ++to fit the alignment requirement of the output section. The ++alignment requirement is the strictest alignment of any input section ++contained within the output section. ++ ++The output section address heuristic is as follows: ++ ++@itemize @bullet ++@item ++If an output memory @var{region} is set for the section then it ++is added to this region and its address will be the next free address ++in that region. ++ ++@item ++If the MEMORY command has been used to create a list of memory ++regions then the first region which has attributes compatible with the ++section is selected to contain it. The section's output address will ++be the next free address in that region; @ref{MEMORY}. ++ ++@item ++If no memory regions were specified, or none match the section then ++the output address will be based on the current value of the location ++counter. ++@end itemize ++ ++@noindent ++For example: ++ ++@smallexample ++.text . : @{ *(.text) @} ++@end smallexample ++ ++@noindent ++and ++ ++@smallexample ++.text : @{ *(.text) @} ++@end smallexample ++ ++@noindent ++are subtly different. The first will set the address of the ++@samp{.text} output section to the current value of the location ++counter. The second will set it to the current value of the location ++counter aligned to the strictest alignment of any of the @samp{.text} ++input sections. ++ ++The @var{address} may be an arbitrary expression; @ref{Expressions}. ++For example, if you want to align the section on a 0x10 byte boundary, ++so that the lowest four bits of the section address are zero, you could ++do something like this: ++@smallexample ++.text ALIGN(0x10) : @{ *(.text) @} ++@end smallexample ++@noindent ++This works because @code{ALIGN} returns the current location counter ++aligned upward to the specified value. ++ ++Specifying @var{address} for a section will change the value of the ++location counter, provided that the section is non-empty. (Empty ++sections are ignored). ++ ++@node Input Section ++@subsection Input Section Description ++@cindex input sections ++@cindex mapping input sections to output sections ++The most common output section command is an input section description. ++ ++The input section description is the most basic linker script operation. ++You use output sections to tell the linker how to lay out your program ++in memory. You use input section descriptions to tell the linker how to ++map the input files into your memory layout. ++ ++@menu ++* Input Section Basics:: Input section basics ++* Input Section Wildcards:: Input section wildcard patterns ++* Input Section Common:: Input section for common symbols ++* Input Section Keep:: Input section and garbage collection ++* Input Section Example:: Input section example ++@end menu ++ ++@node Input Section Basics ++@subsubsection Input Section Basics ++@cindex input section basics ++An input section description consists of a file name optionally followed ++by a list of section names in parentheses. ++ ++The file name and the section name may be wildcard patterns, which we ++describe further below (@pxref{Input Section Wildcards}). ++ ++The most common input section description is to include all input ++sections with a particular name in the output section. For example, to ++include all input @samp{.text} sections, you would write: ++@smallexample ++*(.text) ++@end smallexample ++@noindent ++Here the @samp{*} is a wildcard which matches any file name. To exclude a list ++@cindex EXCLUDE_FILE ++of files from matching the file name wildcard, EXCLUDE_FILE may be used to ++match all files except the ones specified in the EXCLUDE_FILE list. For ++example: ++@smallexample ++EXCLUDE_FILE (*crtend.o *otherfile.o) *(.ctors) ++@end smallexample ++@noindent ++will cause all .ctors sections from all files except @file{crtend.o} ++and @file{otherfile.o} to be included. The EXCLUDE_FILE can also be ++placed inside the section list, for example: ++@smallexample ++*(EXCLUDE_FILE (*crtend.o *otherfile.o) .ctors) ++@end smallexample ++@noindent ++The result of this is identically to the previous example. Supporting ++two syntaxes for EXCLUDE_FILE is useful if the section list contains ++more than one section, as described below. ++ ++There are two ways to include more than one section: ++@smallexample ++*(.text .rdata) ++*(.text) *(.rdata) ++@end smallexample ++@noindent ++The difference between these is the order in which the @samp{.text} and ++@samp{.rdata} input sections will appear in the output section. In the ++first example, they will be intermingled, appearing in the same order as ++they are found in the linker input. In the second example, all ++@samp{.text} input sections will appear first, followed by all ++@samp{.rdata} input sections. ++ ++When using EXCLUDE_FILE with more than one section, if the exclusion ++is within the section list then the exclusion only applies to the ++immediately following section, for example: ++@smallexample ++*(EXCLUDE_FILE (*somefile.o) .text .rdata) ++@end smallexample ++@noindent ++will cause all @samp{.text} sections from all files except ++@file{somefile.o} to be included, while all @samp{.rdata} sections ++from all files, including @file{somefile.o}, will be included. To ++exclude the @samp{.rdata} sections from @file{somefile.o} the example ++could be modified to: ++@smallexample ++*(EXCLUDE_FILE (*somefile.o) .text EXCLUDE_FILE (*somefile.o) .rdata) ++@end smallexample ++@noindent ++Alternatively, placing the EXCLUDE_FILE outside of the section list, ++before the input file selection, will cause the exclusion to apply for ++all sections. Thus the previous example can be rewritten as: ++@smallexample ++EXCLUDE_FILE (*somefile.o) *(.text .rdata) ++@end smallexample ++ ++You can specify a file name to include sections from a particular file. ++You would do this if one or more of your files contain special data that ++needs to be at a particular location in memory. For example: ++@smallexample ++data.o(.data) ++@end smallexample ++ ++To refine the sections that are included based on the section flags ++of an input section, INPUT_SECTION_FLAGS may be used. ++ ++Here is a simple example for using Section header flags for ELF sections: ++ ++@smallexample ++@group ++SECTIONS @{ ++ .text : @{ INPUT_SECTION_FLAGS (SHF_MERGE & SHF_STRINGS) *(.text) @} ++ .text2 : @{ INPUT_SECTION_FLAGS (!SHF_WRITE) *(.text) @} ++@} ++@end group ++@end smallexample ++ ++In this example, the output section @samp{.text} will be comprised of any ++input section matching the name *(.text) whose section header flags ++@code{SHF_MERGE} and @code{SHF_STRINGS} are set. The output section ++@samp{.text2} will be comprised of any input section matching the name *(.text) ++whose section header flag @code{SHF_WRITE} is clear. ++ ++You can also specify files within archives by writing a pattern ++matching the archive, a colon, then the pattern matching the file, ++with no whitespace around the colon. ++ ++@table @samp ++@item archive:file ++matches file within archive ++@item archive: ++matches the whole archive ++@item :file ++matches file but not one in an archive ++@end table ++ ++Either one or both of @samp{archive} and @samp{file} can contain shell ++wildcards. On DOS based file systems, the linker will assume that a ++single letter followed by a colon is a drive specifier, so ++@samp{c:myfile.o} is a simple file specification, not @samp{myfile.o} ++within an archive called @samp{c}. @samp{archive:file} filespecs may ++also be used within an @code{EXCLUDE_FILE} list, but may not appear in ++other linker script contexts. For instance, you cannot extract a file ++from an archive by using @samp{archive:file} in an @code{INPUT} ++command. ++ ++If you use a file name without a list of sections, then all sections in ++the input file will be included in the output section. This is not ++commonly done, but it may by useful on occasion. For example: ++@smallexample ++data.o ++@end smallexample ++ ++When you use a file name which is not an @samp{archive:file} specifier ++and does not contain any wild card ++characters, the linker will first see if you also specified the file ++name on the linker command line or in an @code{INPUT} command. If you ++did not, the linker will attempt to open the file as an input file, as ++though it appeared on the command line. Note that this differs from an ++@code{INPUT} command, because the linker will not search for the file in ++the archive search path. ++ ++@node Input Section Wildcards ++@subsubsection Input Section Wildcard Patterns ++@cindex input section wildcards ++@cindex wildcard file name patterns ++@cindex file name wildcard patterns ++@cindex section name wildcard patterns ++In an input section description, either the file name or the section ++name or both may be wildcard patterns. ++ ++The file name of @samp{*} seen in many examples is a simple wildcard ++pattern for the file name. ++ ++The wildcard patterns are like those used by the Unix shell. ++ ++@table @samp ++@item * ++matches any number of characters ++@item ? ++matches any single character ++@item [@var{chars}] ++matches a single instance of any of the @var{chars}; the @samp{-} ++character may be used to specify a range of characters, as in ++@samp{[a-z]} to match any lower case letter ++@item \ ++quotes the following character ++@end table ++ ++File name wildcard patterns only match files which are explicitly ++specified on the command line or in an @code{INPUT} command. The linker ++does not search directories to expand wildcards. ++ ++If a file name matches more than one wildcard pattern, or if a file name ++appears explicitly and is also matched by a wildcard pattern, the linker ++will use the first match in the linker script. For example, this ++sequence of input section descriptions is probably in error, because the ++@file{data.o} rule will not be used: ++@smallexample ++.data : @{ *(.data) @} ++.data1 : @{ data.o(.data) @} ++@end smallexample ++ ++@cindex SORT_BY_NAME ++Normally, the linker will place files and sections matched by wildcards ++in the order in which they are seen during the link. You can change ++this by using the @code{SORT_BY_NAME} keyword, which appears before a wildcard ++pattern in parentheses (e.g., @code{SORT_BY_NAME(.text*)}). When the ++@code{SORT_BY_NAME} keyword is used, the linker will sort the files or sections ++into ascending order by name before placing them in the output file. ++ ++@cindex SORT_BY_ALIGNMENT ++@code{SORT_BY_ALIGNMENT} is similar to @code{SORT_BY_NAME}. ++@code{SORT_BY_ALIGNMENT} will sort sections into descending order of ++alignment before placing them in the output file. Placing larger ++alignments before smaller alignments can reduce the amount of padding ++needed. ++ ++@cindex SORT_BY_INIT_PRIORITY ++@code{SORT_BY_INIT_PRIORITY} is also similar to @code{SORT_BY_NAME}. ++@code{SORT_BY_INIT_PRIORITY} will sort sections into ascending ++numerical order of the GCC init_priority attribute encoded in the ++section name before placing them in the output file. In ++@code{.init_array.NNNNN} and @code{.fini_array.NNNNN}, @code{NNNNN} is ++the init_priority. In @code{.ctors.NNNNN} and @code{.dtors.NNNNN}, ++@code{NNNNN} is 65535 minus the init_priority. ++ ++@cindex SORT ++@code{SORT} is an alias for @code{SORT_BY_NAME}. ++ ++When there are nested section sorting commands in linker script, there ++can be at most 1 level of nesting for section sorting commands. ++ ++@enumerate ++@item ++@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)). ++It will sort the input sections by name first, then by alignment if two ++sections have the same name. ++@item ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)). ++It will sort the input sections by alignment first, then by name if two ++sections have the same alignment. ++@item ++@code{SORT_BY_NAME} (@code{SORT_BY_NAME} (wildcard section pattern)) is ++treated the same as @code{SORT_BY_NAME} (wildcard section pattern). ++@item ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)) ++is treated the same as @code{SORT_BY_ALIGNMENT} (wildcard section pattern). ++@item ++All other nested section sorting commands are invalid. ++@end enumerate ++ ++When both command-line section sorting option and linker script ++section sorting command are used, section sorting command always ++takes precedence over the command-line option. ++ ++If the section sorting command in linker script isn't nested, the ++command-line option will make the section sorting command to be ++treated as nested sorting command. ++ ++@enumerate ++@item ++@code{SORT_BY_NAME} (wildcard section pattern ) with ++@option{--sort-sections alignment} is equivalent to ++@code{SORT_BY_NAME} (@code{SORT_BY_ALIGNMENT} (wildcard section pattern)). ++@item ++@code{SORT_BY_ALIGNMENT} (wildcard section pattern) with ++@option{--sort-section name} is equivalent to ++@code{SORT_BY_ALIGNMENT} (@code{SORT_BY_NAME} (wildcard section pattern)). ++@end enumerate ++ ++If the section sorting command in linker script is nested, the ++command-line option will be ignored. ++ ++@cindex SORT_NONE ++@code{SORT_NONE} disables section sorting by ignoring the command-line ++section sorting option. ++ ++If you ever get confused about where input sections are going, use the ++@samp{-M} linker option to generate a map file. The map file shows ++precisely how input sections are mapped to output sections. ++ ++This example shows how wildcard patterns might be used to partition ++files. This linker script directs the linker to place all @samp{.text} ++sections in @samp{.text} and all @samp{.bss} sections in @samp{.bss}. ++The linker will place the @samp{.data} section from all files beginning ++with an upper case character in @samp{.DATA}; for all other files, the ++linker will place the @samp{.data} section in @samp{.data}. ++@smallexample ++@group ++SECTIONS @{ ++ .text : @{ *(.text) @} ++ .DATA : @{ [A-Z]*(.data) @} ++ .data : @{ *(.data) @} ++ .bss : @{ *(.bss) @} ++@} ++@end group ++@end smallexample ++ ++@node Input Section Common ++@subsubsection Input Section for Common Symbols ++@cindex common symbol placement ++@cindex uninitialized data placement ++A special notation is needed for common symbols, because in many object ++file formats common symbols do not have a particular input section. The ++linker treats common symbols as though they are in an input section ++named @samp{COMMON}. ++ ++You may use file names with the @samp{COMMON} section just as with any ++other input sections. You can use this to place common symbols from a ++particular input file in one section while common symbols from other ++input files are placed in another section. ++ ++In most cases, common symbols in input files will be placed in the ++@samp{.bss} section in the output file. For example: ++@smallexample ++.bss @{ *(.bss) *(COMMON) @} ++@end smallexample ++ ++@cindex scommon section ++@cindex small common symbols ++Some object file formats have more than one type of common symbol. For ++example, the MIPS ELF object file format distinguishes standard common ++symbols and small common symbols. In this case, the linker will use a ++different special section name for other types of common symbols. In ++the case of MIPS ELF, the linker uses @samp{COMMON} for standard common ++symbols and @samp{.scommon} for small common symbols. This permits you ++to map the different types of common symbols into memory at different ++locations. ++ ++@cindex [COMMON] ++You will sometimes see @samp{[COMMON]} in old linker scripts. This ++notation is now considered obsolete. It is equivalent to ++@samp{*(COMMON)}. ++ ++@node Input Section Keep ++@subsubsection Input Section and Garbage Collection ++@cindex KEEP ++@cindex garbage collection ++When link-time garbage collection is in use (@samp{--gc-sections}), ++it is often useful to mark sections that should not be eliminated. ++This is accomplished by surrounding an input section's wildcard entry ++with @code{KEEP()}, as in @code{KEEP(*(.init))} or ++@code{KEEP(SORT_BY_NAME(*)(.ctors))}. ++ ++@node Input Section Example ++@subsubsection Input Section Example ++The following example is a complete linker script. It tells the linker ++to read all of the sections from file @file{all.o} and place them at the ++start of output section @samp{outputa} which starts at location ++@samp{0x10000}. All of section @samp{.input1} from file @file{foo.o} ++follows immediately, in the same output section. All of section ++@samp{.input2} from @file{foo.o} goes into output section ++@samp{outputb}, followed by section @samp{.input1} from @file{foo1.o}. ++All of the remaining @samp{.input1} and @samp{.input2} sections from any ++files are written to output section @samp{outputc}. ++ ++@smallexample ++@group ++SECTIONS @{ ++ outputa 0x10000 : ++ @{ ++ all.o ++ foo.o (.input1) ++ @} ++@end group ++@group ++ outputb : ++ @{ ++ foo.o (.input2) ++ foo1.o (.input1) ++ @} ++@end group ++@group ++ outputc : ++ @{ ++ *(.input1) ++ *(.input2) ++ @} ++@} ++@end group ++@end smallexample ++ ++If an output section's name is the same as the input section's name ++and is representable as a C identifier, then the linker will ++automatically @pxref{PROVIDE} two symbols: __start_SECNAME and ++__stop_SECNAME, where SECNAME is the name of the section. These ++indicate the start address and end address of the output section ++respectively. Note: most section names are not representable as ++C identifiers because they contain a @samp{.} character. ++ ++@node Output Section Data ++@subsection Output Section Data ++@cindex data ++@cindex section data ++@cindex output section data ++@kindex ASCIZ ``@var{string}'' ++@kindex BYTE(@var{expression}) ++@kindex SHORT(@var{expression}) ++@kindex LONG(@var{expression}) ++@kindex QUAD(@var{expression}) ++@kindex SQUAD(@var{expression}) ++You can include explicit bytes of data in an output section by using ++@code{BYTE}, @code{SHORT}, @code{LONG}, @code{QUAD}, or @code{SQUAD} as ++an output section command. Each keyword is followed by an expression in ++parentheses providing the value to store (@pxref{Expressions}). The ++value of the expression is stored at the current value of the location ++counter. ++ ++The @code{BYTE}, @code{SHORT}, @code{LONG}, and @code{QUAD} commands ++store one, two, four, and eight bytes (respectively). After storing the ++bytes, the location counter is incremented by the number of bytes ++stored. ++ ++For example, this will store the byte 1 followed by the four byte value ++of the symbol @samp{addr}: ++@smallexample ++BYTE(1) ++LONG(addr) ++@end smallexample ++ ++When using a 64 bit host or target, @code{QUAD} and @code{SQUAD} are the ++same; they both store an 8 byte, or 64 bit, value. When both host and ++target are 32 bits, an expression is computed as 32 bits. In this case ++@code{QUAD} stores a 32 bit value zero extended to 64 bits, and ++@code{SQUAD} stores a 32 bit value sign extended to 64 bits. ++ ++If the object file format of the output file has an explicit endianness, ++which is the normal case, the value will be stored in that endianness. ++When the object file format does not have an explicit endianness, as is ++true of, for example, S-records, the value will be stored in the ++endianness of the first input object file. ++ ++You can include a zero-terminated string in an output section by using ++@code{ASCIZ}. The keyword is followed by a string which is stored at ++the current value of the location counter adding a zero byte at the ++end. If the string includes spaces it must be enclosed in double ++quotes. The string may contain '\n', '\r', '\t' and octal numbers. ++Hex numbers are not supported. ++ ++For example, this string of 16 characters will create a 17 byte area ++@smallexample ++ ASCIZ "This is 16 bytes" ++@end smallexample ++ ++Note---these commands only work inside a section description and not ++between them, so the following will produce an error from the linker: ++@smallexample ++SECTIONS @{@ .text : @{@ *(.text) @}@ LONG(1) .data : @{@ *(.data) @}@ @}@ ++@end smallexample ++whereas this will work: ++@smallexample ++SECTIONS @{@ .text : @{@ *(.text) ; LONG(1) @}@ .data : @{@ *(.data) @}@ @}@ ++@end smallexample ++ ++@kindex FILL(@var{expression}) ++@cindex holes, filling ++@cindex unspecified memory ++You may use the @code{FILL} command to set the fill pattern for the ++current section. It is followed by an expression in parentheses. Any ++otherwise unspecified regions of memory within the section (for example, ++gaps left due to the required alignment of input sections) are filled ++with the value of the expression, repeated as ++necessary. A @code{FILL} statement covers memory locations after the ++point at which it occurs in the section definition; by including more ++than one @code{FILL} statement, you can have different fill patterns in ++different parts of an output section. ++ ++This example shows how to fill unspecified regions of memory with the ++value @samp{0x90}: ++@smallexample ++FILL(0x90909090) ++@end smallexample ++ ++The @code{FILL} command is similar to the @samp{=@var{fillexp}} output ++section attribute, but it only affects the ++part of the section following the @code{FILL} command, rather than the ++entire section. If both are used, the @code{FILL} command takes ++precedence. @xref{Output Section Fill}, for details on the fill ++expression. ++ ++@kindex LINKER_VERSION ++@cindex LINKER_VERSION ++Inserts a string containing the version of the linker at the current ++point. Note - by default this directive is disabled and will do ++nothing. It only becomes active if the ++@option{--enable-linker-version} command line option is used. ++ ++Built-in linker scripts for ELF based targets already include this ++directive in their @samp{.comment} section. ++ ++@node Output Section Keywords ++@subsection Output Section Keywords ++There are a couple of keywords which can appear as output section ++commands. ++ ++@table @code ++@kindex CREATE_OBJECT_SYMBOLS ++@cindex input filename symbols ++@cindex filename symbols ++@item CREATE_OBJECT_SYMBOLS ++The command tells the linker to create a symbol for each input file. ++The name of each symbol will be the name of the corresponding input ++file. The section of each symbol will be the output section in which ++the @code{CREATE_OBJECT_SYMBOLS} command appears. ++ ++This is conventional for the a.out object file format. It is not ++normally used for any other object file format. ++ ++@kindex CONSTRUCTORS ++@cindex C++ constructors, arranging in link ++@cindex constructors, arranging in link ++@item CONSTRUCTORS ++When linking using the a.out object file format, the linker uses an ++unusual set construct to support C++ global constructors and ++destructors. When linking object file formats which do not support ++arbitrary sections, such as ECOFF and XCOFF, the linker will ++automatically recognize C++ global constructors and destructors by name. ++For these object file formats, the @code{CONSTRUCTORS} command tells the ++linker to place constructor information in the output section where the ++@code{CONSTRUCTORS} command appears. The @code{CONSTRUCTORS} command is ++ignored for other object file formats. ++ ++The symbol @w{@code{__CTOR_LIST__}} marks the start of the global ++constructors, and the symbol @w{@code{__CTOR_END__}} marks the end. ++Similarly, @w{@code{__DTOR_LIST__}} and @w{@code{__DTOR_END__}} mark ++the start and end of the global destructors. The ++first word in the list is the number of entries, followed by the address ++of each constructor or destructor, followed by a zero word. The ++compiler must arrange to actually run the code. For these object file ++formats @sc{gnu} C++ normally calls constructors from a subroutine ++@code{__main}; a call to @code{__main} is automatically inserted into ++the startup code for @code{main}. @sc{gnu} C++ normally runs ++destructors either by using @code{atexit}, or directly from the function ++@code{exit}. ++ ++For object file formats such as @code{COFF} or @code{ELF} which support ++arbitrary section names, @sc{gnu} C++ will normally arrange to put the ++addresses of global constructors and destructors into the @code{.ctors} ++and @code{.dtors} sections. Placing the following sequence into your ++linker script will build the sort of table which the @sc{gnu} C++ ++runtime code expects to see. ++ ++@smallexample ++ __CTOR_LIST__ = .; ++ LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2) ++ *(.ctors) ++ LONG(0) ++ __CTOR_END__ = .; ++ __DTOR_LIST__ = .; ++ LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2) ++ *(.dtors) ++ LONG(0) ++ __DTOR_END__ = .; ++@end smallexample ++ ++If you are using the @sc{gnu} C++ support for initialization priority, ++which provides some control over the order in which global constructors ++are run, you must sort the constructors at link time to ensure that they ++are executed in the correct order. When using the @code{CONSTRUCTORS} ++command, use @samp{SORT_BY_NAME(CONSTRUCTORS)} instead. When using the ++@code{.ctors} and @code{.dtors} sections, use @samp{*(SORT_BY_NAME(.ctors))} and ++@samp{*(SORT_BY_NAME(.dtors))} instead of just @samp{*(.ctors)} and ++@samp{*(.dtors)}. ++ ++Normally the compiler and linker will handle these issues automatically, ++and you will not need to concern yourself with them. However, you may ++need to consider this if you are using C++ and writing your own linker ++scripts. ++ ++@end table ++ ++@node Output Section Discarding ++@subsection Output Section Discarding ++@cindex discarding sections ++@cindex sections, discarding ++@cindex removing sections ++The linker will not normally create output sections with no contents. ++This is for convenience when referring to input sections that may or ++may not be present in any of the input files. For example: ++@smallexample ++.foo : @{ *(.foo) @} ++@end smallexample ++@noindent ++will only create a @samp{.foo} section in the output file if there is a ++@samp{.foo} section in at least one input file, and if the input ++sections are not all empty. Other link script directives that allocate ++space in an output section will also create the output section. So ++too will assignments to dot even if the assignment does not create ++space, except for @samp{. = 0}, @samp{. = . + 0}, @samp{. = sym}, ++@samp{. = . + sym} and @samp{. = ALIGN (. != 0, expr, 1)} when ++@samp{sym} is an absolute symbol of value 0 defined in the script. ++This allows you to force output of an empty section with @samp{. = .}. ++ ++The linker will ignore address assignments (@pxref{Output Section Address}) ++on discarded output sections, except when the linker script defines ++symbols in the output section. In that case the linker will obey ++the address assignments, possibly advancing dot even though the ++section is discarded. ++ ++@cindex /DISCARD/ ++The special output section name @samp{/DISCARD/} may be used to discard ++input sections. Any input sections which are assigned to an output ++section named @samp{/DISCARD/} are not included in the output file. ++ ++This can be used to discard input sections marked with the ELF flag ++@code{SHF_GNU_RETAIN}, which would otherwise have been saved from linker ++garbage collection. ++ ++Note, sections that match the @samp{/DISCARD/} output section will be ++discarded even if they are in an ELF section group which has other ++members which are not being discarded. This is deliberate. ++Discarding takes precedence over grouping. ++ ++@node Output Section Attributes ++@subsection Output Section Attributes ++@cindex output section attributes ++We showed above that the full description of an output section looked ++like this: ++ ++@smallexample ++@group ++@var{section} [@var{address}] [(@var{type})] : ++ [AT(@var{lma})] ++ [ALIGN(@var{section_align}) | ALIGN_WITH_INPUT] ++ [SUBALIGN(@var{subsection_align})] ++ [@var{constraint}] ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [>@var{region}] [AT>@var{lma_region}] [:@var{phdr} :@var{phdr} @dots{}] [=@var{fillexp}] ++@end group ++@end smallexample ++ ++We've already described @var{section}, @var{address}, and ++@var{output-section-command}. In this section we will describe the ++remaining section attributes. ++ ++@menu ++* Output Section Type:: Output section type ++* Output Section LMA:: Output section LMA ++* Forced Output Alignment:: Forced Output Alignment ++* Forced Input Alignment:: Forced Input Alignment ++* Output Section Constraint:: Output section constraint ++* Output Section Region:: Output section region ++* Output Section Phdr:: Output section phdr ++* Output Section Fill:: Output section fill ++@end menu ++ ++@node Output Section Type ++@subsubsection Output Section Type ++Each output section may have a type. The type is a keyword in ++parentheses. The following types are defined: ++ ++@table @code ++ ++@item NOLOAD ++The section should be marked as not loadable, so that it will not be ++loaded into memory when the program is run. ++ ++@item READONLY ++The section should be marked as read-only. ++ ++@item DSECT ++@item COPY ++@item INFO ++@item OVERLAY ++These type names are supported for backward compatibility, and are ++rarely used. They all have the same effect: the section should be ++marked as not allocatable, so that no memory is allocated for the ++section when the program is run. ++ ++@item TYPE = @var{type} ++Set the section type to the integer @var{type}. When generating an ELF ++output file, type names @code{SHT_PROGBITS}, @code{SHT_STRTAB}, ++@code{SHT_NOTE}, @code{SHT_NOBITS}, @code{SHT_INIT_ARRAY}, ++@code{SHT_FINI_ARRAY}, and @code{SHT_PREINIT_ARRAY} are also allowed ++for @var{type}. It is the user's responsibility to ensure that any ++special requirements of the section type are met. ++ ++Note - the TYPE only is used if some or all of the contents of the ++section do not have an implicit type of their own. So for example: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ *(.bar) @} ++@end smallexample ++will set the type of section @samp{.foo} to the type of the section ++@samp{.bar} in the input files, which may not be the SHT_PROGBITS ++type. Whereas: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ BYTE(1) @} ++@end smallexample ++will set the type of @samp{.foo} to SHT_PROGBBITS. If it is necessary ++to override the type of incoming sections and force the output section ++type then an extra piece of untyped data will be needed: ++@smallexample ++ .foo . TYPE = SHT_PROGBITS @{ BYTE(1); *(.bar) @} ++@end smallexample ++ ++@item READONLY ( TYPE = @var{type} ) ++This form of the syntax combines the @var{READONLY} type with the ++type specified by @var{type}. ++ ++@end table ++ ++@kindex NOLOAD ++@cindex prevent unnecessary loading ++@cindex loading, preventing ++The linker normally sets the attributes of an output section based on ++the input sections which map into it. You can override this by using ++the section type. For example, in the script sample below, the ++@samp{ROM} section is addressed at memory location @samp{0} and does not ++need to be loaded when the program is run. ++@smallexample ++@group ++SECTIONS @{ ++ ROM 0 (NOLOAD) : @{ @dots{} @} ++ @dots{} ++@} ++@end group ++@end smallexample ++ ++@node Output Section LMA ++@subsubsection Output Section LMA ++@kindex AT>@var{lma_region} ++@kindex AT(@var{lma}) ++@cindex load address ++@cindex section load address ++Every section has a virtual address (VMA) and a load address (LMA); see ++@ref{Basic Script Concepts}. The virtual address is specified by the ++@pxref{Output Section Address} described earlier. The load address is ++specified by the @code{AT} or @code{AT>} keywords. Specifying a load ++address is optional. ++ ++The @code{AT} keyword takes an expression as an argument. This ++specifies the exact load address of the section. The @code{AT>} keyword ++takes the name of a memory region as an argument. @xref{MEMORY}. The ++load address of the section is set to the next free address in the ++region, aligned to the section's alignment requirements. ++ ++If neither @code{AT} nor @code{AT>} is specified for an allocatable ++section, the linker will use the following heuristic to determine the ++load address: ++ ++@itemize @bullet ++@item ++If the section has a specific VMA address, then this is used as ++the LMA address as well. ++ ++@item ++If the section is not allocatable then its LMA is set to its VMA. ++ ++@item ++Otherwise if a memory region can be found that is compatible ++with the current section, and this region contains at least one ++section, then the LMA is set so the difference between the ++VMA and LMA is the same as the difference between the VMA and LMA of ++the last section in the located region. ++ ++@item ++If no memory regions have been declared then a default region ++that covers the entire address space is used in the previous step. ++ ++@item ++If no suitable region could be found, or there was no previous ++section then the LMA is set equal to the VMA. ++@end itemize ++ ++@cindex ROM initialized data ++@cindex initialized data in ROM ++This feature is designed to make it easy to build a ROM image. For ++example, the following linker script creates three output sections: one ++called @samp{.text}, which starts at @code{0x1000}, one called ++@samp{.mdata}, which is loaded at the end of the @samp{.text} section ++even though its VMA is @code{0x2000}, and one called @samp{.bss} to hold ++uninitialized data at address @code{0x3000}. The symbol @code{_data} is ++defined with the value @code{0x2000}, which shows that the location ++counter holds the VMA value, not the LMA value. ++ ++@smallexample ++@group ++SECTIONS ++ @{ ++ .text 0x1000 : @{ *(.text) _etext = . ; @} ++ .mdata 0x2000 : ++ AT ( ADDR (.text) + SIZEOF (.text) ) ++ @{ _data = . ; *(.data); _edata = . ; @} ++ .bss 0x3000 : ++ @{ _bstart = . ; *(.bss) *(COMMON) ; _bend = . ;@} ++@} ++@end group ++@end smallexample ++ ++The run-time initialization code for use with a program generated with ++this linker script would include something like the following, to copy ++the initialized data from the ROM image to its runtime address. Notice ++how this code takes advantage of the symbols defined by the linker ++script. ++ ++@smallexample ++@group ++extern char _etext, _data, _edata, _bstart, _bend; ++char *src = &_etext; ++char *dst = &_data; ++ ++/* ROM has data at end of text; copy it. */ ++while (dst < &_edata) ++ *dst++ = *src++; ++ ++/* Zero bss. */ ++for (dst = &_bstart; dst< &_bend; dst++) ++ *dst = 0; ++@end group ++@end smallexample ++ ++@node Forced Output Alignment ++@subsubsection Forced Output Alignment ++@kindex ALIGN(@var{section_align}) ++@cindex forcing output section alignment ++@cindex output section alignment ++You can increase an output section's alignment by using ALIGN. As an ++alternative you can enforce that the difference between the VMA and LMA remains ++intact throughout this output section with the ALIGN_WITH_INPUT attribute. ++ ++@node Forced Input Alignment ++@subsubsection Forced Input Alignment ++@kindex SUBALIGN(@var{subsection_align}) ++@cindex forcing input section alignment ++@cindex input section alignment ++You can force input section alignment within an output section by using ++SUBALIGN. The value specified overrides any alignment given by input ++sections, whether larger or smaller. ++ ++@node Output Section Constraint ++@subsubsection Output Section Constraint ++@kindex ONLY_IF_RO ++@kindex ONLY_IF_RW ++@cindex constraints on output sections ++You can specify that an output section should only be created if all ++of its input sections are read-only or all of its input sections are ++read-write by using the keyword @code{ONLY_IF_RO} and ++@code{ONLY_IF_RW} respectively. ++ ++@node Output Section Region ++@subsubsection Output Section Region ++@kindex >@var{region} ++@cindex section, assigning to memory region ++@cindex memory regions and sections ++You can assign a section to a previously defined region of memory by ++using @samp{>@var{region}}. @xref{MEMORY}. ++ ++Here is a simple example: ++@smallexample ++@group ++MEMORY @{ rom : ORIGIN = 0x1000, LENGTH = 0x1000 @} ++SECTIONS @{ ROM : @{ *(.text) @} >rom @} ++@end group ++@end smallexample ++ ++@node Output Section Phdr ++@subsubsection Output Section Phdr ++@kindex :@var{phdr} ++@cindex section, assigning to program header ++@cindex program headers and sections ++You can assign a section to a previously defined program segment by ++using @samp{:@var{phdr}}. @xref{PHDRS}. If a section is assigned to ++one or more segments, then all subsequent allocated sections will be ++assigned to those segments as well, unless they use an explicitly ++@code{:@var{phdr}} modifier. You can use @code{:NONE} to tell the ++linker to not put the section in any segment at all. ++ ++Here is a simple example: ++@smallexample ++@group ++PHDRS @{ text PT_LOAD ; @} ++SECTIONS @{ .text : @{ *(.text) @} :text @} ++@end group ++@end smallexample ++ ++@node Output Section Fill ++@subsubsection Output Section Fill ++@kindex =@var{fillexp} ++@cindex section fill pattern ++@cindex fill pattern, entire section ++You can set the fill pattern for an entire section by using ++@samp{=@var{fillexp}}. @var{fillexp} is an expression ++(@pxref{Expressions}). Any otherwise unspecified regions of memory ++within the output section (for example, gaps left due to the required ++alignment of input sections) will be filled with the value, repeated as ++necessary. If the fill expression is a simple hex number, ie. a string ++of hex digit starting with @samp{0x} and without a trailing @samp{k} or @samp{M}, then ++an arbitrarily long sequence of hex digits can be used to specify the ++fill pattern; Leading zeros become part of the pattern too. For all ++other cases, including extra parentheses or a unary @code{+}, the fill ++pattern is the four least significant bytes of the value of the ++expression. In all cases, the number is big-endian. ++ ++You can also change the fill value with a @code{FILL} command in the ++output section commands; (@pxref{Output Section Data}). ++ ++Here is a simple example: ++@smallexample ++@group ++SECTIONS @{ .text : @{ *(.text) @} =0x90909090 @} ++@end group ++@end smallexample ++ ++@node Overlay Description ++@subsection Overlay Description ++@kindex OVERLAY ++@cindex overlays ++An overlay description provides an easy way to describe sections which ++are to be loaded as part of a single memory image but are to be run at ++the same memory address. At run time, some sort of overlay manager will ++copy the overlaid sections in and out of the runtime memory address as ++required, perhaps by simply manipulating addressing bits. This approach ++can be useful, for example, when a certain region of memory is faster ++than another. ++ ++Overlays are described using the @code{OVERLAY} command. The ++@code{OVERLAY} command is used within a @code{SECTIONS} command, like an ++output section description. The full syntax of the @code{OVERLAY} ++command is as follows: ++@smallexample ++@group ++OVERLAY [@var{start}] : [NOCROSSREFS] [AT ( @var{ldaddr} )] ++ @{ ++ @var{secname1} ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [:@var{phdr}@dots{}] [=@var{fill}] ++ @var{secname2} ++ @{ ++ @var{output-section-command} ++ @var{output-section-command} ++ @dots{} ++ @} [:@var{phdr}@dots{}] [=@var{fill}] ++ @dots{} ++ @} [>@var{region}] [:@var{phdr}@dots{}] [=@var{fill}] [,] ++@end group ++@end smallexample ++ ++Everything is optional except @code{OVERLAY} (a keyword), and each ++section must have a name (@var{secname1} and @var{secname2} above). The ++section definitions within the @code{OVERLAY} construct are identical to ++those within the general @code{SECTIONS} construct (@pxref{SECTIONS}), ++except that no addresses and no memory regions may be defined for ++sections within an @code{OVERLAY}. ++ ++The comma at the end may be required if a @var{fill} is used and ++the next @var{sections-command} looks like a continuation of the expression. ++ ++The sections are all defined with the same starting address. The load ++addresses of the sections are arranged such that they are consecutive in ++memory starting at the load address used for the @code{OVERLAY} as a ++whole (as with normal section definitions, the load address is optional, ++and defaults to the start address; the start address is also optional, ++and defaults to the current value of the location counter). ++ ++If the @code{NOCROSSREFS} keyword is used, and there are any ++references among the sections, the linker will report an error. Since ++the sections all run at the same address, it normally does not make ++sense for one section to refer directly to another. ++@xref{Miscellaneous Commands, NOCROSSREFS}. ++ ++For each section within the @code{OVERLAY}, the linker automatically ++provides two symbols. The symbol @code{__load_start_@var{secname}} is ++defined as the starting load address of the section. The symbol ++@code{__load_stop_@var{secname}} is defined as the final load address of ++the section. Any characters within @var{secname} which are not legal ++within C identifiers are removed. C (or assembler) code may use these ++symbols to move the overlaid sections around as necessary. ++ ++At the end of the overlay, the value of the location counter is set to ++the start address of the overlay plus the size of the largest section. ++ ++Here is an example. Remember that this would appear inside a ++@code{SECTIONS} construct. ++@smallexample ++@group ++ OVERLAY 0x1000 : AT (0x4000) ++ @{ ++ .text0 @{ o1/*.o(.text) @} ++ .text1 @{ o2/*.o(.text) @} ++ @} ++@end group ++@end smallexample ++@noindent ++This will define both @samp{.text0} and @samp{.text1} to start at ++address 0x1000. @samp{.text0} will be loaded at address 0x4000, and ++@samp{.text1} will be loaded immediately after @samp{.text0}. The ++following symbols will be defined if referenced: @code{__load_start_text0}, ++@code{__load_stop_text0}, @code{__load_start_text1}, ++@code{__load_stop_text1}. ++ ++C code to copy overlay @code{.text1} into the overlay area might look ++like the following. ++ ++@smallexample ++@group ++ extern char __load_start_text1, __load_stop_text1; ++ memcpy ((char *) 0x1000, &__load_start_text1, ++ &__load_stop_text1 - &__load_start_text1); ++@end group ++@end smallexample ++ ++Note that the @code{OVERLAY} command is just syntactic sugar, since ++everything it does can be done using the more basic commands. The above ++example could have been written identically as follows. ++ ++@smallexample ++@group ++ .text0 0x1000 : AT (0x4000) @{ o1/*.o(.text) @} ++ PROVIDE (__load_start_text0 = LOADADDR (.text0)); ++ PROVIDE (__load_stop_text0 = LOADADDR (.text0) + SIZEOF (.text0)); ++ .text1 0x1000 : AT (0x4000 + SIZEOF (.text0)) @{ o2/*.o(.text) @} ++ PROVIDE (__load_start_text1 = LOADADDR (.text1)); ++ PROVIDE (__load_stop_text1 = LOADADDR (.text1) + SIZEOF (.text1)); ++ . = 0x1000 + MAX (SIZEOF (.text0), SIZEOF (.text1)); ++@end group ++@end smallexample ++ ++@node MEMORY ++@section MEMORY Command ++@kindex MEMORY ++@cindex memory regions ++@cindex regions of memory ++@cindex allocating memory ++@cindex discontinuous memory ++The linker's default configuration permits allocation of all available ++memory. You can override this by using the @code{MEMORY} command. ++ ++The @code{MEMORY} command describes the location and size of blocks of ++memory in the target. You can use it to describe which memory regions ++may be used by the linker, and which memory regions it must avoid. You ++can then assign sections to particular memory regions. The linker will ++set section addresses based on the memory regions, and will warn about ++regions that become too full. The linker will not shuffle sections ++around to fit into the available regions. ++ ++A linker script may contain many uses of the @code{MEMORY} command, ++however, all memory blocks defined are treated as if they were ++specified inside a single @code{MEMORY} command. The syntax for ++@code{MEMORY} is: ++@smallexample ++@group ++MEMORY ++ @{ ++ @var{name} [(@var{attr})] : ORIGIN = @var{origin}, LENGTH = @var{len} ++ @dots{} ++ @} ++@end group ++@end smallexample ++ ++The @var{name} is a name used in the linker script to refer to the ++region. The region name has no meaning outside of the linker script. ++Region names are stored in a separate name space, and will not conflict ++with symbol names, file names, or section names. Each memory region ++must have a distinct name within the @code{MEMORY} command. However you can ++add later alias names to existing memory regions with the @ref{REGION_ALIAS} ++command. ++ ++@cindex memory region attributes ++The @var{attr} string is an optional list of attributes that specify ++whether to use a particular memory region for an input section which is ++not explicitly mapped in the linker script. As described in ++@ref{SECTIONS}, if you do not specify an output section for some input ++section, the linker will create an output section with the same name as ++the input section. If you define region attributes, the linker will use ++them to select the memory region for the output section that it creates. ++ ++The @var{attr} string must consist only of the following characters: ++@table @samp ++@item R ++Read-only section ++@item W ++Read/write section ++@item X ++Executable section ++@item A ++Allocatable section ++@item I ++Initialized section ++@item L ++Same as @samp{I} ++@item ! ++Invert the sense of any of the attributes that follow ++@end table ++ ++If an unmapped section matches any of the listed attributes other than ++@samp{!}, it will be placed in the memory region. The @samp{!} ++attribute reverses the test for the characters that follow, so that an ++unmapped section will be placed in the memory region only if it does ++not match any of the attributes listed afterwards. Thus an attribute ++string of @samp{RW!X} will match any unmapped section that has either ++or both of the @samp{R} and @samp{W} attributes, but only as long as ++the section does not also have the @samp{X} attribute. ++ ++@kindex ORIGIN = ++@kindex o = ++@kindex org = ++The @var{origin} is an numerical expression for the start address of ++the memory region. The expression must evaluate to a constant and it ++cannot involve any symbols. The keyword @code{ORIGIN} may be ++abbreviated to @code{org} or @code{o} (but not, for example, ++@code{ORG}). ++ ++@kindex LENGTH = ++@kindex len = ++@kindex l = ++The @var{len} is an expression for the size in bytes of the memory ++region. As with the @var{origin} expression, the expression must ++be numerical only and must evaluate to a constant. The keyword ++@code{LENGTH} may be abbreviated to @code{len} or @code{l}. ++ ++In the following example, we specify that there are two memory regions ++available for allocation: one starting at @samp{0} for 256 kilobytes, ++and the other starting at @samp{0x40000000} for four megabytes. The ++linker will place into the @samp{rom} memory region every section which ++is not explicitly mapped into a memory region, and is either read-only ++or executable. The linker will place other sections which are not ++explicitly mapped into a memory region into the @samp{ram} memory ++region. ++ ++@smallexample ++@group ++MEMORY ++ @{ ++ rom (rx) : ORIGIN = 0, LENGTH = 256K ++ ram (!rx) : org = 0x40000000, l = 4M ++ @} ++@end group ++@end smallexample ++ ++Once you define a memory region, you can direct the linker to place ++specific output sections into that memory region by using the ++@samp{>@var{region}} output section attribute. For example, if you have ++a memory region named @samp{mem}, you would use @samp{>mem} in the ++output section definition. @xref{Output Section Region}. If no address ++was specified for the output section, the linker will set the address to ++the next available address within the memory region. If the combined ++output sections directed to a memory region are too large for the ++region, the linker will issue an error message. ++ ++It is possible to access the origin and length of a memory in an ++expression via the @code{ORIGIN(@var{memory})} and ++@code{LENGTH(@var{memory})} functions: ++ ++@smallexample ++@group ++ _fstack = ORIGIN(ram) + LENGTH(ram) - 4; ++@end group ++@end smallexample ++ ++@node PHDRS ++@section PHDRS Command ++@kindex PHDRS ++@cindex program headers ++@cindex ELF program headers ++@cindex program segments ++@cindex segments, ELF ++The ELF object file format uses @dfn{program headers}, also knows as ++@dfn{segments}. The program headers describe how the program should be ++loaded into memory. You can print them out by using the @code{objdump} ++program with the @samp{-p} option. ++ ++When you run an ELF program on a native ELF system, the system loader ++reads the program headers in order to figure out how to load the ++program. This will only work if the program headers are set correctly. ++This manual does not describe the details of how the system loader ++interprets program headers; for more information, see the ELF ABI. ++ ++The linker will create reasonable program headers by default. However, ++in some cases, you may need to specify the program headers more ++precisely. You may use the @code{PHDRS} command for this purpose. When ++the linker sees the @code{PHDRS} command in the linker script, it will ++not create any program headers other than the ones specified. ++ ++The linker only pays attention to the @code{PHDRS} command when ++generating an ELF output file. In other cases, the linker will simply ++ignore @code{PHDRS}. ++ ++This is the syntax of the @code{PHDRS} command. The words @code{PHDRS}, ++@code{FILEHDR}, @code{AT}, and @code{FLAGS} are keywords. ++ ++@smallexample ++@group ++PHDRS ++@{ ++ @var{name} @var{type} [ FILEHDR ] [ PHDRS ] [ AT ( @var{address} ) ] ++ [ FLAGS ( @var{flags} ) ] ; ++@} ++@end group ++@end smallexample ++ ++The @var{name} is used only for reference in the @code{SECTIONS} command ++of the linker script. It is not put into the output file. Program ++header names are stored in a separate name space, and will not conflict ++with symbol names, file names, or section names. Each program header ++must have a distinct name. The headers are processed in order and it ++is usual for them to map to sections in ascending load address order. ++ ++Certain program header types describe segments of memory which the ++system loader will load from the file. In the linker script, you ++specify the contents of these segments by placing allocatable output ++sections in the segments. You use the @samp{:@var{phdr}} output section ++attribute to place a section in a particular segment. @xref{Output ++Section Phdr}. ++ ++It is normal to put certain sections in more than one segment. This ++merely implies that one segment of memory contains another. You may ++repeat @samp{:@var{phdr}}, using it once for each segment which should ++contain the section. ++ ++If you place a section in one or more segments using @samp{:@var{phdr}}, ++then the linker will place all subsequent allocatable sections which do ++not specify @samp{:@var{phdr}} in the same segments. This is for ++convenience, since generally a whole set of contiguous sections will be ++placed in a single segment. You can use @code{:NONE} to override the ++default segment and tell the linker to not put the section in any ++segment at all. ++ ++@kindex FILEHDR ++@kindex PHDRS ++You may use the @code{FILEHDR} and @code{PHDRS} keywords after ++the program header type to further describe the contents of the segment. ++The @code{FILEHDR} keyword means that the segment should include the ELF ++file header. The @code{PHDRS} keyword means that the segment should ++include the ELF program headers themselves. If applied to a loadable ++segment (@code{PT_LOAD}), all prior loadable segments must have one of ++these keywords. ++ ++The @var{type} may be one of the following. The numbers indicate the ++value of the keyword. ++ ++@table @asis ++@item @code{PT_NULL} (0) ++Indicates an unused program header. ++ ++@item @code{PT_LOAD} (1) ++Indicates that this program header describes a segment to be loaded from ++the file. ++ ++@item @code{PT_DYNAMIC} (2) ++Indicates a segment where dynamic linking information can be found. ++ ++@item @code{PT_INTERP} (3) ++Indicates a segment where the name of the program interpreter may be ++found. ++ ++@item @code{PT_NOTE} (4) ++Indicates a segment holding note information. ++ ++@item @code{PT_SHLIB} (5) ++A reserved program header type, defined but not specified by the ELF ++ABI. ++ ++@item @code{PT_PHDR} (6) ++Indicates a segment where the program headers may be found. ++ ++@item @code{PT_TLS} (7) ++Indicates a segment containing thread local storage. ++ ++@item @var{expression} ++An expression giving the numeric type of the program header. This may ++be used for types not defined above. ++@end table ++ ++You can specify that a segment should be loaded at a particular address ++in memory by using an @code{AT} expression. This is identical to the ++@code{AT} command used as an output section attribute (@pxref{Output ++Section LMA}). The @code{AT} command for a program header overrides the ++output section attribute. ++ ++The linker will normally set the segment flags based on the sections ++which comprise the segment. You may use the @code{FLAGS} keyword to ++explicitly specify the segment flags. The value of @var{flags} must be ++an integer. It is used to set the @code{p_flags} field of the program ++header. ++ ++Here is an example of @code{PHDRS}. This shows a typical set of program ++headers used on a native ELF system. ++ ++@example ++@group ++PHDRS ++@{ ++ headers PT_PHDR PHDRS ; ++ interp PT_INTERP ; ++ text PT_LOAD FILEHDR PHDRS ; ++ data PT_LOAD ; ++ dynamic PT_DYNAMIC ; ++@} ++ ++SECTIONS ++@{ ++ . = SIZEOF_HEADERS; ++ .interp : @{ *(.interp) @} :text :interp ++ .text : @{ *(.text) @} :text ++ .rodata : @{ *(.rodata) @} /* defaults to :text */ ++ @dots{} ++ . = . + 0x1000; /* move to a new page in memory */ ++ .data : @{ *(.data) @} :data ++ .dynamic : @{ *(.dynamic) @} :data :dynamic ++ @dots{} ++@} ++@end group ++@end example ++ ++@node VERSION ++@section VERSION Command ++@kindex VERSION @{script text@} ++@cindex symbol versions ++@cindex version script ++@cindex versions of symbols ++The linker supports symbol versions when using ELF. Symbol versions are ++only useful when using shared libraries. The dynamic linker can use ++symbol versions to select a specific version of a function when it runs ++a program that may have been linked against an earlier version of the ++shared library. ++ ++You can include a version script directly in the main linker script, or ++you can supply the version script as an implicit linker script. You can ++also use the @samp{--version-script} linker option. ++ ++The syntax of the @code{VERSION} command is simply ++@smallexample ++VERSION @{ version-script-commands @} ++@end smallexample ++ ++The format of the version script commands is identical to that used by ++Sun's linker in Solaris 2.5. The version script defines a tree of ++version nodes. You specify the node names and interdependencies in the ++version script. You can specify which symbols are bound to which ++version nodes, and you can reduce a specified set of symbols to local ++scope so that they are not globally visible outside of the shared ++library. ++ ++The easiest way to demonstrate the version script language is with a few ++examples. ++ ++@smallexample ++VERS_1.1 @{ ++ global: ++ foo1; ++ local: ++ old*; ++ original*; ++ new*; ++@}; ++ ++VERS_1.2 @{ ++ foo2; ++@} VERS_1.1; ++ ++VERS_2.0 @{ ++ bar1; bar2; ++ extern "C++" @{ ++ ns::*; ++ "f(int, double)"; ++ @}; ++@} VERS_1.2; ++@end smallexample ++ ++This example version script defines three version nodes. The first ++version node defined is @samp{VERS_1.1}; it has no other dependencies. ++The script binds the symbol @samp{foo1} to @samp{VERS_1.1}. It reduces ++a number of symbols to local scope so that they are not visible outside ++of the shared library; this is done using wildcard patterns, so that any ++symbol whose name begins with @samp{old}, @samp{original}, or @samp{new} ++is matched. The wildcard patterns available are the same as those used ++in the shell when matching filenames (also known as ``globbing''). ++However, if you specify the symbol name inside double quotes, then the ++name is treated as literal, rather than as a glob pattern. ++ ++Next, the version script defines node @samp{VERS_1.2}. This node ++depends upon @samp{VERS_1.1}. The script binds the symbol @samp{foo2} ++to the version node @samp{VERS_1.2}. ++ ++Finally, the version script defines node @samp{VERS_2.0}. This node ++depends upon @samp{VERS_1.2}. The scripts binds the symbols @samp{bar1} ++and @samp{bar2} are bound to the version node @samp{VERS_2.0}. ++ ++When the linker finds a symbol defined in a library which is not ++specifically bound to a version node, it will effectively bind it to an ++unspecified base version of the library. You can bind all otherwise ++unspecified symbols to a given version node by using @samp{global: *;} ++somewhere in the version script. Note that it's slightly crazy to use ++wildcards in a global spec except on the last version node. Global ++wildcards elsewhere run the risk of accidentally adding symbols to the ++set exported for an old version. That's wrong since older versions ++ought to have a fixed set of symbols. ++ ++The names of the version nodes have no specific meaning other than what ++they might suggest to the person reading them. The @samp{2.0} version ++could just as well have appeared in between @samp{1.1} and @samp{1.2}. ++However, this would be a confusing way to write a version script. ++ ++Node name can be omitted, provided it is the only version node ++in the version script. Such version script doesn't assign any versions to ++symbols, only selects which symbols will be globally visible out and which ++won't. ++ ++@smallexample ++@{ global: foo; bar; local: *; @}; ++@end smallexample ++ ++When you link an application against a shared library that has versioned ++symbols, the application itself knows which version of each symbol it ++requires, and it also knows which version nodes it needs from each ++shared library it is linked against. Thus at runtime, the dynamic ++loader can make a quick check to make sure that the libraries you have ++linked against do in fact supply all of the version nodes that the ++application will need to resolve all of the dynamic symbols. In this ++way it is possible for the dynamic linker to know with certainty that ++all external symbols that it needs will be resolvable without having to ++search for each symbol reference. ++ ++The symbol versioning is in effect a much more sophisticated way of ++doing minor version checking that SunOS does. The fundamental problem ++that is being addressed here is that typically references to external ++functions are bound on an as-needed basis, and are not all bound when ++the application starts up. If a shared library is out of date, a ++required interface may be missing; when the application tries to use ++that interface, it may suddenly and unexpectedly fail. With symbol ++versioning, the user will get a warning when they start their program if ++the libraries being used with the application are too old. ++ ++There are several GNU extensions to Sun's versioning approach. The ++first of these is the ability to bind a symbol to a version node in the ++source file where the symbol is defined instead of in the versioning ++script. This was done mainly to reduce the burden on the library ++maintainer. You can do this by putting something like: ++@smallexample ++__asm__(".symver original_foo,foo@@VERS_1.1"); ++@end smallexample ++@noindent ++in the C source file. This renames the function @samp{original_foo} to ++be an alias for @samp{foo} bound to the version node @samp{VERS_1.1}. ++The @samp{local:} directive can be used to prevent the symbol ++@samp{original_foo} from being exported. A @samp{.symver} directive ++takes precedence over a version script. ++ ++The second GNU extension is to allow multiple versions of the same ++function to appear in a given shared library. In this way you can make ++an incompatible change to an interface without increasing the major ++version number of the shared library, while still allowing applications ++linked against the old interface to continue to function. ++ ++To do this, you must use multiple @samp{.symver} directives in the ++source file. Here is an example: ++ ++@smallexample ++__asm__(".symver original_foo,foo@@"); ++__asm__(".symver old_foo,foo@@VERS_1.1"); ++__asm__(".symver old_foo1,foo@@VERS_1.2"); ++__asm__(".symver new_foo,foo@@@@VERS_2.0"); ++@end smallexample ++ ++In this example, @samp{foo@@} represents the symbol @samp{foo} bound to the ++unspecified base version of the symbol. The source file that contains this ++example would define 4 C functions: @samp{original_foo}, @samp{old_foo}, ++@samp{old_foo1}, and @samp{new_foo}. ++ ++When you have multiple definitions of a given symbol, there needs to be ++some way to specify a default version to which external references to ++this symbol will be bound. You can do this with the ++@samp{foo@@@@VERS_2.0} type of @samp{.symver} directive. You can only ++declare one version of a symbol as the default in this manner; otherwise ++you would effectively have multiple definitions of the same symbol. ++ ++If you wish to bind a reference to a specific version of the symbol ++within the shared library, you can use the aliases of convenience ++(i.e., @samp{old_foo}), or you can use the @samp{.symver} directive to ++specifically bind to an external version of the function in question. ++ ++You can also specify the language in the version script: ++ ++@smallexample ++VERSION extern "lang" @{ version-script-commands @} ++@end smallexample ++ ++The supported @samp{lang}s are @samp{C}, @samp{C++}, and @samp{Java}. ++The linker will iterate over the list of symbols at the link time and ++demangle them according to @samp{lang} before matching them to the ++patterns specified in @samp{version-script-commands}. The default ++@samp{lang} is @samp{C}. ++ ++Demangled names may contains spaces and other special characters. As ++described above, you can use a glob pattern to match demangled names, ++or you can use a double-quoted string to match the string exactly. In ++the latter case, be aware that minor differences (such as differing ++whitespace) between the version script and the demangler output will ++cause a mismatch. As the exact string generated by the demangler ++might change in the future, even if the mangled name does not, you ++should check that all of your version directives are behaving as you ++expect when you upgrade. ++ ++@node Expressions ++@section Expressions in Linker Scripts ++@cindex expressions ++@cindex arithmetic ++The syntax for expressions in the linker script language is identical to ++that of C expressions, except that whitespace is required in some ++places to resolve syntactic ambiguities. All expressions are ++evaluated as integers. All expressions are evaluated in the same ++size, which is 32 bits if both the host and target are 32 bits, and is ++otherwise 64 bits. ++ ++You can use and set symbol values in expressions. ++ ++The linker defines several special purpose builtin functions for use in ++expressions. ++ ++@menu ++* Constants:: Constants ++* Symbolic Constants:: Symbolic constants ++* Symbols:: Symbol Names ++* Orphan Sections:: Orphan Sections ++* Location Counter:: The Location Counter ++* Operators:: Operators ++* Evaluation:: Evaluation ++* Expression Section:: The Section of an Expression ++* Builtin Functions:: Builtin Functions ++@end menu ++ ++@node Constants ++@subsection Constants ++@cindex integer notation ++@cindex constants in linker scripts ++All constants are integers. ++ ++As in C, the linker considers an integer beginning with @samp{0} to be ++octal, and an integer beginning with @samp{0x} or @samp{0X} to be ++hexadecimal. Alternatively the linker accepts suffixes of @samp{h} or ++@samp{H} for hexadecimal, @samp{o} or @samp{O} for octal, @samp{b} or ++@samp{B} for binary and @samp{d} or @samp{D} for decimal. Any integer ++value without a prefix or a suffix is considered to be decimal. ++ ++@cindex scaled integers ++@cindex K and M integer suffixes ++@cindex M and K integer suffixes ++@cindex suffixes for integers ++@cindex integer suffixes ++In addition, you can use the suffixes @code{K} and @code{M} to scale a ++constant by ++@c TEXI2ROFF-KILL ++@ifnottex ++@c END TEXI2ROFF-KILL ++@code{1024} or @code{1024*1024} ++@c TEXI2ROFF-KILL ++@end ifnottex ++@tex ++${\rm 1024}$ or ${\rm 1024}^2$ ++@end tex ++@c END TEXI2ROFF-KILL ++respectively. For example, the following ++all refer to the same quantity: ++ ++@smallexample ++_fourk_1 = 4K; ++_fourk_2 = 4096; ++_fourk_3 = 0x1000; ++_fourk_4 = 10000o; ++@end smallexample ++ ++Note - the @code{K} and @code{M} suffixes cannot be used in ++conjunction with the base suffixes mentioned above. ++ ++@node Symbolic Constants ++@subsection Symbolic Constants ++@cindex symbolic constants ++@kindex CONSTANT ++It is possible to refer to target-specific constants via the use of ++the @code{CONSTANT(@var{name})} operator, where @var{name} is one of: ++ ++@table @code ++@item MAXPAGESIZE ++@kindex MAXPAGESIZE ++The target's maximum page size. ++ ++@item COMMONPAGESIZE ++@kindex COMMONPAGESIZE ++The target's default page size. ++@end table ++ ++So for example: ++ ++@smallexample ++ .text ALIGN (CONSTANT (MAXPAGESIZE)) : @{ *(.text) @} ++@end smallexample ++ ++will create a text section aligned to the largest page boundary ++supported by the target. ++ ++@node Symbols ++@subsection Symbol Names ++@cindex symbol names ++@cindex names ++@cindex quoted symbol names ++@kindex " ++Unless quoted, symbol names start with a letter, underscore, or period ++and may include letters, digits, underscores, periods, and hyphens. ++Unquoted symbol names must not conflict with any keywords. You can ++specify a symbol which contains odd characters or has the same name as a ++keyword by surrounding the symbol name in double quotes: ++@smallexample ++"SECTION" = 9; ++"with a space" = "also with a space" + 10; ++@end smallexample ++ ++Since symbols can contain many non-alphabetic characters, it is safest ++to delimit symbols with spaces. For example, @samp{A-B} is one symbol, ++whereas @samp{A - B} is an expression involving subtraction. ++ ++@node Orphan Sections ++@subsection Orphan Sections ++@cindex orphan ++Orphan sections are sections present in the input files which ++are not explicitly placed into the output file by the linker ++script. The linker will still copy these sections into the ++output file by either finding, or creating a suitable output section ++in which to place the orphaned input section. ++ ++If the name of an orphaned input section exactly matches the name of ++an existing output section, then the orphaned input section will be ++placed at the end of that output section. ++ ++If there is no output section with a matching name then new output ++sections will be created. Each new output section will have the same ++name as the orphan section placed within it. If there are multiple ++orphan sections with the same name, these will all be combined into ++one new output section. ++ ++If new output sections are created to hold orphaned input sections, ++then the linker must decide where to place these new output sections ++in relation to existing output sections. On most modern targets, the ++linker attempts to place orphan sections after sections of the same ++attribute, such as code vs data, loadable vs non-loadable, etc. If no ++sections with matching attributes are found, or your target lacks this ++support, the orphan section is placed at the end of the file. ++ ++The command-line options @samp{--orphan-handling} and @samp{--unique} ++(@pxref{Options,,Command-line Options}) can be used to control which ++output sections an orphan is placed in. ++ ++@node Location Counter ++@subsection The Location Counter ++@kindex . ++@cindex dot ++@cindex location counter ++@cindex current output location ++The special linker variable @dfn{dot} @samp{.} always contains the ++current output location counter. Since the @code{.} always refers to a ++location in an output section, it may only appear in an expression ++within a @code{SECTIONS} command. The @code{.} symbol may appear ++anywhere that an ordinary symbol is allowed in an expression. ++ ++@cindex holes ++Assigning a value to @code{.} will cause the location counter to be ++moved. This may be used to create holes in the output section. The ++location counter may not be moved backwards inside an output section, ++and may not be moved backwards outside of an output section if so ++doing creates areas with overlapping LMAs. ++ ++@smallexample ++SECTIONS ++@{ ++ output : ++ @{ ++ file1(.text) ++ . = . + 1000; ++ file2(.text) ++ . += 1000; ++ file3(.text) ++ @} = 0x12345678; ++@} ++@end smallexample ++@noindent ++In the previous example, the @samp{.text} section from @file{file1} is ++located at the beginning of the output section @samp{output}. It is ++followed by a 1000 byte gap. Then the @samp{.text} section from ++@file{file2} appears, also with a 1000 byte gap following before the ++@samp{.text} section from @file{file3}. The notation @samp{= 0x12345678} ++specifies what data to write in the gaps (@pxref{Output Section Fill}). ++ ++@cindex dot inside sections ++Note: @code{.} actually refers to the byte offset from the start of the ++current containing object. Normally this is the @code{SECTIONS} ++statement, whose start address is 0, hence @code{.} can be used as an ++absolute address. If @code{.} is used inside a section description ++however, it refers to the byte offset from the start of that section, ++not an absolute address. Thus in a script like this: ++ ++@smallexample ++SECTIONS ++@{ ++ . = 0x100 ++ .text: @{ ++ *(.text) ++ . = 0x200 ++ @} ++ . = 0x500 ++ .data: @{ ++ *(.data) ++ . += 0x600 ++ @} ++@} ++@end smallexample ++ ++The @samp{.text} section will be assigned a starting address of 0x100 ++and a size of exactly 0x200 bytes, even if there is not enough data in ++the @samp{.text} input sections to fill this area. (If there is too ++much data, an error will be produced because this would be an attempt to ++move @code{.} backwards). The @samp{.data} section will start at 0x500 ++and it will have an extra 0x600 bytes worth of space after the end of ++the values from the @samp{.data} input sections and before the end of ++the @samp{.data} output section itself. ++ ++@cindex dot outside sections ++Setting symbols to the value of the location counter outside of an ++output section statement can result in unexpected values if the linker ++needs to place orphan sections. For example, given the following: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ start_of_data = . ; ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++If the linker needs to place some input section, e.g. @code{.rodata}, ++not mentioned in the script, it might choose to place that section ++between @code{.text} and @code{.data}. You might think the linker ++should place @code{.rodata} on the blank line in the above script, but ++blank lines are of no particular significance to the linker. As well, ++the linker doesn't associate the above symbol names with their ++sections. Instead, it assumes that all assignments or other ++statements belong to the previous output section, except for the ++special case of an assignment to @code{.}. I.e., the linker will ++place the orphan @code{.rodata} section as if the script was written ++as follows: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ start_of_data = . ; ++ .rodata: @{ *(.rodata) @} ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++This may or may not be the script author's intention for the value of ++@code{start_of_data}. One way to influence the orphan section ++placement is to assign the location counter to itself, as the linker ++assumes that an assignment to @code{.} is setting the start address of ++a following output section and thus should be grouped with that ++section. So you could write: ++ ++@smallexample ++SECTIONS ++@{ ++ start_of_text = . ; ++ .text: @{ *(.text) @} ++ end_of_text = . ; ++ ++ . = . ; ++ start_of_data = . ; ++ .data: @{ *(.data) @} ++ end_of_data = . ; ++@} ++@end smallexample ++ ++Now, the orphan @code{.rodata} section will be placed between ++@code{end_of_text} and @code{start_of_data}. ++ ++@need 2000 ++@node Operators ++@subsection Operators ++@cindex operators for arithmetic ++@cindex arithmetic operators ++@cindex precedence in expressions ++The linker recognizes the standard C set of arithmetic operators, with ++the standard bindings and precedence levels: ++@c TEXI2ROFF-KILL ++@ifnottex ++@c END TEXI2ROFF-KILL ++@smallexample ++precedence associativity Operators Notes ++(highest) ++1 left ! - ~ (1) ++2 left * / % ++3 left + - ++4 left >> << ++5 left == != > < <= >= ++6 left & ++7 left | ++8 left && ++9 left || ++10 right ? : ++11 right &= += -= *= /= (2) ++(lowest) ++@end smallexample ++Notes: ++(1) Prefix operators ++(2) @xref{Assignments}. ++@c TEXI2ROFF-KILL ++@end ifnottex ++@tex ++\vskip \baselineskip ++%"lispnarrowing" is the extra indent used generally for smallexample ++\hskip\lispnarrowing\vbox{\offinterlineskip ++\hrule ++\halign ++{\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ #\ \hfil&\vrule#&\strut\hfil\ {\tt #}\ \hfil&\vrule#\cr ++height2pt&\omit&&\omit&&\omit&\cr ++&Precedence&& Associativity &&{\rm Operators}&\cr ++height2pt&\omit&&\omit&&\omit&\cr ++\noalign{\hrule} ++height2pt&\omit&&\omit&&\omit&\cr ++&highest&&&&&\cr ++% '176 is tilde, '~' in tt font ++&1&&left&&\qquad- \char'176\ !\qquad\dag&\cr ++&2&&left&&* / \%&\cr ++&3&&left&&+ -&\cr ++&4&&left&&>> <<&\cr ++&5&&left&&== != > < <= >=&\cr ++&6&&left&&\&&\cr ++&7&&left&&|&\cr ++&8&&left&&{\&\&}&\cr ++&9&&left&&||&\cr ++&10&&right&&? :&\cr ++&11&&right&&\qquad\&= += -= *= /=\qquad\ddag&\cr ++&lowest&&&&&\cr ++height2pt&\omit&&\omit&&\omit&\cr} ++\hrule} ++@end tex ++@iftex ++{ ++@obeylines@parskip=0pt@parindent=0pt ++@dag@quad Prefix operators. ++@ddag@quad @xref{Assignments}. ++} ++@end iftex ++@c END TEXI2ROFF-KILL ++ ++@node Evaluation ++@subsection Evaluation ++@cindex lazy evaluation ++@cindex expression evaluation order ++The linker evaluates expressions lazily. It only computes the value of ++an expression when absolutely necessary. ++ ++The linker needs some information, such as the value of the start ++address of the first section, and the origins and lengths of memory ++regions, in order to do any linking at all. These values are computed ++as soon as possible when the linker reads in the linker script. ++ ++However, other values (such as symbol values) are not known or needed ++until after storage allocation. Such values are evaluated later, when ++other information (such as the sizes of output sections) is available ++for use in the symbol assignment expression. ++ ++The sizes of sections cannot be known until after allocation, so ++assignments dependent upon these are not performed until after ++allocation. ++ ++Some expressions, such as those depending upon the location counter ++@samp{.}, must be evaluated during section allocation. ++ ++If the result of an expression is required, but the value is not ++available, then an error results. For example, a script like the ++following ++@smallexample ++@group ++SECTIONS ++ @{ ++ .text 9+this_isnt_constant : ++ @{ *(.text) @} ++ @} ++@end group ++@end smallexample ++@noindent ++will cause the error message @samp{non constant expression for initial ++address}. ++ ++@node Expression Section ++@subsection The Section of an Expression ++@cindex expression sections ++@cindex absolute expressions ++@cindex relative expressions ++@cindex absolute and relocatable symbols ++@cindex relocatable and absolute symbols ++@cindex symbols, relocatable and absolute ++Addresses and symbols may be section relative, or absolute. A section ++relative symbol is relocatable. If you request relocatable output ++using the @samp{-r} option, a further link operation may change the ++value of a section relative symbol. On the other hand, an absolute ++symbol will retain the same value throughout any further link ++operations. ++ ++Some terms in linker expressions are addresses. This is true of ++section relative symbols and for builtin functions that return an ++address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and ++@code{SEGMENT_START}. Other terms are simply numbers, or are builtin ++functions that return a non-address value, such as @code{LENGTH}. ++One complication is that unless you set @code{LD_FEATURE ("SANE_EXPR")} ++(@pxref{Miscellaneous Commands}), numbers and absolute symbols are treated ++differently depending on their location, for compatibility with older ++versions of @code{ld}. Expressions appearing outside an output ++section definition treat all numbers as absolute addresses. ++Expressions appearing inside an output section definition treat ++absolute symbols as numbers. If @code{LD_FEATURE ("SANE_EXPR")} is ++given, then absolute symbols and numbers are simply treated as numbers ++everywhere. ++ ++In the following simple example, ++ ++@smallexample ++@group ++SECTIONS ++ @{ ++ . = 0x100; ++ __executable_start = 0x100; ++ .data : ++ @{ ++ . = 0x10; ++ __data_start = 0x10; ++ *(.data) ++ @} ++ @dots{} ++ @} ++@end group ++@end smallexample ++ ++both @code{.} and @code{__executable_start} are set to the absolute ++address 0x100 in the first two assignments, then both @code{.} and ++@code{__data_start} are set to 0x10 relative to the @code{.data} ++section in the second two assignments. ++ ++For expressions involving numbers, relative addresses and absolute ++addresses, ld follows these rules to evaluate terms: ++ ++@itemize @bullet ++@item ++Unary operations on an absolute address or number, and binary ++operations on two absolute addresses or two numbers, or between one ++absolute address and a number, apply the operator to the value(s). ++@item ++Unary operations on a relative address, and binary operations on two ++relative addresses in the same section or between one relative address ++and a number, apply the operator to the offset part of the address(es). ++@item ++Other binary operations, that is, between two relative addresses not ++in the same section, or between a relative address and an absolute ++address, first convert any non-absolute term to an absolute address ++before applying the operator. ++@end itemize ++ ++The result section of each sub-expression is as follows: ++ ++@itemize @bullet ++@item ++An operation involving only numbers results in a number. ++@item ++The result of comparisons, @samp{&&} and @samp{||} is also a number. ++@item ++The result of other binary arithmetic and logical operations on two ++relative addresses in the same section or two absolute addresses ++(after above conversions) is also a number when ++@code{LD_FEATURE ("SANE_EXPR")} or inside an output section definition ++but an absolute address otherwise. ++@item ++The result of other operations on relative addresses or one ++relative address and a number, is a relative address in the same ++section as the relative operand(s). ++@item ++The result of other operations on absolute addresses (after above ++conversions) is an absolute address. ++@end itemize ++ ++You can use the builtin function @code{ABSOLUTE} to force an expression ++to be absolute when it would otherwise be relative. For example, to ++create an absolute symbol set to the address of the end of the output ++section @samp{.data}: ++@smallexample ++SECTIONS ++ @{ ++ .data : @{ *(.data) _edata = ABSOLUTE(.); @} ++ @} ++@end smallexample ++@noindent ++If @samp{ABSOLUTE} were not used, @samp{_edata} would be relative to the ++@samp{.data} section. ++ ++Using @code{LOADADDR} also forces an expression absolute, since this ++particular builtin function returns an absolute address. ++ ++@node Builtin Functions ++@subsection Builtin Functions ++@cindex functions in expressions ++The linker script language includes a number of builtin functions for ++use in linker script expressions. ++ ++@table @code ++@item ABSOLUTE(@var{exp}) ++@kindex ABSOLUTE(@var{exp}) ++@cindex expression, absolute ++Return the absolute (non-relocatable, as opposed to non-negative) value ++of the expression @var{exp}. Primarily useful to assign an absolute ++value to a symbol within a section definition, where symbol values are ++normally section relative. @xref{Expression Section}. ++ ++@item ADDR(@var{section}) ++@kindex ADDR(@var{section}) ++@cindex section address in expression ++Return the address (VMA) of the named @var{section}. Your ++script must previously have defined the location of that section. In ++the following example, @code{start_of_output_1}, @code{symbol_1} and ++@code{symbol_2} are assigned equivalent values, except that ++@code{symbol_1} will be relative to the @code{.output1} section while ++the other two will be absolute: ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .output1 : ++ @{ ++ start_of_output_1 = ABSOLUTE(.); ++ @dots{} ++ @} ++ .output : ++ @{ ++ symbol_1 = ADDR(.output1); ++ symbol_2 = start_of_output_1; ++ @} ++@dots{} @} ++@end group ++@end smallexample ++ ++@item ALIGN(@var{align}) ++@itemx ALIGN(@var{exp},@var{align}) ++@kindex ALIGN(@var{align}) ++@kindex ALIGN(@var{exp},@var{align}) ++@cindex round up location counter ++@cindex align location counter ++@cindex round up expression ++@cindex align expression ++Return the location counter (@code{.}) or arbitrary expression aligned ++to the next @var{align} boundary. The single operand @code{ALIGN} ++doesn't change the value of the location counter---it just does ++arithmetic on it. The two operand @code{ALIGN} allows an arbitrary ++expression to be aligned upwards (@code{ALIGN(@var{align})} is ++equivalent to @code{ALIGN(ABSOLUTE(.), @var{align})}). ++ ++Here is an example which aligns the output @code{.data} section to the ++next @code{0x2000} byte boundary after the preceding section and sets a ++variable within the section to the next @code{0x8000} boundary after the ++input sections: ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .data ALIGN(0x2000): @{ ++ *(.data) ++ variable = ALIGN(0x8000); ++ @} ++@dots{} @} ++@end group ++@end smallexample ++@noindent ++The first use of @code{ALIGN} in this example specifies the location of ++a section because it is used as the optional @var{address} attribute of ++a section definition (@pxref{Output Section Address}). The second use ++of @code{ALIGN} is used to defines the value of a symbol. ++ ++The builtin function @code{NEXT} is closely related to @code{ALIGN}. ++ ++@item ALIGNOF(@var{section}) ++@kindex ALIGNOF(@var{section}) ++@cindex section alignment ++Return the alignment in bytes of the named @var{section}, if that section has ++been allocated. If the section has not been allocated when this is ++evaluated, the linker will report an error. In the following example, ++the alignment of the @code{.output} section is stored as the first ++value in that section. ++@smallexample ++@group ++SECTIONS@{ @dots{} ++ .output @{ ++ LONG (ALIGNOF (.output)) ++ @dots{} ++ @} ++@dots{} @} ++@end group ++@end smallexample ++ ++@item BLOCK(@var{exp}) ++@kindex BLOCK(@var{exp}) ++This is a synonym for @code{ALIGN}, for compatibility with older linker ++scripts. It is most often seen when setting the address of an output ++section. ++ ++@item DATA_SEGMENT_ALIGN(@var{maxpagesize}, @var{commonpagesize}) ++@kindex DATA_SEGMENT_ALIGN(@var{maxpagesize}, @var{commonpagesize}) ++This is equivalent to either ++@smallexample ++(ALIGN(@var{maxpagesize}) + (. & (@var{maxpagesize} - 1))) ++@end smallexample ++or ++@smallexample ++(ALIGN(@var{maxpagesize}) ++ + ((. + @var{commonpagesize} - 1) & (@var{maxpagesize} - @var{commonpagesize}))) ++@end smallexample ++@noindent ++depending on whether the latter uses fewer @var{commonpagesize} sized pages ++for the data segment (area between the result of this expression and ++@code{DATA_SEGMENT_END}) than the former or not. ++If the latter form is used, it means @var{commonpagesize} bytes of runtime ++memory will be saved at the expense of up to @var{commonpagesize} wasted ++bytes in the on-disk file. ++ ++This expression can only be used directly in @code{SECTIONS} commands, not in ++any output section descriptions and only once in the linker script. ++@var{commonpagesize} should be less or equal to @var{maxpagesize} and should ++be the system page size the object wants to be optimized for while still ++running on system page sizes up to @var{maxpagesize}. Note however ++that @samp{-z relro} protection will not be effective if the system ++page size is larger than @var{commonpagesize}. ++ ++@noindent ++Example: ++@smallexample ++ . = DATA_SEGMENT_ALIGN(0x10000, 0x2000); ++@end smallexample ++ ++@item DATA_SEGMENT_END(@var{exp}) ++@kindex DATA_SEGMENT_END(@var{exp}) ++This defines the end of data segment for @code{DATA_SEGMENT_ALIGN} ++evaluation purposes. ++ ++@smallexample ++ . = DATA_SEGMENT_END(.); ++@end smallexample ++ ++@item DATA_SEGMENT_RELRO_END(@var{offset}, @var{exp}) ++@kindex DATA_SEGMENT_RELRO_END(@var{offset}, @var{exp}) ++This defines the end of the @code{PT_GNU_RELRO} segment when ++@samp{-z relro} option is used. ++When @samp{-z relro} option is not present, @code{DATA_SEGMENT_RELRO_END} ++does nothing, otherwise @code{DATA_SEGMENT_ALIGN} is padded so that ++@var{exp} + @var{offset} is aligned to the @var{commonpagesize} ++argument given to @code{DATA_SEGMENT_ALIGN}. If present in the linker ++script, it must be placed between @code{DATA_SEGMENT_ALIGN} and ++@code{DATA_SEGMENT_END}. Evaluates to the second argument plus any ++padding needed at the end of the @code{PT_GNU_RELRO} segment due to ++section alignment. ++ ++@smallexample ++ . = DATA_SEGMENT_RELRO_END(24, .); ++@end smallexample ++ ++@item DEFINED(@var{symbol}) ++@kindex DEFINED(@var{symbol}) ++@cindex symbol defaults ++Return 1 if @var{symbol} is in the linker global symbol table and is ++defined before the statement using DEFINED in the script, otherwise ++return 0. You can use this function to provide ++default values for symbols. For example, the following script fragment ++shows how to set a global symbol @samp{begin} to the first location in ++the @samp{.text} section---but if a symbol called @samp{begin} already ++existed, its value is preserved: ++ ++@smallexample ++@group ++SECTIONS @{ @dots{} ++ .text : @{ ++ begin = DEFINED(begin) ? begin : . ; ++ @dots{} ++ @} ++ @dots{} ++@} ++@end group ++@end smallexample ++ ++@item LENGTH(@var{memory}) ++@kindex LENGTH(@var{memory}) ++Return the length of the memory region named @var{memory}. ++ ++@item LOADADDR(@var{section}) ++@kindex LOADADDR(@var{section}) ++@cindex section load address in expression ++Return the absolute LMA of the named @var{section}. (@pxref{Output ++Section LMA}). ++ ++@item LOG2CEIL(@var{exp}) ++@kindex LOG2CEIL(@var{exp}) ++Return the binary logarithm of @var{exp} rounded towards infinity. ++@code{LOG2CEIL(0)} returns 0. ++ ++@kindex MAX ++@item MAX(@var{exp1}, @var{exp2}) ++Returns the maximum of @var{exp1} and @var{exp2}. ++ ++@kindex MIN ++@item MIN(@var{exp1}, @var{exp2}) ++Returns the minimum of @var{exp1} and @var{exp2}. ++ ++@item NEXT(@var{exp}) ++@kindex NEXT(@var{exp}) ++@cindex unallocated address, next ++Return the next unallocated address that is a multiple of @var{exp}. ++This function is closely related to @code{ALIGN(@var{exp})}; unless you ++use the @code{MEMORY} command to define discontinuous memory for the ++output file, the two functions are equivalent. ++ ++@item ORIGIN(@var{memory}) ++@kindex ORIGIN(@var{memory}) ++Return the origin of the memory region named @var{memory}. ++ ++@item SEGMENT_START(@var{segment}, @var{default}) ++@kindex SEGMENT_START(@var{segment}, @var{default}) ++Return the base address of the named @var{segment}. If an explicit ++value has already been given for this segment (with a command-line ++@samp{-T} option) then that value will be returned otherwise the value ++will be @var{default}. At present, the @samp{-T} command-line option ++can only be used to set the base address for the ``text'', ``data'', and ++``bss'' sections, but you can use @code{SEGMENT_START} with any segment ++name. ++ ++@item SIZEOF(@var{section}) ++@kindex SIZEOF(@var{section}) ++@cindex section size ++Return the size in bytes of the named @var{section}, if that section has ++been allocated. If the section has not been allocated when this is ++evaluated, the linker will report an error. In the following example, ++@code{symbol_1} and @code{symbol_2} are assigned identical values: ++@smallexample ++@group ++SECTIONS@{ @dots{} ++ .output @{ ++ .start = . ; ++ @dots{} ++ .end = . ; ++ @} ++ symbol_1 = .end - .start ; ++ symbol_2 = SIZEOF(.output); ++@dots{} @} ++@end group ++@end smallexample ++ ++@item SIZEOF_HEADERS ++@kindex SIZEOF_HEADERS ++@cindex header size ++Return the size in bytes of the output file's headers. This is ++information which appears at the start of the output file. You can use ++this number when setting the start address of the first section, if you ++choose, to facilitate paging. ++ ++@cindex not enough room for program headers ++@cindex program headers, not enough room ++When producing an ELF output file, if the linker script uses the ++@code{SIZEOF_HEADERS} builtin function, the linker must compute the ++number of program headers before it has determined all the section ++addresses and sizes. If the linker later discovers that it needs ++additional program headers, it will report an error @samp{not enough ++room for program headers}. To avoid this error, you must avoid using ++the @code{SIZEOF_HEADERS} function, or you must rework your linker ++script to avoid forcing the linker to use additional program headers, or ++you must define the program headers yourself using the @code{PHDRS} ++command (@pxref{PHDRS}). ++@end table ++ ++@node Implicit Linker Scripts ++@section Implicit Linker Scripts ++@cindex implicit linker scripts ++If you specify a linker input file which the linker can not recognize as ++an object file or an archive file, it will try to read the file as a ++linker script. If the file can not be parsed as a linker script, the ++linker will report an error. ++ ++An implicit linker script will not replace the default linker script. ++ ++Typically an implicit linker script would contain only symbol ++assignments, or the @code{INPUT}, @code{GROUP}, or @code{VERSION} ++commands. ++ ++Any input files read because of an implicit linker script will be read ++at the position in the command line where the implicit linker script was ++read. This can affect archive searching. ++ ++@node Plugins ++@chapter Linker Plugins ++ ++@cindex plugins ++@cindex linker plugins ++The linker can use dynamically loaded plugins to modify its behavior. ++For example, the link-time optimization feature that some compilers ++support is implemented with a linker plugin. ++ ++Currently there is only one plugin shipped by default, but more may ++be added here later. ++ ++Plugins are enabled via the use of the @option{-plugin @var{name}} ++command line option. @xref{Options}. ++ ++@menu ++* libdep Plugin:: Static Library Dependencies Plugin ++@end menu ++ ++@node libdep Plugin ++@section Static Library Dependencies Plugin ++@cindex static library dependencies ++Originally, static libraries were contained in an archive file consisting ++just of a collection of relocatable object files. Later they evolved to ++optionally include a symbol table, to assist in finding the needed objects ++within a library. There their evolution ended, and dynamic libraries ++rose to ascendance. ++ ++One useful feature of dynamic libraries was that, more than just collecting ++multiple objects into a single file, they also included a list of their ++dependencies, such that one could specify just the name of a single dynamic ++library at link time, and all of its dependencies would be implicitly ++referenced as well. But static libraries lacked this feature, so if a ++link invocation was switched from using dynamic libraries to static ++libraries, the link command would usually fail unless it was rewritten to ++explicitly list the dependencies of the static library. ++ ++The GNU @command{ar} utility now supports a @option{--record-libdeps} option ++to embed dependency lists into static libraries as well, and the @file{libdep} ++plugin may be used to read this dependency information at link time. The ++dependency information is stored as a single string, carrying @option{-l} ++and @option{-L} arguments as they would normally appear in a linker ++command line. As such, the information can be written with any text ++utility and stored into any archive, even if GNU @command{ar} is not ++being used to create the archive. The information is stored in an ++archive member named @samp{__.LIBDEP}. ++ ++For example, given a library @file{libssl.a} that depends on another ++library @file{libcrypto.a} which may be found in @file{/usr/local/lib}, ++the @samp{__.LIBDEP} member of @file{libssl.a} would contain ++ ++@smallexample ++-L/usr/local/lib -lcrypto ++@end smallexample ++ ++@ifset GENERIC ++@node Machine Dependent ++@chapter Machine Dependent Features ++ ++@cindex machine dependencies ++@command{ld} has additional features on some platforms; the following ++sections describe them. Machines where @command{ld} has no additional ++functionality are not listed. ++ ++@menu ++@ifset H8300 ++* H8/300:: @command{ld} and the H8/300 ++@end ifset ++@ifset M68HC11 ++* M68HC11/68HC12:: @code{ld} and the Motorola 68HC11 and 68HC12 families ++@end ifset ++@ifset ARM ++* ARM:: @command{ld} and the ARM family ++@end ifset ++@ifset HPPA ++* HPPA ELF32:: @command{ld} and HPPA 32-bit ELF ++@end ifset ++@ifset M68K ++* M68K:: @command{ld} and the Motorola 68K family ++@end ifset ++@ifset MIPS ++* MIPS:: @command{ld} and the MIPS family ++@end ifset ++@ifset MMIX ++* MMIX:: @command{ld} and MMIX ++@end ifset ++@ifset MSP430 ++* MSP430:: @command{ld} and MSP430 ++@end ifset ++@ifset NDS32 ++* NDS32:: @command{ld} and NDS32 ++@end ifset ++@ifset NIOSII ++* Nios II:: @command{ld} and the Altera Nios II ++@end ifset ++@ifset POWERPC ++* PowerPC ELF32:: @command{ld} and PowerPC 32-bit ELF Support ++@end ifset ++@ifset POWERPC64 ++* PowerPC64 ELF64:: @command{ld} and PowerPC64 64-bit ELF Support ++@end ifset ++@ifset S/390 ++* S/390 ELF:: @command{ld} and S/390 ELF Support ++@end ifset ++@ifset SPU ++* SPU ELF:: @command{ld} and SPU ELF Support ++@end ifset ++@ifset TICOFF ++* TI COFF:: @command{ld} and TI COFF ++@end ifset ++@ifset WIN32 ++* WIN32:: @command{ld} and WIN32 (cygwin/mingw) ++@end ifset ++@ifset XTENSA ++* Xtensa:: @command{ld} and Xtensa Processors ++@end ifset ++@end menu ++@end ifset ++ ++@ifset H8300 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node H8/300 ++@section @command{ld} and the H8/300 ++ ++@cindex H8/300 support ++For the H8/300, @command{ld} can perform these global optimizations when ++you specify the @samp{--relax} command-line option. ++ ++@table @emph ++@cindex relaxing on H8/300 ++@item relaxing address modes ++@command{ld} finds all @code{jsr} and @code{jmp} instructions whose ++targets are within eight bits, and turns them into eight-bit ++program-counter relative @code{bsr} and @code{bra} instructions, ++respectively. ++ ++@cindex synthesizing on H8/300 ++@item synthesizing instructions ++@c FIXME: specifically mov.b, or any mov instructions really? -> mov.b only, at least on H8, H8H, H8S ++@command{ld} finds all @code{mov.b} instructions which use the ++sixteen-bit absolute address form, but refer to the top ++page of memory, and changes them to use the eight-bit address form. ++(That is: the linker turns @samp{mov.b @code{@@}@var{aa}:16} into ++@samp{mov.b @code{@@}@var{aa}:8} whenever the address @var{aa} is in the ++top page of memory). ++ ++@command{ld} finds all @code{mov} instructions which use the register ++indirect with 32-bit displacement addressing mode, but use a small ++displacement inside 16-bit displacement range, and changes them to use ++the 16-bit displacement form. (That is: the linker turns @samp{mov.b ++@code{@@}@var{d}:32,ERx} into @samp{mov.b @code{@@}@var{d}:16,ERx} ++whenever the displacement @var{d} is in the 16 bit signed integer ++range. Only implemented in ELF-format ld). ++ ++@item bit manipulation instructions ++@command{ld} finds all bit manipulation instructions like @code{band, bclr, ++biand, bild, bior, bist, bixor, bld, bnot, bor, bset, bst, btst, bxor} ++which use 32 bit and 16 bit absolute address form, but refer to the top ++page of memory, and changes them to use the 8 bit address form. ++(That is: the linker turns @samp{bset #xx:3,@code{@@}@var{aa}:32} into ++@samp{bset #xx:3,@code{@@}@var{aa}:8} whenever the address @var{aa} is in ++the top page of memory). ++ ++@item system control instructions ++@command{ld} finds all @code{ldc.w, stc.w} instructions which use the ++32 bit absolute address form, but refer to the top page of memory, and ++changes them to use 16 bit address form. ++(That is: the linker turns @samp{ldc.w @code{@@}@var{aa}:32,ccr} into ++@samp{ldc.w @code{@@}@var{aa}:16,ccr} whenever the address @var{aa} is in ++the top page of memory). ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifclear GENERIC ++@ifset Renesas ++@c This stuff is pointless to say unless you're especially concerned ++@c with Renesas chips; don't enable it for generic case, please. ++@node Renesas ++@chapter @command{ld} and Other Renesas Chips ++ ++@command{ld} also supports the Renesas (formerly Hitachi) H8/300H, ++H8/500, and SH chips. No special features, commands, or command-line ++options are required for these chips. ++@end ifset ++@end ifclear ++ ++@ifset ARM ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@ifset M68HC11 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node M68HC11/68HC12 ++@section @command{ld} and the Motorola 68HC11 and 68HC12 families ++ ++@cindex M68HC11 and 68HC12 support ++ ++@subsection Linker Relaxation ++ ++For the Motorola 68HC11, @command{ld} can perform these global ++optimizations when you specify the @samp{--relax} command-line option. ++ ++@table @emph ++@cindex relaxing on M68HC11 ++@item relaxing address modes ++@command{ld} finds all @code{jsr} and @code{jmp} instructions whose ++targets are within eight bits, and turns them into eight-bit ++program-counter relative @code{bsr} and @code{bra} instructions, ++respectively. ++ ++@command{ld} also looks at all 16-bit extended addressing modes and ++transforms them in a direct addressing mode when the address is in ++page 0 (between 0 and 0x0ff). ++ ++@item relaxing gcc instruction group ++When @command{gcc} is called with @option{-mrelax}, it can emit group ++of instructions that the linker can optimize to use a 68HC11 direct ++addressing mode. These instructions consists of @code{bclr} or ++@code{bset} instructions. ++ ++@end table ++ ++@subsection Trampoline Generation ++ ++@cindex trampoline generation on M68HC11 ++@cindex trampoline generation on M68HC12 ++For 68HC11 and 68HC12, @command{ld} can generate trampoline code to ++call a far function using a normal @code{jsr} instruction. The linker ++will also change the relocation to some far function to use the ++trampoline address instead of the function address. This is typically the ++case when a pointer to a function is taken. The pointer will in fact ++point to the function trampoline. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@node ARM ++@section @command{ld} and the ARM family ++ ++@cindex ARM interworking support ++@kindex --support-old-code ++For the ARM, @command{ld} will generate code stubs to allow functions calls ++between ARM and Thumb code. These stubs only work with code that has ++been compiled and assembled with the @samp{-mthumb-interwork} command ++line option. If it is necessary to link with old ARM object files or ++libraries, which have not been compiled with the -mthumb-interwork ++option then the @samp{--support-old-code} command-line switch should be ++given to the linker. This will make it generate larger stub functions ++which will work with non-interworking aware ARM code. Note, however, ++the linker does not support generating stubs for function calls to ++non-interworking aware Thumb code. ++ ++@cindex thumb entry point ++@cindex entry point, thumb ++@kindex --thumb-entry=@var{entry} ++The @samp{--thumb-entry} switch is a duplicate of the generic ++@samp{--entry} switch, in that it sets the program's starting address. ++But it also sets the bottom bit of the address, so that it can be ++branched to using a BX instruction, and the program will start ++executing in Thumb mode straight away. ++ ++@cindex PE import table prefixing ++@kindex --use-nul-prefixed-import-tables ++The @samp{--use-nul-prefixed-import-tables} switch is specifying, that ++the import tables idata4 and idata5 have to be generated with a zero ++element prefix for import libraries. This is the old style to generate ++import tables. By default this option is turned off. ++ ++@cindex BE8 ++@kindex --be8 ++The @samp{--be8} switch instructs @command{ld} to generate BE8 format ++executables. This option is only valid when linking big-endian ++objects - ie ones which have been assembled with the @option{-EB} ++option. The resulting image will contain big-endian data and ++little-endian code. ++ ++@cindex TARGET1 ++@kindex --target1-rel ++@kindex --target1-abs ++The @samp{R_ARM_TARGET1} relocation is typically used for entries in the ++@samp{.init_array} section. It is interpreted as either @samp{R_ARM_REL32} ++or @samp{R_ARM_ABS32}, depending on the target. The @samp{--target1-rel} ++and @samp{--target1-abs} switches override the default. ++ ++@cindex TARGET2 ++@kindex --target2=@var{type} ++The @samp{--target2=type} switch overrides the default definition of the ++@samp{R_ARM_TARGET2} relocation. Valid values for @samp{type}, their ++meanings, and target defaults are as follows: ++@table @samp ++@item rel ++@samp{R_ARM_REL32} (arm*-*-elf, arm*-*-eabi) ++@item abs ++@samp{R_ARM_ABS32} ++@item got-rel ++@samp{R_ARM_GOT_PREL} (arm*-*-linux, arm*-*-*bsd) ++@end table ++ ++@cindex FIX_V4BX ++@kindex --fix-v4bx ++The @samp{R_ARM_V4BX} relocation (defined by the ARM AAELF ++specification) enables objects compiled for the ARMv4 architecture to be ++interworking-safe when linked with other objects compiled for ARMv4t, but ++also allows pure ARMv4 binaries to be built from the same ARMv4 objects. ++ ++In the latter case, the switch @option{--fix-v4bx} must be passed to the ++linker, which causes v4t @code{BX rM} instructions to be rewritten as ++@code{MOV PC,rM}, since v4 processors do not have a @code{BX} instruction. ++ ++In the former case, the switch should not be used, and @samp{R_ARM_V4BX} ++relocations are ignored. ++ ++@cindex FIX_V4BX_INTERWORKING ++@kindex --fix-v4bx-interworking ++Replace @code{BX rM} instructions identified by @samp{R_ARM_V4BX} ++relocations with a branch to the following veneer: ++ ++@smallexample ++TST rM, #1 ++MOVEQ PC, rM ++BX Rn ++@end smallexample ++ ++This allows generation of libraries/applications that work on ARMv4 cores ++and are still interworking safe. Note that the above veneer clobbers the ++condition flags, so may cause incorrect program behavior in rare cases. ++ ++@cindex USE_BLX ++@kindex --use-blx ++The @samp{--use-blx} switch enables the linker to use ARM/Thumb ++BLX instructions (available on ARMv5t and above) in various ++situations. Currently it is used to perform calls via the PLT from Thumb ++code using BLX rather than using BX and a mode-switching stub before ++each PLT entry. This should lead to such calls executing slightly faster. ++ ++@cindex VFP11_DENORM_FIX ++@kindex --vfp11-denorm-fix ++The @samp{--vfp11-denorm-fix} switch enables a link-time workaround for a ++bug in certain VFP11 coprocessor hardware, which sometimes allows ++instructions with denorm operands (which must be handled by support code) ++to have those operands overwritten by subsequent instructions before ++the support code can read the intended values. ++ ++The bug may be avoided in scalar mode if you allow at least one ++intervening instruction between a VFP11 instruction which uses a register ++and another instruction which writes to the same register, or at least two ++intervening instructions if vector mode is in use. The bug only affects ++full-compliance floating-point mode: you do not need this workaround if ++you are using "runfast" mode. Please contact ARM for further details. ++ ++If you know you are using buggy VFP11 hardware, you can ++enable this workaround by specifying the linker option ++@samp{--vfp-denorm-fix=scalar} if you are using the VFP11 scalar ++mode only, or @samp{--vfp-denorm-fix=vector} if you are using ++vector mode (the latter also works for scalar code). The default is ++@samp{--vfp-denorm-fix=none}. ++ ++If the workaround is enabled, instructions are scanned for ++potentially-troublesome sequences, and a veneer is created for each ++such sequence which may trigger the erratum. The veneer consists of the ++first instruction of the sequence and a branch back to the subsequent ++instruction. The original instruction is then replaced with a branch to ++the veneer. The extra cycles required to call and return from the veneer ++are sufficient to avoid the erratum in both the scalar and vector cases. ++ ++@cindex ARM1176 erratum workaround ++@kindex --fix-arm1176 ++@kindex --no-fix-arm1176 ++The @samp{--fix-arm1176} switch enables a link-time workaround for an erratum ++in certain ARM1176 processors. The workaround is enabled by default if you ++are targeting ARM v6 (excluding ARM v6T2) or earlier. It can be disabled ++unconditionally by specifying @samp{--no-fix-arm1176}. ++ ++Further information is available in the ``ARM1176JZ-S and ARM1176JZF-S ++Programmer Advice Notice'' available on the ARM documentation website at: ++http://infocenter.arm.com/. ++ ++@cindex STM32L4xx erratum workaround ++@kindex --fix-stm32l4xx-629360 ++ ++The @samp{--fix-stm32l4xx-629360} switch enables a link-time ++workaround for a bug in the bus matrix / memory controller for some of ++the STM32 Cortex-M4 based products (STM32L4xx). When accessing ++off-chip memory via the affected bus for bus reads of 9 words or more, ++the bus can generate corrupt data and/or abort. These are only ++core-initiated accesses (not DMA), and might affect any access: ++integer loads such as LDM, POP and floating-point loads such as VLDM, ++VPOP. Stores are not affected. ++ ++The bug can be avoided by splitting memory accesses into the ++necessary chunks to keep bus reads below 8 words. ++ ++The workaround is not enabled by default, this is equivalent to use ++@samp{--fix-stm32l4xx-629360=none}. If you know you are using buggy ++STM32L4xx hardware, you can enable the workaround by specifying the ++linker option @samp{--fix-stm32l4xx-629360}, or the equivalent ++@samp{--fix-stm32l4xx-629360=default}. ++ ++If the workaround is enabled, instructions are scanned for ++potentially-troublesome sequences, and a veneer is created for each ++such sequence which may trigger the erratum. The veneer consists in a ++replacement sequence emulating the behaviour of the original one and a ++branch back to the subsequent instruction. The original instruction is ++then replaced with a branch to the veneer. ++ ++The workaround does not always preserve the memory access order for ++the LDMDB instruction, when the instruction loads the PC. ++ ++The workaround is not able to handle problematic instructions when ++they are in the middle of an IT block, since a branch is not allowed ++there. In that case, the linker reports a warning and no replacement ++occurs. ++ ++The workaround is not able to replace problematic instructions with a ++PC-relative branch instruction if the @samp{.text} section is too ++large. In that case, when the branch that replaces the original code ++cannot be encoded, the linker reports a warning and no replacement ++occurs. ++ ++@cindex NO_ENUM_SIZE_WARNING ++@kindex --no-enum-size-warning ++The @option{--no-enum-size-warning} switch prevents the linker from ++warning when linking object files that specify incompatible EABI ++enumeration size attributes. For example, with this switch enabled, ++linking of an object file using 32-bit enumeration values with another ++using enumeration values fitted into the smallest possible space will ++not be diagnosed. ++ ++@cindex NO_WCHAR_SIZE_WARNING ++@kindex --no-wchar-size-warning ++The @option{--no-wchar-size-warning} switch prevents the linker from ++warning when linking object files that specify incompatible EABI ++@code{wchar_t} size attributes. For example, with this switch enabled, ++linking of an object file using 32-bit @code{wchar_t} values with another ++using 16-bit @code{wchar_t} values will not be diagnosed. ++ ++@cindex PIC_VENEER ++@kindex --pic-veneer ++The @samp{--pic-veneer} switch makes the linker use PIC sequences for ++ARM/Thumb interworking veneers, even if the rest of the binary ++is not PIC. This avoids problems on uClinux targets where ++@samp{--emit-relocs} is used to generate relocatable binaries. ++ ++@cindex STUB_GROUP_SIZE ++@kindex --stub-group-size=@var{N} ++The linker will automatically generate and insert small sequences of ++code into a linked ARM ELF executable whenever an attempt is made to ++perform a function call to a symbol that is too far away. The ++placement of these sequences of instructions - called stubs - is ++controlled by the command-line option @option{--stub-group-size=N}. ++The placement is important because a poor choice can create a need for ++duplicate stubs, increasing the code size. The linker will try to ++group stubs together in order to reduce interruptions to the flow of ++code, but it needs guidance as to how big these groups should be and ++where they should be placed. ++ ++The value of @samp{N}, the parameter to the ++@option{--stub-group-size=} option controls where the stub groups are ++placed. If it is negative then all stubs are placed after the first ++branch that needs them. If it is positive then the stubs can be ++placed either before or after the branches that need them. If the ++value of @samp{N} is 1 (either +1 or -1) then the linker will choose ++exactly where to place groups of stubs, using its built in heuristics. ++A value of @samp{N} greater than 1 (or smaller than -1) tells the ++linker that a single group of stubs can service at most @samp{N} bytes ++from the input sections. ++ ++The default, if @option{--stub-group-size=} is not specified, is ++@samp{N = +1}. ++ ++Farcalls stubs insertion is fully supported for the ARM-EABI target ++only, because it relies on object files properties not present ++otherwise. ++ ++@cindex Cortex-A8 erratum workaround ++@kindex --fix-cortex-a8 ++@kindex --no-fix-cortex-a8 ++The @samp{--fix-cortex-a8} switch enables a link-time workaround for an erratum in certain Cortex-A8 processors. The workaround is enabled by default if you are targeting the ARM v7-A architecture profile. It can be enabled otherwise by specifying @samp{--fix-cortex-a8}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a8}. ++ ++The erratum only affects Thumb-2 code. Please contact ARM for further details. ++ ++@cindex Cortex-A53 erratum 835769 workaround ++@kindex --fix-cortex-a53-835769 ++@kindex --no-fix-cortex-a53-835769 ++The @samp{--fix-cortex-a53-835769} switch enables a link-time workaround for erratum 835769 present on certain early revisions of Cortex-A53 processors. The workaround is disabled by default. It can be enabled by specifying @samp{--fix-cortex-a53-835769}, or disabled unconditionally by specifying @samp{--no-fix-cortex-a53-835769}. ++ ++Please contact ARM for further details. ++ ++@kindex --merge-exidx-entries ++@kindex --no-merge-exidx-entries ++@cindex Merging exidx entries ++The @samp{--no-merge-exidx-entries} switch disables the merging of adjacent exidx entries in debuginfo. ++ ++@kindex --long-plt ++@cindex 32-bit PLT entries ++The @samp{--long-plt} option enables the use of 16 byte PLT entries ++which support up to 4Gb of code. The default is to use 12 byte PLT ++entries which only support 512Mb of code. ++ ++@kindex --no-apply-dynamic-relocs ++@cindex AArch64 rela addend ++The @samp{--no-apply-dynamic-relocs} option makes AArch64 linker do not apply ++link-time values for dynamic relocations. ++ ++@cindex Placement of SG veneers ++All SG veneers are placed in the special output section @code{.gnu.sgstubs}. ++Its start address must be set, either with the command-line option ++@samp{--section-start} or in a linker script, to indicate where to place these ++veneers in memory. ++ ++@kindex --cmse-implib ++@cindex Secure gateway import library ++The @samp{--cmse-implib} option requests that the import libraries ++specified by the @samp{--out-implib} and @samp{--in-implib} options are ++secure gateway import libraries, suitable for linking a non-secure ++executable against secure code as per ARMv8-M Security Extensions. ++ ++@kindex --in-implib=@var{file} ++@cindex Input import library ++The @samp{--in-implib=file} specifies an input import library whose symbols ++must keep the same address in the executable being produced. A warning is ++given if no @samp{--out-implib} is given but new symbols have been introduced ++in the executable that should be listed in its import library. Otherwise, if ++@samp{--out-implib} is specified, the symbols are added to the output import ++library. A warning is also given if some symbols present in the input import ++library have disappeared from the executable. This option is only effective ++for Secure Gateway import libraries, ie. when @samp{--cmse-implib} is ++specified. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset HPPA ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node HPPA ELF32 ++@section @command{ld} and HPPA 32-bit ELF Support ++@cindex HPPA multiple sub-space stubs ++@kindex --multi-subspace ++When generating a shared library, @command{ld} will by default generate ++import stubs suitable for use with a single sub-space application. ++The @samp{--multi-subspace} switch causes @command{ld} to generate export ++stubs, and different (larger) import stubs suitable for use with ++multiple sub-spaces. ++ ++@cindex HPPA stub grouping ++@kindex --stub-group-size=@var{N} ++Long branch stubs and import/export stubs are placed by @command{ld} in ++stub sections located between groups of input sections. ++@samp{--stub-group-size} specifies the maximum size of a group of input ++sections handled by one stub section. Since branch offsets are signed, ++a stub section may serve two groups of input sections, one group before ++the stub section, and one group after it. However, when using ++conditional branches that require stubs, it may be better (for branch ++prediction) that stub sections only serve one group of input sections. ++A negative value for @samp{N} chooses this scheme, ensuring that ++branches to stubs always use a negative offset. Two special values of ++@samp{N} are recognized, @samp{1} and @samp{-1}. These both instruct ++@command{ld} to automatically size input section groups for the branch types ++detected, with the same behaviour regarding stub placement as other ++positive or negative values of @samp{N} respectively. ++ ++Note that @samp{--stub-group-size} does not split input sections. A ++single input section larger than the group size specified will of course ++create a larger group (of one section). If input sections are too ++large, it may not be possible for a branch to reach its stub. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset M68K ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node M68K ++@section @command{ld} and the Motorola 68K family ++ ++@cindex Motorola 68K GOT generation ++@kindex --got=@var{type} ++The @samp{--got=@var{type}} option lets you choose the GOT generation scheme. ++The choices are @samp{single}, @samp{negative}, @samp{multigot} and ++@samp{target}. When @samp{target} is selected the linker chooses ++the default GOT generation scheme for the current target. ++@samp{single} tells the linker to generate a single GOT with ++entries only at non-negative offsets. ++@samp{negative} instructs the linker to generate a single GOT with ++entries at both negative and positive offsets. Not all environments ++support such GOTs. ++@samp{multigot} allows the linker to generate several GOTs in the ++output file. All GOT references from a single input object ++file access the same GOT, but references from different input object ++files might access different GOTs. Not all environments support such GOTs. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MIPS ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MIPS ++@section @command{ld} and the MIPS family ++ ++@cindex MIPS microMIPS instruction choice selection ++@kindex --insn32 ++@kindex --no-insn32 ++The @samp{--insn32} and @samp{--no-insn32} options control the choice of ++microMIPS instructions used in code generated by the linker, such as that ++in the PLT or lazy binding stubs, or in relaxation. If @samp{--insn32} is ++used, then the linker only uses 32-bit instruction encodings. By default ++or if @samp{--no-insn32} is used, all instruction encodings are used, ++including 16-bit ones where possible. ++ ++@cindex MIPS branch relocation check control ++@kindex --ignore-branch-isa ++@kindex --no-ignore-branch-isa ++The @samp{--ignore-branch-isa} and @samp{--no-ignore-branch-isa} options ++control branch relocation checks for invalid ISA mode transitions. If ++@samp{--ignore-branch-isa} is used, then the linker accepts any branch ++relocations and any ISA mode transition required is lost in relocation ++calculation, except for some cases of @code{BAL} instructions which meet ++relaxation conditions and are converted to equivalent @code{JALX} ++instructions as the associated relocation is calculated. By default ++or if @samp{--no-ignore-branch-isa} is used a check is made causing ++the loss of an ISA mode transition to produce an error. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MMIX ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MMIX ++@section @code{ld} and MMIX ++For MMIX, there is a choice of generating @code{ELF} object files or ++@code{mmo} object files when linking. The simulator @code{mmix} ++understands the @code{mmo} format. The binutils @code{objcopy} utility ++can translate between the two formats. ++ ++There is one special section, the @samp{.MMIX.reg_contents} section. ++Contents in this section is assumed to correspond to that of global ++registers, and symbols referring to it are translated to special symbols, ++equal to registers. In a final link, the start address of the ++@samp{.MMIX.reg_contents} section corresponds to the first allocated ++global register multiplied by 8. Register @code{$255} is not included in ++this section; it is always set to the program entry, which is at the ++symbol @code{Main} for @code{mmo} files. ++ ++Global symbols with the prefix @code{__.MMIX.start.}, for example ++@code{__.MMIX.start..text} and @code{__.MMIX.start..data} are special. ++The default linker script uses these to set the default start address ++of a section. ++ ++Initial and trailing multiples of zero-valued 32-bit words in a section, ++are left out from an mmo file. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset MSP430 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node MSP430 ++@section @code{ld} and MSP430 ++For the MSP430 it is possible to select the MPU architecture. The flag @samp{-m [mpu type]} ++will select an appropriate linker script for selected MPU type. (To get a list of known MPUs ++just pass @samp{-m help} option to the linker). ++ ++@cindex MSP430 extra sections ++The linker will recognize some extra sections which are MSP430 specific: ++ ++@table @code ++@item @samp{.vectors} ++Defines a portion of ROM where interrupt vectors located. ++ ++@item @samp{.bootloader} ++Defines the bootloader portion of the ROM (if applicable). Any code ++in this section will be uploaded to the MPU. ++ ++@item @samp{.infomem} ++Defines an information memory section (if applicable). Any code in ++this section will be uploaded to the MPU. ++ ++@item @samp{.infomemnobits} ++This is the same as the @samp{.infomem} section except that any code ++in this section will not be uploaded to the MPU. ++ ++@item @samp{.noinit} ++Denotes a portion of RAM located above @samp{.bss} section. ++ ++The last two sections are used by gcc. ++@end table ++ ++@table @option ++@cindex MSP430 Options ++@kindex --code-region ++@item --code-region=[either,lower,upper,none] ++This will transform .text* sections to [either,lower,upper].text* sections. The ++argument passed to GCC for -mcode-region is propagated to the linker ++using this option. ++ ++@kindex --data-region ++@item --data-region=[either,lower,upper,none] ++This will transform .data*, .bss* and .rodata* sections to ++[either,lower,upper].[data,bss,rodata]* sections. The argument passed to GCC ++for -mdata-region is propagated to the linker using this option. ++ ++@kindex --disable-sec-transformation ++@item --disable-sec-transformation ++Prevent the transformation of sections as specified by the @code{--code-region} ++and @code{--data-region} options. ++This is useful if you are compiling and linking using a single call to the GCC ++wrapper, and want to compile the source files using -m[code,data]-region but ++not transform the sections for prebuilt libraries and objects. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset NDS32 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node NDS32 ++@section @code{ld} and NDS32 ++@kindex relaxing on NDS32 ++For NDS32, there are some options to select relaxation behavior. The linker ++relaxes objects according to these options. ++ ++@table @code ++@item @samp{--m[no-]fp-as-gp} ++Disable/enable fp-as-gp relaxation. ++ ++@item @samp{--mexport-symbols=FILE} ++Exporting symbols and their address into FILE as linker script. ++ ++@item @samp{--m[no-]ex9} ++Disable/enable link-time EX9 relaxation. ++ ++@item @samp{--mexport-ex9=FILE} ++Export the EX9 table after linking. ++ ++@item @samp{--mimport-ex9=FILE} ++Import the Ex9 table for EX9 relaxation. ++ ++@item @samp{--mupdate-ex9} ++Update the existing EX9 table. ++ ++@item @samp{--mex9-limit=NUM} ++Maximum number of entries in the ex9 table. ++ ++@item @samp{--mex9-loop-aware} ++Avoid generating the EX9 instruction inside the loop. ++ ++@item @samp{--m[no-]ifc} ++Disable/enable the link-time IFC optimization. ++ ++@item @samp{--mifc-loop-aware} ++Avoid generating the IFC instruction inside the loop. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset NIOSII ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node Nios II ++@section @command{ld} and the Altera Nios II ++@cindex Nios II call relaxation ++@kindex --relax on Nios II ++ ++Call and immediate jump instructions on Nios II processors are limited to ++transferring control to addresses in the same 256MB memory segment, ++which may result in @command{ld} giving ++@samp{relocation truncated to fit} errors with very large programs. ++The command-line option @option{--relax} enables the generation of ++trampolines that can access the entire 32-bit address space for calls ++outside the normal @code{call} and @code{jmpi} address range. These ++trampolines are inserted at section boundaries, so may not themselves ++be reachable if an input section and its associated call trampolines are ++larger than 256MB. ++ ++The @option{--relax} option is enabled by default unless @option{-r} ++is also specified. You can disable trampoline generation by using the ++@option{--no-relax} linker option. You can also disable this optimization ++locally by using the @samp{set .noat} directive in assembly-language ++source files, as the linker-inserted trampolines use the @code{at} ++register as a temporary. ++ ++Note that the linker @option{--relax} option is independent of assembler ++relaxation options, and that using the GNU assembler's @option{-relax-all} ++option interferes with the linker's more selective call instruction relaxation. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset POWERPC ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node PowerPC ELF32 ++@section @command{ld} and PowerPC 32-bit ELF Support ++@cindex PowerPC long branches ++@kindex --relax on PowerPC ++Branches on PowerPC processors are limited to a signed 26-bit ++displacement, which may result in @command{ld} giving ++@samp{relocation truncated to fit} errors with very large programs. ++@samp{--relax} enables the generation of trampolines that can access ++the entire 32-bit address space. These trampolines are inserted at ++section boundaries, so may not themselves be reachable if an input ++section exceeds 33M in size. You may combine @samp{-r} and ++@samp{--relax} to add trampolines in a partial link. In that case ++both branches to undefined symbols and inter-section branches are also ++considered potentially out of range, and trampolines inserted. ++ ++@cindex PowerPC ELF32 options ++@table @option ++@cindex PowerPC PLT ++@kindex --bss-plt ++@item --bss-plt ++Current PowerPC GCC accepts a @samp{-msecure-plt} option that ++generates code capable of using a newer PLT and GOT layout that has ++the security advantage of no executable section ever needing to be ++writable and no writable section ever being executable. PowerPC ++@command{ld} will generate this layout, including stubs to access the ++PLT, if all input files (including startup and static libraries) were ++compiled with @samp{-msecure-plt}. @samp{--bss-plt} forces the old ++BSS PLT (and GOT layout) which can give slightly better performance. ++ ++@kindex --secure-plt ++@item --secure-plt ++@command{ld} will use the new PLT and GOT layout if it is linking new ++@samp{-fpic} or @samp{-fPIC} code, but does not do so automatically ++when linking non-PIC code. This option requests the new PLT and GOT ++layout. A warning will be given if some object file requires the old ++style BSS PLT. ++ ++@cindex PowerPC GOT ++@kindex --sdata-got ++@item --sdata-got ++The new secure PLT and GOT are placed differently relative to other ++sections compared to older BSS PLT and GOT placement. The location of ++@code{.plt} must change because the new secure PLT is an initialized ++section while the old PLT is uninitialized. The reason for the ++@code{.got} change is more subtle: The new placement allows ++@code{.got} to be read-only in applications linked with ++@samp{-z relro -z now}. However, this placement means that ++@code{.sdata} cannot always be used in shared libraries, because the ++PowerPC ABI accesses @code{.sdata} in shared libraries from the GOT ++pointer. @samp{--sdata-got} forces the old GOT placement. PowerPC ++GCC doesn't use @code{.sdata} in shared libraries, so this option is ++really only useful for other compilers that may do so. ++ ++@cindex PowerPC stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label linker stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex PowerPC TLS optimization ++@kindex --no-tls-optimize ++@item --no-tls-optimize ++PowerPC @command{ld} normally performs some optimization of code ++sequences used to access Thread-Local Storage. Use this option to ++disable the optimization. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset POWERPC64 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node PowerPC64 ELF64 ++@section @command{ld} and PowerPC64 64-bit ELF Support ++ ++@cindex PowerPC64 ELF64 options ++@table @option ++@cindex PowerPC64 stub grouping ++@kindex --stub-group-size ++@item --stub-group-size ++Long branch stubs, PLT call stubs and TOC adjusting stubs are placed ++by @command{ld} in stub sections located between groups of input sections. ++@samp{--stub-group-size} specifies the maximum size of a group of input ++sections handled by one stub section. Since branch offsets are signed, ++a stub section may serve two groups of input sections, one group before ++the stub section, and one group after it. However, when using ++conditional branches that require stubs, it may be better (for branch ++prediction) that stub sections only serve one group of input sections. ++A negative value for @samp{N} chooses this scheme, ensuring that ++branches to stubs always use a negative offset. Two special values of ++@samp{N} are recognized, @samp{1} and @samp{-1}. These both instruct ++@command{ld} to automatically size input section groups for the branch types ++detected, with the same behaviour regarding stub placement as other ++positive or negative values of @samp{N} respectively. ++ ++Note that @samp{--stub-group-size} does not split input sections. A ++single input section larger than the group size specified will of course ++create a larger group (of one section). If input sections are too ++large, it may not be possible for a branch to reach its stub. ++ ++@cindex PowerPC64 stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label linker stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex PowerPC64 dot symbols ++@kindex --dotsyms ++@kindex --no-dotsyms ++@item --dotsyms ++@itemx --no-dotsyms ++These two options control how @command{ld} interprets version patterns ++in a version script. Older PowerPC64 compilers emitted both a ++function descriptor symbol with the same name as the function, and a ++code entry symbol with the name prefixed by a dot (@samp{.}). To ++properly version a function @samp{foo}, the version script thus needs ++to control both @samp{foo} and @samp{.foo}. The option ++@samp{--dotsyms}, on by default, automatically adds the required ++dot-prefixed patterns. Use @samp{--no-dotsyms} to disable this ++feature. ++ ++@cindex PowerPC64 register save/restore functions ++@kindex --save-restore-funcs ++@kindex --no-save-restore-funcs ++@item --save-restore-funcs ++@itemx --no-save-restore-funcs ++These two options control whether PowerPC64 @command{ld} automatically ++provides out-of-line register save and restore functions used by ++@samp{-Os} code. The default is to provide any such referenced ++function for a normal final link, and to not do so for a relocatable ++link. ++ ++@cindex PowerPC64 TLS optimization ++@kindex --no-tls-optimize ++@item --no-tls-optimize ++PowerPC64 @command{ld} normally performs some optimization of code ++sequences used to access Thread-Local Storage. Use this option to ++disable the optimization. ++ ++@cindex PowerPC64 __tls_get_addr optimization ++@kindex --tls-get-addr-optimize ++@kindex --no-tls-get-addr-optimize ++@kindex --tls-get-addr-regsave ++@kindex --no-tls-get-addr-regsave ++@item --tls-get-addr-optimize ++@itemx --no-tls-get-addr-optimize ++These options control how PowerPC64 @command{ld} uses a special ++stub to call __tls_get_addr. PowerPC64 glibc 2.22 and later support ++an optimization that allows the second and subsequent calls to ++@code{__tls_get_addr} for a given symbol to be resolved by the special ++stub without calling in to glibc. By default the linker enables ++generation of the stub when glibc advertises the availability of ++__tls_get_addr_opt. ++Using @option{--tls-get-addr-optimize} with an older glibc won't do ++much besides slow down your applications, but may be useful if linking ++an application against an older glibc with the expectation that it ++will normally be used on systems having a newer glibc. ++@option{--tls-get-addr-regsave} forces generation of a stub that saves ++and restores volatile registers around the call into glibc. Normally, ++this is done when the linker detects a call to __tls_get_addr_desc. ++Such calls then go via the register saving stub to __tls_get_addr_opt. ++@option{--no-tls-get-addr-regsave} disables generation of the ++register saves. ++ ++@cindex PowerPC64 OPD optimization ++@kindex --no-opd-optimize ++@item --no-opd-optimize ++PowerPC64 @command{ld} normally removes @code{.opd} section entries ++corresponding to deleted link-once functions, or functions removed by ++the action of @samp{--gc-sections} or linker script @code{/DISCARD/}. ++Use this option to disable @code{.opd} optimization. ++ ++@cindex PowerPC64 OPD spacing ++@kindex --non-overlapping-opd ++@item --non-overlapping-opd ++Some PowerPC64 compilers have an option to generate compressed ++@code{.opd} entries spaced 16 bytes apart, overlapping the third word, ++the static chain pointer (unused in C) with the first word of the next ++entry. This option expands such entries to the full 24 bytes. ++ ++@cindex PowerPC64 TOC optimization ++@kindex --no-toc-optimize ++@item --no-toc-optimize ++PowerPC64 @command{ld} normally removes unused @code{.toc} section ++entries. Such entries are detected by examining relocations that ++reference the TOC in code sections. A reloc in a deleted code section ++marks a TOC word as unneeded, while a reloc in a kept code section ++marks a TOC word as needed. Since the TOC may reference itself, TOC ++relocs are also examined. TOC words marked as both needed and ++unneeded will of course be kept. TOC words without any referencing ++reloc are assumed to be part of a multi-word entry, and are kept or ++discarded as per the nearest marked preceding word. This works ++reliably for compiler generated code, but may be incorrect if assembly ++code is used to insert TOC entries. Use this option to disable the ++optimization. ++ ++@cindex PowerPC64 inline PLT call optimization ++@kindex --no-inline-optimize ++@item --no-inline-optimize ++PowerPC64 @command{ld} normally replaces inline PLT call sequences ++marked with @code{R_PPC64_PLTSEQ}, @code{R_PPC64_PLTCALL}, ++@code{R_PPC64_PLT16_HA} and @code{R_PPC64_PLT16_LO_DS} relocations by ++a number of @code{nop}s and a direct call when the function is defined ++locally and can't be overridden by some other definition. This option ++disables that optimization. ++ ++@cindex PowerPC64 multi-TOC ++@kindex --no-multi-toc ++@item --no-multi-toc ++If given any toc option besides @code{-mcmodel=medium} or ++@code{-mcmodel=large}, PowerPC64 GCC generates code for a TOC model ++where TOC ++entries are accessed with a 16-bit offset from r2. This limits the ++total TOC size to 64K. PowerPC64 @command{ld} extends this limit by ++grouping code sections such that each group uses less than 64K for its ++TOC entries, then inserts r2 adjusting stubs between inter-group ++calls. @command{ld} does not split apart input sections, so cannot ++help if a single input file has a @code{.toc} section that exceeds ++64K, most likely from linking multiple files with @command{ld -r}. ++Use this option to turn off this feature. ++ ++@cindex PowerPC64 TOC sorting ++@kindex --no-toc-sort ++@item --no-toc-sort ++By default, @command{ld} sorts TOC sections so that those whose file ++happens to have a section called @code{.init} or @code{.fini} are ++placed first, followed by TOC sections referenced by code generated ++with PowerPC64 gcc's @code{-mcmodel=small}, and lastly TOC sections ++referenced only by code generated with PowerPC64 gcc's ++@code{-mcmodel=medium} or @code{-mcmodel=large} options. Doing this ++results in better TOC grouping for multi-TOC. Use this option to turn ++off this feature. ++ ++@cindex PowerPC64 PLT stub alignment ++@kindex --plt-align ++@kindex --no-plt-align ++@item --plt-align ++@itemx --no-plt-align ++Use these options to control whether individual PLT call stubs are ++aligned to a 32-byte boundary, or to the specified power of two ++boundary when using @code{--plt-align=}. A negative value may be ++specified to pad PLT call stubs so that they do not cross the ++specified power of two boundary (or the minimum number of boundaries ++if a PLT stub is so large that it must cross a boundary). By default ++PLT call stubs are aligned to 32-byte boundaries. ++ ++@cindex PowerPC64 PLT call stub static chain ++@kindex --plt-static-chain ++@kindex --no-plt-static-chain ++@item --plt-static-chain ++@itemx --no-plt-static-chain ++Use these options to control whether PLT call stubs load the static ++chain pointer (r11). @code{ld} defaults to not loading the static ++chain since there is never any need to do so on a PLT call. ++ ++@cindex PowerPC64 PLT call stub thread safety ++@kindex --plt-thread-safe ++@kindex --no-plt-thread-safe ++@item --plt-thread-safe ++@itemx --no-plt-thread-safe ++With power7's weakly ordered memory model, it is possible when using ++lazy binding for ld.so to update a plt entry in one thread and have ++another thread see the individual plt entry words update in the wrong ++order, despite ld.so carefully writing in the correct order and using ++memory write barriers. To avoid this we need some sort of read ++barrier in the call stub, or use LD_BIND_NOW=1. By default, @code{ld} ++looks for calls to commonly used functions that create threads, and if ++seen, adds the necessary barriers. Use these options to change the ++default behaviour. ++ ++@cindex PowerPC64 ELFv2 PLT localentry optimization ++@kindex --plt-localentry ++@kindex --no-plt-localentry ++@item --plt-localentry ++@itemx --no-localentry ++ELFv2 functions with localentry:0 are those with a single entry point, ++ie. global entry == local entry, and that have no requirement on r2 ++(the TOC/GOT pointer) or r12, and guarantee r2 is unchanged on return. ++Such an external function can be called via the PLT without saving r2 ++or restoring it on return, avoiding a common load-hit-store for small ++functions. The optimization is attractive, with up to 40% reduction ++in execution time for a small function, but can result in symbol ++interposition failures. Also, minor changes in a shared library, ++including system libraries, can cause a function that was localentry:0 ++to become localentry:8. This will result in a dynamic loader ++complaint and failure to run. The option is experimental, use with ++care. @option{--no-plt-localentry} is the default. ++ ++@cindex PowerPC64 Power10 stubs ++@kindex --power10-stubs ++@kindex --no-power10-stubs ++@item --power10-stubs ++@itemx --no-power10-stubs ++When PowerPC64 @command{ld} links input object files containing ++relocations used on power10 prefixed instructions it normally creates ++linkage stubs (PLT call and long branch) using power10 instructions ++for @code{@@notoc} PLT calls where @code{r2} is not known. The ++power10 notoc stubs are smaller and faster, so are preferred for ++power10. @option{--power10-stubs} and @option{--no-power10-stubs} ++allow you to override the linker's selection of stub instructions. ++@option{--power10-stubs=auto} allows the user to select the default ++auto mode. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset S/390 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node S/390 ELF ++@section @command{ld} and S/390 ELF Support ++ ++@cindex S/390 ELF options ++@table @option ++ ++@cindex S/390 ++@kindex --s390-pgste ++@item --s390-pgste ++This option marks the result file with a @code{PT_S390_PGSTE} ++segment. The Linux kernel is supposed to allocate 4k page tables for ++binaries marked that way. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset SPU ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node SPU ELF ++@section @command{ld} and SPU ELF Support ++ ++@cindex SPU ELF options ++@table @option ++ ++@cindex SPU plugins ++@kindex --plugin ++@item --plugin ++This option marks an executable as a PIC plugin module. ++ ++@cindex SPU overlays ++@kindex --no-overlays ++@item --no-overlays ++Normally, @command{ld} recognizes calls to functions within overlay ++regions, and redirects such calls to an overlay manager via a stub. ++@command{ld} also provides a built-in overlay manager. This option ++turns off all this special overlay handling. ++ ++@cindex SPU overlay stub symbols ++@kindex --emit-stub-syms ++@item --emit-stub-syms ++This option causes @command{ld} to label overlay stubs with a local ++symbol that encodes the stub type and destination. ++ ++@cindex SPU extra overlay stubs ++@kindex --extra-overlay-stubs ++@item --extra-overlay-stubs ++This option causes @command{ld} to add overlay call stubs on all ++function calls out of overlay regions. Normally stubs are not added ++on calls to non-overlay regions. ++ ++@cindex SPU local store size ++@kindex --local-store=lo:hi ++@item --local-store=lo:hi ++@command{ld} usually checks that a final executable for SPU fits in ++the address range 0 to 256k. This option may be used to change the ++range. Disable the check entirely with @option{--local-store=0:0}. ++ ++@cindex SPU ++@kindex --stack-analysis ++@item --stack-analysis ++SPU local store space is limited. Over-allocation of stack space ++unnecessarily limits space available for code and data, while ++under-allocation results in runtime failures. If given this option, ++@command{ld} will provide an estimate of maximum stack usage. ++@command{ld} does this by examining symbols in code sections to ++determine the extents of functions, and looking at function prologues ++for stack adjusting instructions. A call-graph is created by looking ++for relocations on branch instructions. The graph is then searched ++for the maximum stack usage path. Note that this analysis does not ++find calls made via function pointers, and does not handle recursion ++and other cycles in the call graph. Stack usage may be ++under-estimated if your code makes such calls. Also, stack usage for ++dynamic allocation, e.g. alloca, will not be detected. If a link map ++is requested, detailed information about each function's stack usage ++and calls will be given. ++ ++@cindex SPU ++@kindex --emit-stack-syms ++@item --emit-stack-syms ++This option, if given along with @option{--stack-analysis} will result ++in @command{ld} emitting stack sizing symbols for each function. ++These take the form @code{__stack_} for global ++functions, and @code{__stack__} for static ++functions. @code{} is the section id in hex. The value of ++such symbols is the stack requirement for the corresponding function. ++The symbol size will be zero, type @code{STT_NOTYPE}, binding ++@code{STB_LOCAL}, and section @code{SHN_ABS}. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset TICOFF ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node TI COFF ++@section @command{ld}'s Support for Various TI COFF Versions ++@cindex TI COFF versions ++@kindex --format=@var{version} ++The @samp{--format} switch allows selection of one of the various ++TI COFF versions. The latest of this writing is 2; versions 0 and 1 are ++also supported. The TI COFF versions also vary in header byte-order ++format; @command{ld} will read any version or byte order, but the output ++header format depends on the default specified by the specific target. ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset WIN32 ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node WIN32 ++@section @command{ld} and WIN32 (cygwin/mingw) ++ ++This section describes some of the win32 specific @command{ld} issues. ++See @ref{Options,,Command-line Options} for detailed description of the ++command-line options mentioned here. ++ ++@table @emph ++@cindex import libraries ++@item import libraries ++The standard Windows linker creates and uses so-called import ++libraries, which contains information for linking to dll's. They are ++regular static archives and are handled as any other static ++archive. The cygwin and mingw ports of @command{ld} have specific ++support for creating such libraries provided with the ++@samp{--out-implib} command-line option. ++ ++@item Resource only DLLs ++It is possible to create a DLL that only contains resources, ie just a ++@samp{.rsrc} section, but in order to do so a custom linker script ++must be used. This is because the built-in default linker scripts ++will always create @samp{.text} and @samp{.idata} sections, even if ++there is no input to go into them. ++ ++The script should look like this, although the @code{OUTPUT_FORMAT} ++should be changed to match the desired format. ++ ++@example ++OUTPUT_FORMAT(pei-i386) ++SECTIONS ++@{ ++ . = SIZEOF_HEADERS; ++ . = ALIGN(__section_alignment__); ++ .rsrc __image_base__ + __section_alignment__ : ALIGN(4) ++ @{ ++ KEEP (*(.rsrc)) ++ KEEP (*(.rsrc$*)) ++ @} ++ /DISCARD/ : @{ *(*) @} ++@} ++@end example ++ ++With this script saved to a file called, eg @file{rsrc.ld}, a command ++line like this can be used to create the resource only DLL ++@file{rsrc.dll} from an input file called @file{rsrc.o}: ++ ++@smallexample ++ld -dll --subsystem windows -e 0 -s rsrc.o -o rsrc.dll -T rsrc.ld ++@end smallexample ++ ++@item exporting DLL symbols ++@cindex exporting DLL symbols ++The cygwin/mingw @command{ld} has several ways to export symbols for dll's. ++ ++@table @emph ++@item using auto-export functionality ++@cindex using auto-export functionality ++By default @command{ld} exports symbols with the auto-export functionality, ++which is controlled by the following command-line options: ++ ++@itemize ++@item --export-all-symbols [This is the default] ++@item --exclude-symbols ++@item --exclude-libs ++@item --exclude-modules-for-implib ++@item --version-script ++@end itemize ++ ++When auto-export is in operation, @command{ld} will export all the non-local ++(global and common) symbols it finds in a DLL, with the exception of a few ++symbols known to belong to the system's runtime and libraries. As it will ++often not be desirable to export all of a DLL's symbols, which may include ++private functions that are not part of any public interface, the command-line ++options listed above may be used to filter symbols out from the list for ++exporting. The @samp{--output-def} option can be used in order to see the ++final list of exported symbols with all exclusions taken into effect. ++ ++If @samp{--export-all-symbols} is not given explicitly on the ++command line, then the default auto-export behavior will be @emph{disabled} ++if either of the following are true: ++ ++@itemize ++@item A DEF file is used. ++@item Any symbol in any object file was marked with the __declspec(dllexport) attribute. ++@end itemize ++ ++@item using a DEF file ++@cindex using a DEF file ++Another way of exporting symbols is using a DEF file. A DEF file is ++an ASCII file containing definitions of symbols which should be ++exported when a dll is created. Usually it is named @samp{.def} and is added as any other object file to the linker's ++command line. The file's name must end in @samp{.def} or @samp{.DEF}. ++ ++@example ++gcc -o .def ++@end example ++ ++Using a DEF file turns off the normal auto-export behavior, unless the ++@samp{--export-all-symbols} option is also used. ++ ++Here is an example of a DEF file for a shared library called @samp{xyz.dll}: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x20000000 ++ ++EXPORTS ++foo ++bar ++_bar = bar ++another_foo = abc.dll.afoo ++var1 DATA ++doo = foo == foo2 ++eoo DATA == var1 ++@end example ++ ++This example defines a DLL with a non-default base address and seven ++symbols in the export table. The third exported symbol @code{_bar} is an ++alias for the second. The fourth symbol, @code{another_foo} is resolved ++by "forwarding" to another module and treating it as an alias for ++@code{afoo} exported from the DLL @samp{abc.dll}. The final symbol ++@code{var1} is declared to be a data object. The @samp{doo} symbol in ++export library is an alias of @samp{foo}, which gets the string name ++in export table @samp{foo2}. The @samp{eoo} symbol is an data export ++symbol, which gets in export table the name @samp{var1}. ++ ++The optional @code{LIBRARY } command indicates the @emph{internal} ++name of the output DLL. If @samp{} does not include a suffix, ++the default library suffix, @samp{.DLL} is appended. ++ ++When the .DEF file is used to build an application, rather than a ++library, the @code{NAME } command should be used instead of ++@code{LIBRARY}. If @samp{} does not include a suffix, the default ++executable suffix, @samp{.EXE} is appended. ++ ++With either @code{LIBRARY } or @code{NAME } the optional ++specification @code{BASE = } may be used to specify a ++non-default base address for the image. ++ ++If neither @code{LIBRARY } nor @code{NAME } is specified, ++or they specify an empty string, the internal name is the same as the ++filename specified on the command line. ++ ++The complete specification of an export symbol is: ++ ++@example ++EXPORTS ++ ( ( ( [ = ] ) ++ | ( = . )) ++ [ @@ ] [NONAME] [DATA] [CONSTANT] [PRIVATE] [== ] ) * ++@end example ++ ++Declares @samp{} as an exported symbol from the DLL, or declares ++@samp{} as an exported alias for @samp{}; or declares ++@samp{} as a "forward" alias for the symbol ++@samp{} in the DLL @samp{}. ++Optionally, the symbol may be exported by the specified ordinal ++@samp{} alias. The optional @samp{} is the to be used ++string in import/export table for the symbol. ++ ++The optional keywords that follow the declaration indicate: ++ ++@code{NONAME}: Do not put the symbol name in the DLL's export table. It ++will still be exported by its ordinal alias (either the value specified ++by the .def specification or, otherwise, the value assigned by the ++linker). The symbol name, however, does remain visible in the import ++library (if any), unless @code{PRIVATE} is also specified. ++ ++@code{DATA}: The symbol is a variable or object, rather than a function. ++The import lib will export only an indirect reference to @code{foo} as ++the symbol @code{_imp__foo} (ie, @code{foo} must be resolved as ++@code{*_imp__foo}). ++ ++@code{CONSTANT}: Like @code{DATA}, but put the undecorated @code{foo} as ++well as @code{_imp__foo} into the import library. Both refer to the ++read-only import address table's pointer to the variable, not to the ++variable itself. This can be dangerous. If the user code fails to add ++the @code{dllimport} attribute and also fails to explicitly add the ++extra indirection that the use of the attribute enforces, the ++application will behave unexpectedly. ++ ++@code{PRIVATE}: Put the symbol in the DLL's export table, but do not put ++it into the static import library used to resolve imports at link time. The ++symbol can still be imported using the @code{LoadLibrary/GetProcAddress} ++API at runtime or by using the GNU ld extension of linking directly to ++the DLL without an import library. ++ ++See ld/deffilep.y in the binutils sources for the full specification of ++other DEF file statements ++ ++@cindex creating a DEF file ++While linking a shared dll, @command{ld} is able to create a DEF file ++with the @samp{--output-def } command-line option. ++ ++@item Using decorations ++@cindex Using decorations ++Another way of marking symbols for export is to modify the source code ++itself, so that when building the DLL each symbol to be exported is ++declared as: ++ ++@example ++__declspec(dllexport) int a_variable ++__declspec(dllexport) void a_function(int with_args) ++@end example ++ ++All such symbols will be exported from the DLL. If, however, ++any of the object files in the DLL contain symbols decorated in ++this way, then the normal auto-export behavior is disabled, unless ++the @samp{--export-all-symbols} option is also used. ++ ++Note that object files that wish to access these symbols must @emph{not} ++decorate them with dllexport. Instead, they should use dllimport, ++instead: ++ ++@example ++__declspec(dllimport) int a_variable ++__declspec(dllimport) void a_function(int with_args) ++@end example ++ ++This complicates the structure of library header files, because ++when included by the library itself the header must declare the ++variables and functions as dllexport, but when included by client ++code the header must declare them as dllimport. There are a number ++of idioms that are typically used to do this; often client code can ++omit the __declspec() declaration completely. See ++@samp{--enable-auto-import} and @samp{automatic data imports} for more ++information. ++@end table ++ ++@cindex automatic data imports ++@item automatic data imports ++The standard Windows dll format supports data imports from dlls only ++by adding special decorations (dllimport/dllexport), which let the ++compiler produce specific assembler instructions to deal with this ++issue. This increases the effort necessary to port existing Un*x ++code to these platforms, especially for large ++c++ libraries and applications. The auto-import feature, which was ++initially provided by Paul Sokolovsky, allows one to omit the ++decorations to achieve a behavior that conforms to that on POSIX/Un*x ++platforms. This feature is enabled with the @samp{--enable-auto-import} ++command-line option, although it is enabled by default on cygwin/mingw. ++The @samp{--enable-auto-import} option itself now serves mainly to ++suppress any warnings that are ordinarily emitted when linked objects ++trigger the feature's use. ++ ++auto-import of variables does not always work flawlessly without ++additional assistance. Sometimes, you will see this message ++ ++"variable '' can't be auto-imported. Please read the ++documentation for ld's @code{--enable-auto-import} for details." ++ ++The @samp{--enable-auto-import} documentation explains why this error ++occurs, and several methods that can be used to overcome this difficulty. ++One of these methods is the @emph{runtime pseudo-relocs} feature, described ++below. ++ ++@cindex runtime pseudo-relocation ++For complex variables imported from DLLs (such as structs or classes), ++object files typically contain a base address for the variable and an ++offset (@emph{addend}) within the variable--to specify a particular ++field or public member, for instance. Unfortunately, the runtime loader used ++in win32 environments is incapable of fixing these references at runtime ++without the additional information supplied by dllimport/dllexport decorations. ++The standard auto-import feature described above is unable to resolve these ++references. ++ ++The @samp{--enable-runtime-pseudo-relocs} switch allows these references to ++be resolved without error, while leaving the task of adjusting the references ++themselves (with their non-zero addends) to specialized code provided by the ++runtime environment. Recent versions of the cygwin and mingw environments and ++compilers provide this runtime support; older versions do not. However, the ++support is only necessary on the developer's platform; the compiled result will ++run without error on an older system. ++ ++@samp{--enable-runtime-pseudo-relocs} is not the default; it must be explicitly ++enabled as needed. ++ ++@cindex direct linking to a dll ++@item direct linking to a dll ++The cygwin/mingw ports of @command{ld} support the direct linking, ++including data symbols, to a dll without the usage of any import ++libraries. This is much faster and uses much less memory than does the ++traditional import library method, especially when linking large ++libraries or applications. When @command{ld} creates an import lib, each ++function or variable exported from the dll is stored in its own bfd, even ++though a single bfd could contain many exports. The overhead involved in ++storing, loading, and processing so many bfd's is quite large, and explains the ++tremendous time, memory, and storage needed to link against particularly ++large or complex libraries when using import libs. ++ ++Linking directly to a dll uses no extra command-line switches other than ++@samp{-L} and @samp{-l}, because @command{ld} already searches for a number ++of names to match each library. All that is needed from the developer's ++perspective is an understanding of this search, in order to force ld to ++select the dll instead of an import library. ++ ++ ++For instance, when ld is called with the argument @samp{-lxxx} it will attempt ++to find, in the first directory of its search path, ++ ++@example ++libxxx.dll.a ++xxx.dll.a ++libxxx.a ++xxx.lib ++libxxx.lib ++cygxxx.dll (*) ++libxxx.dll ++xxx.dll ++@end example ++ ++before moving on to the next directory in the search path. ++ ++(*) Actually, this is not @samp{cygxxx.dll} but in fact is @samp{xxx.dll}, ++where @samp{} is set by the @command{ld} option ++@samp{--dll-search-prefix=}. In the case of cygwin, the standard gcc spec ++file includes @samp{--dll-search-prefix=cyg}, so in effect we actually search for ++@samp{cygxxx.dll}. ++ ++Other win32-based unix environments, such as mingw or pw32, may use other ++@samp{}es, although at present only cygwin makes use of this feature. It ++was originally intended to help avoid name conflicts among dll's built for the ++various win32/un*x environments, so that (for example) two versions of a zlib dll ++could coexist on the same machine. ++ ++The generic cygwin/mingw path layout uses a @samp{bin} directory for ++applications and dll's and a @samp{lib} directory for the import ++libraries (using cygwin nomenclature): ++ ++@example ++bin/ ++ cygxxx.dll ++lib/ ++ libxxx.dll.a (in case of dll's) ++ libxxx.a (in case of static archive) ++@end example ++ ++Linking directly to a dll without using the import library can be ++done two ways: ++ ++1. Use the dll directly by adding the @samp{bin} path to the link line ++@example ++gcc -Wl,-verbose -o a.exe -L../bin/ -lxxx ++@end example ++ ++However, as the dll's often have version numbers appended to their names ++(@samp{cygncurses-5.dll}) this will often fail, unless one specifies ++@samp{-L../bin -lncurses-5} to include the version. Import libs are generally ++not versioned, and do not have this difficulty. ++ ++2. Create a symbolic link from the dll to a file in the @samp{lib} ++directory according to the above mentioned search pattern. This ++should be used to avoid unwanted changes in the tools needed for ++making the app/dll. ++ ++@example ++ln -s bin/cygxxx.dll lib/[cyg|lib|]xxx.dll[.a] ++@end example ++ ++Then you can link without any make environment changes. ++ ++@example ++gcc -Wl,-verbose -o a.exe -L../lib/ -lxxx ++@end example ++ ++This technique also avoids the version number problems, because the following is ++perfectly legal ++ ++@example ++bin/ ++ cygxxx-5.dll ++lib/ ++ libxxx.dll.a -> ../bin/cygxxx-5.dll ++@end example ++ ++Linking directly to a dll without using an import lib will work ++even when auto-import features are exercised, and even when ++@samp{--enable-runtime-pseudo-relocs} is used. ++ ++Given the improvements in speed and memory usage, one might justifiably ++wonder why import libraries are used at all. There are three reasons: ++ ++1. Until recently, the link-directly-to-dll functionality did @emph{not} ++work with auto-imported data. ++ ++2. Sometimes it is necessary to include pure static objects within the ++import library (which otherwise contains only bfd's for indirection ++symbols that point to the exports of a dll). Again, the import lib ++for the cygwin kernel makes use of this ability, and it is not ++possible to do this without an import lib. ++ ++3. Symbol aliases can only be resolved using an import lib. This is ++critical when linking against OS-supplied dll's (eg, the win32 API) ++in which symbols are usually exported as undecorated aliases of their ++stdcall-decorated assembly names. ++ ++So, import libs are not going away. But the ability to replace ++true import libs with a simple symbolic link to (or a copy of) ++a dll, in many cases, is a useful addition to the suite of tools ++binutils makes available to the win32 developer. Given the ++massive improvements in memory requirements during linking, storage ++requirements, and linking speed, we expect that many developers ++will soon begin to use this feature whenever possible. ++ ++@item symbol aliasing ++@table @emph ++@item adding additional names ++Sometimes, it is useful to export symbols with additional names. ++A symbol @samp{foo} will be exported as @samp{foo}, but it can also be ++exported as @samp{_foo} by using special directives in the DEF file ++when creating the dll. This will affect also the optional created ++import library. Consider the following DEF file: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x61000000 ++ ++EXPORTS ++foo ++_foo = foo ++@end example ++ ++The line @samp{_foo = foo} maps the symbol @samp{foo} to @samp{_foo}. ++ ++Another method for creating a symbol alias is to create it in the ++source code using the "weak" attribute: ++ ++@example ++void foo () @{ /* Do something. */; @} ++void _foo () __attribute__ ((weak, alias ("foo"))); ++@end example ++ ++See the gcc manual for more information about attributes and weak ++symbols. ++ ++@item renaming symbols ++Sometimes it is useful to rename exports. For instance, the cygwin ++kernel does this regularly. A symbol @samp{_foo} can be exported as ++@samp{foo} but not as @samp{_foo} by using special directives in the ++DEF file. (This will also affect the import library, if it is ++created). In the following example: ++ ++@example ++LIBRARY "xyz.dll" BASE=0x61000000 ++ ++EXPORTS ++_foo = foo ++@end example ++ ++The line @samp{_foo = foo} maps the exported symbol @samp{foo} to ++@samp{_foo}. ++@end table ++ ++Note: using a DEF file disables the default auto-export behavior, ++unless the @samp{--export-all-symbols} command-line option is used. ++If, however, you are trying to rename symbols, then you should list ++@emph{all} desired exports in the DEF file, including the symbols ++that are not being renamed, and do @emph{not} use the ++@samp{--export-all-symbols} option. If you list only the ++renamed symbols in the DEF file, and use @samp{--export-all-symbols} ++to handle the other symbols, then the both the new names @emph{and} ++the original names for the renamed symbols will be exported. ++In effect, you'd be aliasing those symbols, not renaming them, ++which is probably not what you wanted. ++ ++@cindex weak externals ++@item weak externals ++The Windows object format, PE, specifies a form of weak symbols called ++weak externals. When a weak symbol is linked and the symbol is not ++defined, the weak symbol becomes an alias for some other symbol. There ++are three variants of weak externals: ++@itemize ++@item Definition is searched for in objects and libraries, historically ++called lazy externals. ++@item Definition is searched for only in other objects, not in libraries. ++This form is not presently implemented. ++@item No search; the symbol is an alias. This form is not presently ++implemented. ++@end itemize ++As a GNU extension, weak symbols that do not specify an alternate symbol ++are supported. If the symbol is undefined when linking, the symbol ++uses a default value. ++ ++@cindex aligned common symbols ++@item aligned common symbols ++As a GNU extension to the PE file format, it is possible to specify the ++desired alignment for a common symbol. This information is conveyed from ++the assembler or compiler to the linker by means of GNU-specific commands ++carried in the object file's @samp{.drectve} section, which are recognized ++by @command{ld} and respected when laying out the common symbols. Native ++tools will be able to process object files employing this GNU extension, ++but will fail to respect the alignment instructions, and may issue noisy ++warnings about unknown linker directives. ++ ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifset XTENSA ++@ifclear GENERIC ++@raisesections ++@end ifclear ++ ++@node Xtensa ++@section @code{ld} and Xtensa Processors ++ ++@cindex Xtensa processors ++The default @command{ld} behavior for Xtensa processors is to interpret ++@code{SECTIONS} commands so that lists of explicitly named sections in a ++specification with a wildcard file will be interleaved when necessary to ++keep literal pools within the range of PC-relative load offsets. For ++example, with the command: ++ ++@smallexample ++SECTIONS ++@{ ++ .text : @{ ++ *(.literal .text) ++ @} ++@} ++@end smallexample ++ ++@noindent ++@command{ld} may interleave some of the @code{.literal} ++and @code{.text} sections from different object files to ensure that the ++literal pools are within the range of PC-relative load offsets. A valid ++interleaving might place the @code{.literal} sections from an initial ++group of files followed by the @code{.text} sections of that group of ++files. Then, the @code{.literal} sections from the rest of the files ++and the @code{.text} sections from the rest of the files would follow. ++ ++@cindex @option{--relax} on Xtensa ++@cindex relaxing on Xtensa ++Relaxation is enabled by default for the Xtensa version of @command{ld} and ++provides two important link-time optimizations. The first optimization ++is to combine identical literal values to reduce code size. A redundant ++literal will be removed and all the @code{L32R} instructions that use it ++will be changed to reference an identical literal, as long as the ++location of the replacement literal is within the offset range of all ++the @code{L32R} instructions. The second optimization is to remove ++unnecessary overhead from assembler-generated ``longcall'' sequences of ++@code{L32R}/@code{CALLX@var{n}} when the target functions are within ++range of direct @code{CALL@var{n}} instructions. ++ ++For each of these cases where an indirect call sequence can be optimized ++to a direct call, the linker will change the @code{CALLX@var{n}} ++instruction to a @code{CALL@var{n}} instruction, remove the @code{L32R} ++instruction, and remove the literal referenced by the @code{L32R} ++instruction if it is not used for anything else. Removing the ++@code{L32R} instruction always reduces code size but can potentially ++hurt performance by changing the alignment of subsequent branch targets. ++By default, the linker will always preserve alignments, either by ++switching some instructions between 24-bit encodings and the equivalent ++density instructions or by inserting a no-op in place of the @code{L32R} ++instruction that was removed. If code size is more important than ++performance, the @option{--size-opt} option can be used to prevent the ++linker from widening density instructions or inserting no-ops, except in ++a few cases where no-ops are required for correctness. ++ ++The following Xtensa-specific command-line options can be used to ++control the linker: ++ ++@cindex Xtensa options ++@table @option ++@item --size-opt ++When optimizing indirect calls to direct calls, optimize for code size ++more than performance. With this option, the linker will not insert ++no-ops or widen density instructions to preserve branch target ++alignment. There may still be some cases where no-ops are required to ++preserve the correctness of the code. ++ ++@item --abi-windowed ++@itemx --abi-call0 ++Choose ABI for the output object and for the generated PLT code. ++PLT code inserted by the linker must match ABI of the output object ++because windowed and call0 ABI use incompatible function call ++conventions. ++Default ABI is chosen by the ABI tag in the @code{.xtensa.info} section ++of the first input object. ++A warning is issued if ABI tags of input objects do not match each other ++or the chosen output object ABI. ++@end table ++ ++@ifclear GENERIC ++@lowersections ++@end ifclear ++@end ifset ++ ++@ifclear SingleFormat ++@node BFD ++@chapter BFD ++ ++@cindex back end ++@cindex object file management ++@cindex object formats available ++@kindex objdump -i ++The linker accesses object and archive files using the BFD libraries. ++These libraries allow the linker to use the same routines to operate on ++object files whatever the object file format. A different object file ++format can be supported simply by creating a new BFD back end and adding ++it to the library. To conserve runtime memory, however, the linker and ++associated tools are usually configured to support only a subset of the ++object file formats available. You can use @code{objdump -i} ++(@pxref{objdump,,objdump,binutils.info,The GNU Binary Utilities}) to ++list all the formats available for your configuration. ++ ++@cindex BFD requirements ++@cindex requirements for BFD ++As with most implementations, BFD is a compromise between ++several conflicting requirements. The major factor influencing ++BFD design was efficiency: any time used converting between ++formats is time which would not have been spent had BFD not ++been involved. This is partly offset by abstraction payback; since ++BFD simplifies applications and back ends, more time and care ++may be spent optimizing algorithms for a greater speed. ++ ++One minor artifact of the BFD solution which you should bear in ++mind is the potential for information loss. There are two places where ++useful information can be lost using the BFD mechanism: during ++conversion and during output. @xref{BFD information loss}. ++ ++@menu ++* BFD outline:: How it works: an outline of BFD ++@end menu ++ ++@node BFD outline ++@section How It Works: An Outline of BFD ++@cindex opening object files ++@include bfdsumm.texi ++@end ifclear ++ ++@node Reporting Bugs ++@chapter Reporting Bugs ++@cindex bugs in @command{ld} ++@cindex reporting bugs in @command{ld} ++ ++Your bug reports play an essential role in making @command{ld} reliable. ++ ++Reporting a bug may help you by bringing a solution to your problem, or ++it may not. But in any case the principal function of a bug report is ++to help the entire community by making the next version of @command{ld} ++work better. Bug reports are your contribution to the maintenance of ++@command{ld}. ++ ++In order for a bug report to serve its purpose, you must include the ++information that enables us to fix the bug. ++ ++@menu ++* Bug Criteria:: Have you found a bug? ++* Bug Reporting:: How to report bugs ++@end menu ++ ++@node Bug Criteria ++@section Have You Found a Bug? ++@cindex bug criteria ++ ++If you are not sure whether you have found a bug, here are some guidelines: ++ ++@itemize @bullet ++@cindex fatal signal ++@cindex linker crash ++@cindex crash of linker ++@item ++If the linker gets a fatal signal, for any input whatever, that is a ++@command{ld} bug. Reliable linkers never crash. ++ ++@cindex error on valid input ++@item ++If @command{ld} produces an error message for valid input, that is a bug. ++ ++@cindex invalid input ++@item ++If @command{ld} does not produce an error message for invalid input, that ++may be a bug. In the general case, the linker can not verify that ++object files are correct. ++ ++@item ++If you are an experienced user of linkers, your suggestions for ++improvement of @command{ld} are welcome in any case. ++@end itemize ++ ++@node Bug Reporting ++@section How to Report Bugs ++@cindex bug reports ++@cindex @command{ld} bugs, reporting ++ ++A number of companies and individuals offer support for @sc{gnu} ++products. If you obtained @command{ld} from a support organization, we ++recommend you contact that organization first. ++ ++You can find contact information for many support companies and ++individuals in the file @file{etc/SERVICE} in the @sc{gnu} Emacs ++distribution. ++ ++@ifset BUGURL ++Otherwise, send bug reports for @command{ld} to ++@value{BUGURL}. ++@end ifset ++ ++The fundamental principle of reporting bugs usefully is this: ++@strong{report all the facts}. If you are not sure whether to state a ++fact or leave it out, state it! ++ ++Often people omit facts because they think they know what causes the ++problem and assume that some details do not matter. Thus, you might ++assume that the name of a symbol you use in an example does not ++matter. Well, probably it does not, but one cannot be sure. Perhaps ++the bug is a stray memory reference which happens to fetch from the ++location where that name is stored in memory; perhaps, if the name ++were different, the contents of that location would fool the linker ++into doing the right thing despite the bug. Play it safe and give a ++specific, complete example. That is the easiest thing for you to do, ++and the most helpful. ++ ++Keep in mind that the purpose of a bug report is to enable us to fix ++the bug if it is new to us. Therefore, always write your bug reports ++on the assumption that the bug has not been reported previously. ++ ++Sometimes people give a few sketchy facts and ask, ``Does this ring a ++bell?'' This cannot help us fix a bug, so it is basically useless. We ++respond by asking for enough details to enable us to investigate. ++You might as well expedite matters by sending them to begin with. ++ ++To enable us to fix the bug, you should include all these things: ++ ++@itemize @bullet ++@item ++The version of @command{ld}. @command{ld} announces it if you start it with ++the @samp{--version} argument. ++ ++Without this, we will not know whether there is any point in looking for ++the bug in the current version of @command{ld}. ++ ++@item ++Any patches you may have applied to the @command{ld} source, including any ++patches made to the @code{BFD} library. ++ ++@item ++The type of machine you are using, and the operating system name and ++version number. ++ ++@item ++What compiler (and its version) was used to compile @command{ld}---e.g. ++``@code{gcc-2.7}''. ++ ++@item ++The command arguments you gave the linker to link your example and ++observe the bug. To guarantee you will not omit something important, ++list them all. A copy of the Makefile (or the output from make) is ++sufficient. ++ ++If we were to try to guess the arguments, we would probably guess wrong ++and then we might not encounter the bug. ++ ++@item ++A complete input file, or set of input files, that will reproduce the ++bug. It is generally most helpful to send the actual object files ++provided that they are reasonably small. Say no more than 10K. For ++bigger files you can either make them available by FTP or HTTP or else ++state that you are willing to send the object file(s) to whomever ++requests them. (Note - your email will be going to a mailing list, so ++we do not want to clog it up with large attachments). But small ++attachments are best. ++ ++If the source files were assembled using @code{gas} or compiled using ++@code{gcc}, then it may be OK to send the source files rather than the ++object files. In this case, be sure to say exactly what version of ++@code{gas} or @code{gcc} was used to produce the object files. Also say ++how @code{gas} or @code{gcc} were configured. ++ ++@item ++A description of what behavior you observe that you believe is ++incorrect. For example, ``It gets a fatal signal.'' ++ ++Of course, if the bug is that @command{ld} gets a fatal signal, then we ++will certainly notice it. But if the bug is incorrect output, we might ++not notice unless it is glaringly wrong. You might as well not give us ++a chance to make a mistake. ++ ++Even if the problem you experience is a fatal signal, you should still ++say so explicitly. Suppose something strange is going on, such as, your ++copy of @command{ld} is out of sync, or you have encountered a bug in the ++C library on your system. (This has happened!) Your copy might crash ++and ours would not. If you told us to expect a crash, then when ours ++fails to crash, we would know that the bug was not happening for us. If ++you had not told us to expect a crash, then we would not be able to draw ++any conclusion from our observations. ++ ++@item ++If you wish to suggest changes to the @command{ld} source, send us context ++diffs, as generated by @code{diff} with the @samp{-u}, @samp{-c}, or ++@samp{-p} option. Always send diffs from the old file to the new file. ++If you even discuss something in the @command{ld} source, refer to it by ++context, not by line number. ++ ++The line numbers in our development sources will not match those in your ++sources. Your line numbers would convey no useful information to us. ++@end itemize ++ ++Here are some things that are not necessary: ++ ++@itemize @bullet ++@item ++A description of the envelope of the bug. ++ ++Often people who encounter a bug spend a lot of time investigating ++which changes to the input file will make the bug go away and which ++changes will not affect it. ++ ++This is often time consuming and not very useful, because the way we ++will find the bug is by running a single example under the debugger ++with breakpoints, not by pure deduction from a series of examples. ++We recommend that you save your time for something else. ++ ++Of course, if you can find a simpler example to report @emph{instead} ++of the original one, that is a convenience for us. Errors in the ++output will be easier to spot, running under the debugger will take ++less time, and so on. ++ ++However, simplification is not vital; if you do not want to do this, ++report the bug anyway and send us the entire test case you used. ++ ++@item ++A patch for the bug. ++ ++A patch for the bug does help us if it is a good one. But do not omit ++the necessary information, such as the test case, on the assumption that ++a patch is all we need. We might see problems with your patch and decide ++to fix the problem another way, or we might not understand it at all. ++ ++Sometimes with a program as complicated as @command{ld} it is very hard to ++construct an example that will make the program follow a certain path ++through the code. If you do not send us the example, we will not be ++able to construct one, so we will not be able to verify that the bug is ++fixed. ++ ++And if we cannot understand what bug you are trying to fix, or why your ++patch should be an improvement, we will not install it. A test case will ++help us to understand. ++ ++@item ++A guess about what the bug is or what it depends on. ++ ++Such guesses are usually wrong. Even we cannot guess right about such ++things without first using the debugger to find the facts. ++@end itemize ++ ++@node MRI ++@appendix MRI Compatible Script Files ++@cindex MRI compatibility ++To aid users making the transition to @sc{gnu} @command{ld} from the MRI ++linker, @command{ld} can use MRI compatible linker scripts as an ++alternative to the more general-purpose linker scripting language ++described in @ref{Scripts}. MRI compatible linker scripts have a much ++simpler command set than the scripting language otherwise used with ++@command{ld}. @sc{gnu} @command{ld} supports the most commonly used MRI ++linker commands; these commands are described here. ++ ++In general, MRI scripts aren't of much use with the @code{a.out} object ++file format, since it only has three sections and MRI scripts lack some ++features to make use of them. ++ ++You can specify a file containing an MRI-compatible script using the ++@samp{-c} command-line option. ++ ++Each command in an MRI-compatible script occupies its own line; each ++command line starts with the keyword that identifies the command (though ++blank lines are also allowed for punctuation). If a line of an ++MRI-compatible script begins with an unrecognized keyword, @command{ld} ++issues a warning message, but continues processing the script. ++ ++Lines beginning with @samp{*} are comments. ++ ++You can write these commands using all upper-case letters, or all ++lower case; for example, @samp{chip} is the same as @samp{CHIP}. ++The following list shows only the upper-case form of each command. ++ ++@table @code ++@cindex @code{ABSOLUTE} (MRI) ++@item ABSOLUTE @var{secname} ++@itemx ABSOLUTE @var{secname}, @var{secname}, @dots{} @var{secname} ++Normally, @command{ld} includes in the output file all sections from all ++the input files. However, in an MRI-compatible script, you can use the ++@code{ABSOLUTE} command to restrict the sections that will be present in ++your output program. If the @code{ABSOLUTE} command is used at all in a ++script, then only the sections named explicitly in @code{ABSOLUTE} ++commands will appear in the linker output. You can still use other ++input sections (whatever you select on the command line, or using ++@code{LOAD}) to resolve addresses in the output file. ++ ++@cindex @code{ALIAS} (MRI) ++@item ALIAS @var{out-secname}, @var{in-secname} ++Use this command to place the data from input section @var{in-secname} ++in a section called @var{out-secname} in the linker output file. ++ ++@var{in-secname} may be an integer. ++ ++@cindex @code{ALIGN} (MRI) ++@item ALIGN @var{secname} = @var{expression} ++Align the section called @var{secname} to @var{expression}. The ++@var{expression} should be a power of two. ++ ++@cindex @code{BASE} (MRI) ++@item BASE @var{expression} ++Use the value of @var{expression} as the lowest address (other than ++absolute addresses) in the output file. ++ ++@cindex @code{CHIP} (MRI) ++@item CHIP @var{expression} ++@itemx CHIP @var{expression}, @var{expression} ++This command does nothing; it is accepted only for compatibility. ++ ++@cindex @code{END} (MRI) ++@item END ++This command does nothing whatever; it's only accepted for compatibility. ++ ++@cindex @code{FORMAT} (MRI) ++@item FORMAT @var{output-format} ++Similar to the @code{OUTPUT_FORMAT} command in the more general linker ++language, but restricted to S-records, if @var{output-format} is @samp{S} ++ ++@cindex @code{LIST} (MRI) ++@item LIST @var{anything}@dots{} ++Print (to the standard output file) a link map, as produced by the ++@command{ld} command-line option @samp{-M}. ++ ++The keyword @code{LIST} may be followed by anything on the ++same line, with no change in its effect. ++ ++@cindex @code{LOAD} (MRI) ++@item LOAD @var{filename} ++@itemx LOAD @var{filename}, @var{filename}, @dots{} @var{filename} ++Include one or more object file @var{filename} in the link; this has the ++same effect as specifying @var{filename} directly on the @command{ld} ++command line. ++ ++@cindex @code{NAME} (MRI) ++@item NAME @var{output-name} ++@var{output-name} is the name for the program produced by @command{ld}; the ++MRI-compatible command @code{NAME} is equivalent to the command-line ++option @samp{-o} or the general script language command @code{OUTPUT}. ++ ++@cindex @code{ORDER} (MRI) ++@item ORDER @var{secname}, @var{secname}, @dots{} @var{secname} ++@itemx ORDER @var{secname} @var{secname} @var{secname} ++Normally, @command{ld} orders the sections in its output file in the ++order in which they first appear in the input files. In an MRI-compatible ++script, you can override this ordering with the @code{ORDER} command. The ++sections you list with @code{ORDER} will appear first in your output ++file, in the order specified. ++ ++@cindex @code{PUBLIC} (MRI) ++@item PUBLIC @var{name}=@var{expression} ++@itemx PUBLIC @var{name},@var{expression} ++@itemx PUBLIC @var{name} @var{expression} ++Supply a value (@var{expression}) for external symbol ++@var{name} used in the linker input files. ++ ++@cindex @code{SECT} (MRI) ++@item SECT @var{secname}, @var{expression} ++@itemx SECT @var{secname}=@var{expression} ++@itemx SECT @var{secname} @var{expression} ++You can use any of these three forms of the @code{SECT} command to ++specify the start address (@var{expression}) for section @var{secname}. ++If you have more than one @code{SECT} statement for the same ++@var{secname}, only the @emph{first} sets the start address. ++@end table ++ ++@node GNU Free Documentation License ++@appendix GNU Free Documentation License ++@include fdl.texi ++ ++@node LD Index ++@unnumbered LD Index ++ ++@printindex cp ++ ++@tex ++% I think something like @@colophon should be in texinfo. In the ++% meantime: ++\long\def\colophon{\hbox to0pt{}\vfill ++\centerline{The body of this manual is set in} ++\centerline{\fontname\tenrm,} ++\centerline{with headings in {\bf\fontname\tenbf}} ++\centerline{and examples in {\tt\fontname\tentt}.} ++\centerline{{\it\fontname\tenit\/} and} ++\centerline{{\sl\fontname\tensl\/}} ++\centerline{are used for emphasis.}\vfill} ++\page\colophon ++% Blame: doc@@cygnus.com, 28mar91. ++@end tex ++ ++@bye +diff -rupN binutils.orig/ld/ldfile.c binutils-2.41/ld/ldfile.c +--- binutils.orig/ld/ldfile.c 2024-05-13 13:03:47.800601771 +0100 ++++ binutils-2.41/ld/ldfile.c 2024-05-13 13:04:08.595633300 +0100 +@@ -868,19 +868,7 @@ ldfile_find_command_file (const char *na + return result; + } + +-enum script_open_style { +- script_nonT, +- script_T, +- script_defaultT +-}; +- +-struct script_name_list +-{ +- struct script_name_list *next; +- enum script_open_style open_how; +- char name[1]; +-}; +- ++struct script_name_list *processed_scripts = NULL; + /* Open command file NAME. */ + + static void +@@ -888,7 +876,6 @@ ldfile_open_command_file_1 (const char * + { + FILE *ldlex_input_stack; + bool sysrooted; +- static struct script_name_list *processed_scripts = NULL; + struct script_name_list *script; + size_t len; + +diff -rupN binutils.orig/ld/ldfile.c.orig binutils-2.41/ld/ldfile.c.orig +--- binutils.orig/ld/ldfile.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ldfile.c.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,998 @@ ++/* Linker file opening and searching. ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdlink.h" ++#include "ctf-api.h" ++#include "safe-ctype.h" ++#include "ld.h" ++#include "ldmisc.h" ++#include "ldexp.h" ++#include "ldlang.h" ++#include "ldfile.h" ++#include "ldmain.h" ++#include ++#include "ldlex.h" ++#include "ldemul.h" ++#include "libiberty.h" ++#include "filenames.h" ++#include ++#if BFD_SUPPORTS_PLUGINS ++#include "plugin-api.h" ++#include "plugin.h" ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ ++bool ldfile_assumed_script = false; ++const char *ldfile_output_machine_name = ""; ++unsigned long ldfile_output_machine; ++enum bfd_architecture ldfile_output_architecture; ++search_dirs_type *search_head; ++ ++#ifdef VMS ++static char *slash = ""; ++#else ++#if defined (_WIN32) && !defined (__CYGWIN32__) ++static char *slash = "\\"; ++#else ++static char *slash = "/"; ++#endif ++#endif ++ ++typedef struct search_arch ++{ ++ char *name; ++ struct search_arch *next; ++} search_arch_type; ++ ++static search_dirs_type **search_tail_ptr = &search_head; ++static search_arch_type *search_arch_head; ++static search_arch_type **search_arch_tail_ptr = &search_arch_head; ++ ++typedef struct input_remap ++{ ++ const char * pattern; /* Pattern to match input files. */ ++ const char * renamed; /* Filename to use if the pattern matches. */ ++ struct input_remap * next; /* Link in a chain of these structures. */ ++} input_remap; ++ ++static struct input_remap * input_remaps = NULL; ++ ++void ++ldfile_add_remap (const char * pattern, const char * renamed) ++{ ++ struct input_remap * new_entry; ++ ++ new_entry = xmalloc (sizeof * new_entry); ++ new_entry->pattern = xstrdup (pattern); ++ new_entry->next = NULL; ++ ++ /* Look for special filenames that mean that the input file should be ignored. */ ++ if (strcmp (renamed, "/dev/null") == 0 ++ || strcmp (renamed, "NUL") == 0) ++ new_entry->renamed = NULL; ++ else ++ /* FIXME: Should we add sanity checking of the 'renamed' string ? */ ++ new_entry->renamed = xstrdup (renamed); ++ ++ /* It would be easier to add this new node at the start of the chain, ++ but users expect that remapping will occur in the order in which ++ they occur on the command line, and in the remapping files. */ ++ if (input_remaps == NULL) ++ { ++ input_remaps = new_entry; ++ } ++ else ++ { ++ struct input_remap * i; ++ ++ for (i = input_remaps; i->next != NULL; i = i->next) ++ ; ++ i->next = new_entry; ++ } ++} ++ ++void ++ldfile_remap_input_free (void) ++{ ++ while (input_remaps != NULL) ++ { ++ struct input_remap * i = input_remaps; ++ ++ input_remaps = i->next; ++ free ((void *) i->pattern); ++ free ((void *) i->renamed); ++ free (i); ++ } ++} ++ ++bool ++ldfile_add_remap_file (const char * file) ++{ ++ FILE * f; ++ ++ f = fopen (file, FOPEN_RT); ++ if (f == NULL) ++ return false; ++ ++ size_t linelen = 256; ++ char * line = xmalloc (linelen); ++ ++ do ++ { ++ char * p = line; ++ char * q; ++ ++ /* Normally this would use getline(3), but we need to be portable. */ ++ while ((q = fgets (p, linelen - (p - line), f)) != NULL ++ && strlen (q) == linelen - (p - line) - 1 ++ && line[linelen - 2] != '\n') ++ { ++ line = xrealloc (line, 2 * linelen); ++ p = line + linelen - 1; ++ linelen += linelen; ++ } ++ ++ if (q == NULL && p == line) ++ break; ++ ++ p = strchr (line, '\n'); ++ if (p) ++ *p = '\0'; ++ ++ /* Because the file format does not know any form of quoting we ++ can search forward for the next '#' character and if found ++ make it terminating the line. */ ++ p = strchr (line, '#'); ++ if (p) ++ *p = '\0'; ++ ++ /* Remove leading whitespace. NUL is no whitespace character. */ ++ p = line; ++ while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v') ++ ++p; ++ ++ /* If the line is blank it is ignored. */ ++ if (*p == '\0') ++ continue; ++ ++ char * pattern = p; ++ ++ /* Advance past the pattern. We accept whitespace or '=' as an ++ end-of-pattern marker. */ ++ while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f' ++ && *p != '\r' && *p != '\v') ++ ++p; ++ ++ if (*p == '\0') ++ { ++ einfo ("%F%P: malformed remap file entry: %s\n", line); ++ continue; ++ } ++ ++ * p++ = '\0'; ++ ++ /* Skip whitespace again. */ ++ while (*p == ' ' || *p == '\f' || *p == '\r' || *p == '\t' || *p == '\v') ++ ++p; ++ ++ if (*p == '\0') ++ { ++ einfo ("%F%P: malformed remap file entry: %s\n", line); ++ continue; ++ } ++ ++ char * renamed = p; ++ ++ /* Advance past the rename entry. */ ++ while (*p && *p != '=' && *p != ' ' && *p != '\t' && *p != '\f' ++ && *p != '\r' && *p != '\v') ++ ++p; ++ /* And terminate it. */ ++ *p = '\0'; ++ ++ ldfile_add_remap (pattern, renamed); ++ } ++ while (! feof (f)); ++ ++ free (line); ++ fclose (f); ++ ++ return true; ++} ++ ++const char * ++ldfile_possibly_remap_input (const char * filename) ++{ ++ struct input_remap * i; ++ ++ if (filename == NULL) ++ return NULL; ++ ++ for (i = input_remaps; i != NULL; i = i->next) ++ { ++ if (fnmatch (i->pattern, filename, 0) == 0) ++ { ++ if (verbose) ++ { ++ if (strpbrk ((i->pattern), "?*[") != NULL) ++ { ++ if (i->renamed) ++ info_msg (_("remap input file '%s' to '%s' based upon pattern '%s'\n"), ++ filename, i->renamed, i->pattern); ++ else ++ info_msg (_("remove input file '%s' based upon pattern '%s'\n"), ++ filename, i->pattern); ++ } ++ else ++ { ++ if (i->renamed) ++ info_msg (_("remap input file '%s' to '%s'\n"), ++ filename, i->renamed); ++ else ++ info_msg (_("remove input file '%s'\n"), ++ filename); ++ } ++ } ++ ++ return i->renamed; ++ } ++ } ++ ++ return filename; ++} ++ ++void ++ldfile_print_input_remaps (void) ++{ ++ if (input_remaps == NULL) ++ return; ++ ++ minfo (_("\nInput File Remapping\n\n")); ++ ++ struct input_remap * i; ++ ++ for (i = input_remaps; i != NULL; i = i->next) ++ minfo (_(" Pattern: %s\tMaps To: %s\n"), i->pattern, ++ i->renamed ? i->renamed : _("")); ++} ++ ++ ++/* Test whether a pathname, after canonicalization, is the same or a ++ sub-directory of the sysroot directory. */ ++ ++static bool ++is_sysrooted_pathname (const char *name) ++{ ++ char *realname; ++ int len; ++ bool result; ++ ++ if (ld_canon_sysroot == NULL) ++ return false; ++ ++ realname = lrealpath (name); ++ len = strlen (realname); ++ result = false; ++ if (len > ld_canon_sysroot_len ++ && IS_DIR_SEPARATOR (realname[ld_canon_sysroot_len])) ++ { ++ realname[ld_canon_sysroot_len] = '\0'; ++ result = FILENAME_CMP (ld_canon_sysroot, realname) == 0; ++ } ++ ++ free (realname); ++ return result; ++} ++ ++/* Adds NAME to the library search path. ++ Makes a copy of NAME using xmalloc(). */ ++ ++void ++ldfile_add_library_path (const char *name, bool cmdline) ++{ ++ search_dirs_type *new_dirs; ++ ++ if (!cmdline && config.only_cmd_line_lib_dirs) ++ return; ++ ++ new_dirs = (search_dirs_type *) xmalloc (sizeof (search_dirs_type)); ++ new_dirs->next = NULL; ++ new_dirs->cmdline = cmdline; ++ *search_tail_ptr = new_dirs; ++ search_tail_ptr = &new_dirs->next; ++ ++ /* If a directory is marked as honoring sysroot, prepend the sysroot path ++ now. */ ++ if (name[0] == '=') ++ new_dirs->name = concat (ld_sysroot, name + 1, (const char *) NULL); ++ else if (startswith (name, "$SYSROOT")) ++ new_dirs->name = concat (ld_sysroot, name + strlen ("$SYSROOT"), (const char *) NULL); ++ else ++ new_dirs->name = xstrdup (name); ++} ++ ++/* Try to open a BFD for a lang_input_statement. */ ++ ++bool ++ldfile_try_open_bfd (const char *attempt, ++ lang_input_statement_type *entry) ++{ ++ entry->the_bfd = bfd_openr (attempt, entry->target); ++ ++ if (verbose) ++ { ++ if (entry->the_bfd == NULL) ++ info_msg (_("attempt to open %s failed\n"), attempt); ++ else ++ info_msg (_("attempt to open %s succeeded\n"), attempt); ++ } ++ ++ if (entry->the_bfd == NULL) ++ { ++ if (bfd_get_error () == bfd_error_invalid_target) ++ einfo (_("%F%P: invalid BFD target `%s'\n"), entry->target); ++ return false; ++ } ++ ++ /* PR 30568: Do not track lto generated temporary object files. */ ++#if BFD_SUPPORTS_PLUGINS ++ if (!entry->flags.lto_output) ++#endif ++ track_dependency_files (attempt); ++ ++ /* Linker needs to decompress sections. */ ++ entry->the_bfd->flags |= BFD_DECOMPRESS; ++ ++ /* This is a linker input BFD. */ ++ entry->the_bfd->is_linker_input = 1; ++ ++#if BFD_SUPPORTS_PLUGINS ++ if (entry->flags.lto_output) ++ entry->the_bfd->lto_output = 1; ++#endif ++ ++ /* If we are searching for this file, see if the architecture is ++ compatible with the output file. If it isn't, keep searching. ++ If we can't open the file as an object file, stop the search ++ here. If we are statically linking, ensure that we don't link ++ a dynamic object. ++ ++ In the code below, it's OK to exit early if the check fails, ++ closing the checked BFD and returning false, but if the BFD ++ checks out compatible, do not exit early returning true, or ++ the plugins will not get a chance to claim the file. */ ++ ++ if (entry->flags.search_dirs || !entry->flags.dynamic) ++ { ++ bfd *check; ++ ++ if (bfd_check_format (entry->the_bfd, bfd_archive)) ++ check = bfd_openr_next_archived_file (entry->the_bfd, NULL); ++ else ++ check = entry->the_bfd; ++ ++ if (check != NULL) ++ { ++ if (!bfd_check_format (check, bfd_object)) ++ { ++ if (check == entry->the_bfd ++ && entry->flags.search_dirs ++ && bfd_get_error () == bfd_error_file_not_recognized ++ && !ldemul_unrecognized_file (entry)) ++ { ++ int token, skip = 0; ++ char *arg, *arg1, *arg2, *arg3; ++ extern FILE *yyin; ++ ++ /* Try to interpret the file as a linker script. */ ++ ldfile_open_command_file (attempt); ++ ++ ldfile_assumed_script = true; ++ parser_input = input_selected; ++ ldlex_script (); ++ token = INPUT_SCRIPT; ++ while (token != 0) ++ { ++ switch (token) ++ { ++ case OUTPUT_FORMAT: ++ if ((token = yylex ()) != '(') ++ continue; ++ if ((token = yylex ()) != NAME) ++ continue; ++ arg1 = yylval.name; ++ arg2 = NULL; ++ arg3 = NULL; ++ token = yylex (); ++ if (token == ',') ++ { ++ if ((token = yylex ()) != NAME) ++ { ++ free (arg1); ++ continue; ++ } ++ arg2 = yylval.name; ++ if ((token = yylex ()) != ',' ++ || (token = yylex ()) != NAME) ++ { ++ free (arg1); ++ free (arg2); ++ continue; ++ } ++ arg3 = yylval.name; ++ token = yylex (); ++ } ++ if (token == ')') ++ { ++ switch (command_line.endian) ++ { ++ default: ++ case ENDIAN_UNSET: ++ arg = arg1; break; ++ case ENDIAN_BIG: ++ arg = arg2 ? arg2 : arg1; break; ++ case ENDIAN_LITTLE: ++ arg = arg3 ? arg3 : arg1; break; ++ } ++ if (strcmp (arg, lang_get_output_target ()) != 0) ++ skip = 1; ++ } ++ free (arg1); ++ free (arg2); ++ free (arg3); ++ break; ++ case NAME: ++ case LNAME: ++ case VERS_IDENTIFIER: ++ case VERS_TAG: ++ free (yylval.name); ++ break; ++ case INT: ++ free (yylval.bigint.str); ++ break; ++ } ++ token = yylex (); ++ } ++ ldlex_popstate (); ++ ldfile_assumed_script = false; ++ fclose (yyin); ++ yyin = NULL; ++ if (skip) ++ { ++ if (command_line.warn_search_mismatch) ++ einfo (_("%P: skipping incompatible %s " ++ "when searching for %s\n"), ++ attempt, entry->local_sym_name); ++ bfd_close (entry->the_bfd); ++ entry->the_bfd = NULL; ++ return false; ++ } ++ } ++ goto success; ++ } ++ ++ if (!entry->flags.dynamic && (entry->the_bfd->flags & DYNAMIC) != 0) ++ { ++ einfo (_("%F%P: attempted static link of dynamic object `%s'\n"), ++ attempt); ++ bfd_close (entry->the_bfd); ++ entry->the_bfd = NULL; ++ return false; ++ } ++ ++ if (entry->flags.search_dirs ++ && !bfd_arch_get_compatible (check, link_info.output_bfd, ++ command_line.accept_unknown_input_arch) ++ /* XCOFF archives can have 32 and 64 bit objects. */ ++ && !(bfd_get_flavour (check) == bfd_target_xcoff_flavour ++ && (bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_xcoff_flavour) ++ && bfd_check_format (entry->the_bfd, bfd_archive))) ++ { ++ if (command_line.warn_search_mismatch) ++ einfo (_("%P: skipping incompatible %s " ++ "when searching for %s\n"), ++ attempt, entry->local_sym_name); ++ bfd_close (entry->the_bfd); ++ entry->the_bfd = NULL; ++ return false; ++ } ++ } ++ } ++ success: ++#if BFD_SUPPORTS_PLUGINS ++ /* If plugins are active, they get first chance to claim ++ any successfully-opened input file. We skip archives ++ here; the plugin wants us to offer it the individual ++ members when we enumerate them, not the whole file. We ++ also ignore corefiles, because that's just weird. It is ++ a needed side-effect of calling bfd_check_format with ++ bfd_object that it sets the bfd's arch and mach, which ++ will be needed when and if we want to bfd_create a new ++ one using this one as a template. */ ++ if (link_info.lto_plugin_active ++ && !no_more_claiming ++ && bfd_check_format (entry->the_bfd, bfd_object)) ++ plugin_maybe_claim (entry); ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ ++ /* It opened OK, the format checked out, and the plugins have had ++ their chance to claim it, so this is success. */ ++ return true; ++} ++ ++/* Search for and open the file specified by ENTRY. If it is an ++ archive, use ARCH, LIB and SUFFIX to modify the file name. */ ++ ++bool ++ldfile_open_file_search (const char *arch, ++ lang_input_statement_type *entry, ++ const char *lib, ++ const char *suffix) ++{ ++ search_dirs_type *search; ++ ++ /* If this is not an archive, try to open it in the current ++ directory first. */ ++ if (!entry->flags.maybe_archive) ++ { ++ if (entry->flags.sysrooted && IS_ABSOLUTE_PATH (entry->filename)) ++ { ++ char *name = concat (ld_sysroot, entry->filename, ++ (const char *) NULL); ++ if (ldfile_try_open_bfd (name, entry)) ++ { ++ entry->filename = name; ++ return true; ++ } ++ free (name); ++ } ++ else if (ldfile_try_open_bfd (entry->filename, entry)) ++ return true; ++ ++ if (IS_ABSOLUTE_PATH (entry->filename)) ++ return false; ++ } ++ ++ for (search = search_head; search != NULL; search = search->next) ++ { ++ char *string; ++ ++ if (entry->flags.dynamic && !bfd_link_relocatable (&link_info)) ++ { ++ if (ldemul_open_dynamic_archive (arch, search, entry)) ++ return true; ++ } ++ ++ if (entry->flags.maybe_archive && !entry->flags.full_name_provided) ++ string = concat (search->name, slash, lib, entry->filename, ++ arch, suffix, (const char *) NULL); ++ else ++ string = concat (search->name, slash, entry->filename, ++ (const char *) 0); ++ ++ if (ldfile_try_open_bfd (string, entry)) ++ { ++ entry->filename = string; ++ return true; ++ } ++ ++ free (string); ++ } ++ ++ return false; ++} ++ ++/* Open the input file specified by ENTRY. ++ PR 4437: Do not stop on the first missing file, but ++ continue processing other input files in case there ++ are more errors to report. */ ++ ++void ++ldfile_open_file (lang_input_statement_type *entry) ++{ ++ if (entry->the_bfd != NULL) ++ return; ++ ++ if (!entry->flags.search_dirs) ++ { ++ if (ldfile_try_open_bfd (entry->filename, entry)) ++ return; ++ ++ if (filename_cmp (entry->filename, entry->local_sym_name) != 0) ++ einfo (_("%P: cannot find %s (%s): %E\n"), ++ entry->filename, entry->local_sym_name); ++ else ++ einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name); ++ ++ entry->flags.missing_file = true; ++ input_flags.missing_file = true; ++ } ++ else ++ { ++ search_arch_type *arch; ++ bool found = false; ++ ++ /* If extra_search_path is set, entry->filename is a relative path. ++ Search the directory of the current linker script before searching ++ other paths. */ ++ if (entry->extra_search_path) ++ { ++ char *path = concat (entry->extra_search_path, slash, entry->filename, ++ (const char *)0); ++ if (ldfile_try_open_bfd (path, entry)) ++ { ++ entry->filename = path; ++ entry->flags.search_dirs = false; ++ return; ++ } ++ ++ free (path); ++ } ++ ++ /* Try to open or lib.a. */ ++ for (arch = search_arch_head; arch != NULL; arch = arch->next) ++ { ++ found = ldfile_open_file_search (arch->name, entry, "lib", ".a"); ++ if (found) ++ break; ++#ifdef VMS ++ found = ldfile_open_file_search (arch->name, entry, ":lib", ".a"); ++ if (found) ++ break; ++#endif ++ found = ldemul_find_potential_libraries (arch->name, entry); ++ if (found) ++ break; ++ } ++ ++ /* If we have found the file, we don't need to search directories ++ again. */ ++ if (found) ++ entry->flags.search_dirs = false; ++ else ++ { ++ if (entry->flags.sysrooted ++ && ld_sysroot ++ && IS_ABSOLUTE_PATH (entry->local_sym_name)) ++ einfo (_("%P: cannot find %s inside %s\n"), ++ entry->local_sym_name, ld_sysroot); ++#if SUPPORT_ERROR_HANDLING_SCRIPT ++ else if (error_handling_script != NULL) ++ { ++ char * argv[4]; ++ const char * res; ++ int status, err; ++ ++ argv[0] = error_handling_script; ++ argv[1] = "missing-lib"; ++ argv[2] = (char *) entry->local_sym_name; ++ argv[3] = NULL; ++ ++ if (verbose) ++ einfo (_("%P: About to run error handling script '%s' with arguments: '%s' '%s'\n"), ++ argv[0], argv[1], argv[2]); ++ ++ res = pex_one (PEX_SEARCH, error_handling_script, argv, ++ N_("error handling script"), ++ NULL /* Send stdout to random, temp file. */, ++ NULL /* Write to stderr. */, ++ &status, &err); ++ if (res != NULL) ++ { ++ einfo (_("%P: Failed to run error handling script '%s', reason: "), ++ error_handling_script); ++ /* FIXME: We assume here that errrno == err. */ ++ perror (res); ++ } ++ else /* We ignore the return status of the script ++ and always print the error message. */ ++ einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name); ++ } ++#endif ++ else ++ einfo (_("%P: cannot find %s: %E\n"), entry->local_sym_name); ++ ++ /* PR 25747: Be kind to users who forgot to add the ++ "lib" prefix to their library when it was created. */ ++ for (arch = search_arch_head; arch != NULL; arch = arch->next) ++ { ++ if (ldfile_open_file_search (arch->name, entry, "", ".a")) ++ { ++ const char * base = lbasename (entry->filename); ++ ++ einfo (_("%P: note to link with %s use -l:%s or rename it to lib%s\n"), ++ entry->filename, base, base); ++ bfd_close (entry->the_bfd); ++ entry->the_bfd = NULL; ++ break; ++ } ++ } ++ ++ entry->flags.missing_file = true; ++ input_flags.missing_file = true; ++ } ++ } ++} ++ ++/* Try to open NAME. */ ++ ++static FILE * ++try_open (const char *name, bool *sysrooted) ++{ ++ FILE *result; ++ ++ result = fopen (name, "r"); ++ ++ if (result != NULL) ++ *sysrooted = is_sysrooted_pathname (name); ++ ++ if (verbose) ++ { ++ if (result == NULL) ++ info_msg (_("cannot find script file %s\n"), name); ++ else ++ info_msg (_("opened script file %s\n"), name); ++ } ++ ++ return result; ++} ++ ++/* Return TRUE iff directory DIR contains an "ldscripts" subdirectory. */ ++ ++static bool ++check_for_scripts_dir (char *dir) ++{ ++ char *buf; ++ struct stat s; ++ bool res; ++ ++ buf = concat (dir, "/ldscripts", (const char *) NULL); ++ res = stat (buf, &s) == 0 && S_ISDIR (s.st_mode); ++ free (buf); ++ return res; ++} ++ ++/* Return the default directory for finding script files. ++ We look for the "ldscripts" directory in: ++ ++ SCRIPTDIR (passed from Makefile) ++ (adjusted according to the current location of the binary) ++ the dir where this program is (for using it from the build tree). */ ++ ++static char * ++find_scripts_dir (void) ++{ ++ char *dir; ++ ++ dir = make_relative_prefix (program_name, BINDIR, SCRIPTDIR); ++ if (dir) ++ { ++ if (check_for_scripts_dir (dir)) ++ return dir; ++ free (dir); ++ } ++ ++ dir = make_relative_prefix (program_name, TOOLBINDIR, SCRIPTDIR); ++ if (dir) ++ { ++ if (check_for_scripts_dir (dir)) ++ return dir; ++ free (dir); ++ } ++ ++ /* Look for "ldscripts" in the dir where our binary is. */ ++ dir = make_relative_prefix (program_name, ".", "."); ++ if (dir) ++ { ++ if (check_for_scripts_dir (dir)) ++ return dir; ++ free (dir); ++ } ++ ++ return NULL; ++} ++ ++/* If DEFAULT_ONLY is false, try to open NAME; if that fails, look for ++ it in directories specified with -L, then in the default script ++ directory. If DEFAULT_ONLY is true, the search is restricted to ++ the default script location. */ ++ ++static FILE * ++ldfile_find_command_file (const char *name, ++ bool default_only, ++ bool *sysrooted) ++{ ++ search_dirs_type *search; ++ FILE *result = NULL; ++ char *path; ++ static search_dirs_type *script_search; ++ ++ if (!default_only) ++ { ++ /* First try raw name. */ ++ result = try_open (name, sysrooted); ++ if (result != NULL) ++ return result; ++ } ++ ++ if (!script_search) ++ { ++ char *script_dir = find_scripts_dir (); ++ if (script_dir) ++ { ++ search_dirs_type **save_tail_ptr = search_tail_ptr; ++ search_tail_ptr = &script_search; ++ ldfile_add_library_path (script_dir, true); ++ search_tail_ptr = save_tail_ptr; ++ } ++ } ++ ++ /* Temporarily append script_search to the path list so that the ++ paths specified with -L will be searched first. */ ++ *search_tail_ptr = script_search; ++ ++ /* Try now prefixes. */ ++ for (search = default_only ? script_search : search_head; ++ search != NULL; ++ search = search->next) ++ { ++ path = concat (search->name, slash, name, (const char *) NULL); ++ result = try_open (path, sysrooted); ++ free (path); ++ if (result) ++ break; ++ } ++ ++ /* Restore the original path list. */ ++ *search_tail_ptr = NULL; ++ ++ return result; ++} ++ ++enum script_open_style { ++ script_nonT, ++ script_T, ++ script_defaultT ++}; ++ ++struct script_name_list ++{ ++ struct script_name_list *next; ++ enum script_open_style open_how; ++ char name[1]; ++}; ++ ++/* Open command file NAME. */ ++ ++static void ++ldfile_open_command_file_1 (const char *name, enum script_open_style open_how) ++{ ++ FILE *ldlex_input_stack; ++ bool sysrooted; ++ static struct script_name_list *processed_scripts = NULL; ++ struct script_name_list *script; ++ size_t len; ++ ++ /* PR 24576: Catch the case where the user has accidentally included ++ the same linker script twice. */ ++ for (script = processed_scripts; script != NULL; script = script->next) ++ { ++ if ((open_how != script_nonT || script->open_how != script_nonT) ++ && strcmp (name, script->name) == 0) ++ { ++ einfo (_("%F%P: error: linker script file '%s'" ++ " appears multiple times\n"), name); ++ return; ++ } ++ } ++ ++ /* FIXME: This memory is never freed, but that should not really matter. ++ It will be released when the linker exits, and it is unlikely to ever ++ be more than a few tens of bytes. */ ++ len = strlen (name); ++ script = xmalloc (sizeof (*script) + len); ++ script->next = processed_scripts; ++ script->open_how = open_how; ++ memcpy (script->name, name, len + 1); ++ processed_scripts = script; ++ ++ ldlex_input_stack = ldfile_find_command_file (name, ++ open_how == script_defaultT, ++ &sysrooted); ++ if (ldlex_input_stack == NULL) ++ { ++ bfd_set_error (bfd_error_system_call); ++ einfo (_("%F%P: cannot open linker script file %s: %E\n"), name); ++ return; ++ } ++ ++ track_dependency_files (name); ++ ++ lex_push_file (ldlex_input_stack, name, sysrooted); ++ ++ lineno = 1; ++ ++ saved_script_handle = ldlex_input_stack; ++} ++ ++/* Open command file NAME in the current directory, -L directories, ++ the default script location, in that order. */ ++ ++void ++ldfile_open_command_file (const char *name) ++{ ++ ldfile_open_command_file_1 (name, script_nonT); ++} ++ ++void ++ldfile_open_script_file (const char *name) ++{ ++ ldfile_open_command_file_1 (name, script_T); ++} ++ ++/* Open command file NAME at the default script location. */ ++ ++void ++ldfile_open_default_command_file (const char *name) ++{ ++ ldfile_open_command_file_1 (name, script_defaultT); ++} ++ ++void ++ldfile_add_arch (const char *in_name) ++{ ++ char *name = xstrdup (in_name); ++ search_arch_type *new_arch ++ = (search_arch_type *) xmalloc (sizeof (search_arch_type)); ++ ++ ldfile_output_machine_name = in_name; ++ ++ new_arch->name = name; ++ new_arch->next = NULL; ++ while (*name) ++ { ++ *name = TOLOWER (*name); ++ name++; ++ } ++ *search_arch_tail_ptr = new_arch; ++ search_arch_tail_ptr = &new_arch->next; ++ ++} ++ ++/* Set the output architecture. */ ++ ++void ++ldfile_set_output_arch (const char *string, enum bfd_architecture defarch) ++{ ++ const bfd_arch_info_type *arch = bfd_scan_arch (string); ++ ++ if (arch) ++ { ++ ldfile_output_architecture = arch->arch; ++ ldfile_output_machine = arch->mach; ++ ldfile_output_machine_name = arch->printable_name; ++ } ++ else if (defarch != bfd_arch_unknown) ++ ldfile_output_architecture = defarch; ++ else ++ einfo (_("%F%P: cannot represent machine `%s'\n"), string); ++} +diff -rupN binutils.orig/ld/ldfile.h binutils-2.41/ld/ldfile.h +--- binutils.orig/ld/ldfile.h 2024-05-13 13:03:47.801601773 +0100 ++++ binutils-2.41/ld/ldfile.h 2024-05-13 13:04:08.595633300 +0100 +@@ -29,7 +29,8 @@ extern const char *ldfile_output_machine + /* Structure used to hold the list of directories to search for + libraries. */ + +-typedef struct search_dirs { ++typedef struct search_dirs ++{ + /* Next directory on list. */ + struct search_dirs *next; + /* Name of directory. */ +@@ -38,6 +39,22 @@ typedef struct search_dirs { + bool cmdline; + } search_dirs_type; + ++enum script_open_style ++{ ++ script_nonT, ++ script_T, ++ script_defaultT ++}; ++ ++struct script_name_list ++{ ++ struct script_name_list * next; ++ enum script_open_style open_how; ++ char name[1]; ++}; ++ ++extern struct script_name_list * processed_scripts; ++ + extern search_dirs_type *search_head; + + extern void ldfile_add_arch +diff -rupN binutils.orig/ld/ldgram.y binutils-2.41/ld/ldgram.y +--- binutils.orig/ld/ldgram.y 2024-05-13 13:03:47.802601774 +0100 ++++ binutils-2.41/ld/ldgram.y 2024-05-13 13:04:08.596633302 +0100 +@@ -154,7 +154,7 @@ static int error_index; + %token LOG2CEIL FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL + %token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START + %token VERS_TAG VERS_IDENTIFIER +-%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT ++%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT INPUT_SECTION_ORDERING_SCRIPT + %token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS ALIGN_WITH_INPUT + %token EXCLUDE_FILE + %token CONSTANT +@@ -169,6 +169,7 @@ file: + INPUT_SCRIPT script_file + | INPUT_MRI_SCRIPT mri_script_file + | INPUT_VERSION_SCRIPT version_script_file ++ | INPUT_SECTION_ORDERING_SCRIPT section_ordering_script_file + | INPUT_DYNAMIC_LIST dynamic_list_file + | INPUT_DEFSYM defsym_expr + ; +@@ -1503,6 +1504,39 @@ opt_semicolon: + | ';' + ; + ++section_ordering_script_file: ++ { ++ ldlex_script (); ++ PUSH_ERROR (_("section-ordering-file script")); ++ } ++ section_ordering_list ++ { ++ ldlex_popstate (); ++ POP_ERROR (); ++ } ++ ; ++ ++section_ordering_list: ++ section_ordering_list section_order ++ | section_ordering_list statement_anywhere ++ | ++ ; ++ ++section_order: NAME ':' ++ { ++ ldlex_wild (); ++ lang_enter_output_section_statement ++ ($1, NULL, 0, NULL, NULL, NULL, NULL, 0, 0); ++ } ++ '{' ++ statement_list_opt ++ '}' ++ { ++ ldlex_popstate (); ++ lang_leave_output_section_statement (NULL, NULL, NULL, NULL); ++ } ++ opt_comma ++ + %% + void + yyerror(arg) +diff -rupN binutils.orig/ld/ldgram.y.orig binutils-2.41/ld/ldgram.y.orig +--- binutils.orig/ld/ldgram.y.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ldgram.y.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,1518 @@ ++/* A YACC grammar to parse a superset of the AT&T linker scripting language. ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ Written by Steve Chamberlain of Cygnus Support (steve@cygnus.com). ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++%{ ++/* ++ ++ */ ++ ++#define DONTDECLARE_MALLOC ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdlink.h" ++#include "ctf-api.h" ++#include "ld.h" ++#include "ldexp.h" ++#include "ldver.h" ++#include "ldlang.h" ++#include "ldfile.h" ++#include "ldemul.h" ++#include "ldmisc.h" ++#include "ldmain.h" ++#include "mri.h" ++#include "ldctor.h" ++#include "ldlex.h" ++ ++#ifndef YYDEBUG ++#define YYDEBUG 1 ++#endif ++ ++static enum section_type sectype; ++static etree_type *sectype_value; ++static lang_memory_region_type *region; ++ ++static bool ldgram_had_keep = false; ++static char *ldgram_vers_current_lang = NULL; ++ ++#define ERROR_NAME_MAX 20 ++static char *error_names[ERROR_NAME_MAX]; ++static int error_index; ++#define PUSH_ERROR(x) if (error_index < ERROR_NAME_MAX) error_names[error_index] = x; error_index++; ++#define POP_ERROR() error_index--; ++%} ++%union { ++ bfd_vma integer; ++ struct big_int ++ { ++ bfd_vma integer; ++ char *str; ++ } bigint; ++ fill_type *fill; ++ char *name; ++ const char *cname; ++ struct wildcard_spec wildcard; ++ struct wildcard_list *wildcard_list; ++ struct name_list *name_list; ++ struct flag_info_list *flag_info_list; ++ struct flag_info *flag_info; ++ int token; ++ union etree_union *etree; ++ struct phdr_info ++ { ++ bool filehdr; ++ bool phdrs; ++ union etree_union *at; ++ union etree_union *flags; ++ } phdr; ++ struct lang_nocrossref *nocrossref; ++ struct lang_output_section_phdr_list *section_phdr; ++ struct bfd_elf_version_deps *deflist; ++ struct bfd_elf_version_expr *versyms; ++ struct bfd_elf_version_tree *versnode; ++} ++ ++%type exp opt_exp_with_type mustbe_exp opt_at phdr_type phdr_val ++%type opt_exp_without_type opt_subalign opt_align ++%type fill_opt fill_exp ++%type exclude_name_list ++%type section_name_list ++%type sect_flag_list ++%type sect_flags ++%type memspec_opt memspec_at_opt paren_script_name casesymlist ++%type wildcard_name ++%type section_name_spec filename_spec wildcard_maybe_exclude ++%token INT ++%token NAME LNAME ++%type length ++%type phdr_qualifiers ++%type nocrossref_list ++%type phdr_opt ++%type opt_nocrossrefs ++ ++%right PLUSEQ MINUSEQ MULTEQ DIVEQ '=' LSHIFTEQ RSHIFTEQ ANDEQ OREQ ++%right '?' ':' ++%left OROR ++%left ANDAND ++%left '|' ++%left '^' ++%left '&' ++%left EQ NE ++%left '<' '>' LE GE ++%left LSHIFT RSHIFT ++ ++%left '+' '-' ++%left '*' '/' '%' ++ ++%right UNARY ++%token END ++%left '(' ++%token ALIGN_K BLOCK BIND QUAD SQUAD LONG SHORT BYTE ASCIZ ++%token SECTIONS PHDRS INSERT_K AFTER BEFORE LINKER_VERSION ++%token DATA_SEGMENT_ALIGN DATA_SEGMENT_RELRO_END DATA_SEGMENT_END ++%token SORT_BY_NAME SORT_BY_ALIGNMENT SORT_NONE ++%token SORT_BY_INIT_PRIORITY ++%token '{' '}' ++%token SIZEOF_HEADERS OUTPUT_FORMAT FORCE_COMMON_ALLOCATION OUTPUT_ARCH ++%token INHIBIT_COMMON_ALLOCATION FORCE_GROUP_ALLOCATION ++%token SEGMENT_START ++%token INCLUDE ++%token MEMORY ++%token REGION_ALIAS ++%token LD_FEATURE ++%token NOLOAD DSECT COPY INFO OVERLAY ++%token READONLY ++%token TYPE ++%token DEFINED TARGET_K SEARCH_DIR MAP ENTRY ++%token NEXT ++%token SIZEOF ALIGNOF ADDR LOADADDR MAX_K MIN_K ++%token STARTUP HLL SYSLIB FLOAT NOFLOAT NOCROSSREFS NOCROSSREFS_TO ++%token ORIGIN FILL ++%token LENGTH CREATE_OBJECT_SYMBOLS INPUT GROUP OUTPUT CONSTRUCTORS ++%token ALIGNMOD AT SUBALIGN HIDDEN PROVIDE PROVIDE_HIDDEN AS_NEEDED ++%type assign_op atype attributes_opt sect_constraint opt_align_with_input ++%type filename ++%token CHIP LIST SECT ABSOLUTE LOAD NEWLINE ENDWORD ORDER NAMEWORD ASSERT_K ++%token LOG2CEIL FORMAT PUBLIC DEFSYMEND BASE ALIAS TRUNCATE REL ++%token INPUT_SCRIPT INPUT_MRI_SCRIPT INPUT_DEFSYM CASE EXTERN START ++%token VERS_TAG VERS_IDENTIFIER ++%token GLOBAL LOCAL VERSIONK INPUT_VERSION_SCRIPT ++%token KEEP ONLY_IF_RO ONLY_IF_RW SPECIAL INPUT_SECTION_FLAGS ALIGN_WITH_INPUT ++%token EXCLUDE_FILE ++%token CONSTANT ++%type vers_defns ++%type vers_tag ++%type verdep ++%token INPUT_DYNAMIC_LIST ++ ++%% ++ ++file: ++ INPUT_SCRIPT script_file ++ | INPUT_MRI_SCRIPT mri_script_file ++ | INPUT_VERSION_SCRIPT version_script_file ++ | INPUT_DYNAMIC_LIST dynamic_list_file ++ | INPUT_DEFSYM defsym_expr ++ ; ++ ++ ++filename: NAME; ++ ++ ++defsym_expr: ++ { ldlex_expression(); } ++ assignment ++ { ldlex_popstate(); } ++ ; ++ ++/* SYNTAX WITHIN AN MRI SCRIPT FILE */ ++mri_script_file: ++ { ++ ldlex_mri_script (); ++ PUSH_ERROR (_("MRI style script")); ++ } ++ mri_script_lines ++ { ++ ldlex_popstate (); ++ mri_draw_tree (); ++ POP_ERROR (); ++ } ++ ; ++ ++mri_script_lines: ++ mri_script_lines mri_script_command NEWLINE ++ | ++ ; ++ ++mri_script_command: ++ CHIP exp ++ | CHIP exp ',' exp ++ | NAME { ++ einfo(_("%F%P: unrecognised keyword in MRI style script '%s'\n"),$1); ++ } ++ | LIST { ++ config.map_filename = "-"; ++ } ++ | ORDER ordernamelist ++ | ENDWORD ++ | PUBLIC NAME '=' exp ++ { mri_public($2, $4); } ++ | PUBLIC NAME ',' exp ++ { mri_public($2, $4); } ++ | PUBLIC NAME exp ++ { mri_public($2, $3); } ++ | FORMAT NAME ++ { mri_format($2); } ++ | SECT NAME ',' exp ++ { mri_output_section($2, $4);} ++ | SECT NAME exp ++ { mri_output_section($2, $3);} ++ | SECT NAME '=' exp ++ { mri_output_section($2, $4);} ++ | ALIGN_K NAME '=' exp ++ { mri_align($2,$4); } ++ | ALIGN_K NAME ',' exp ++ { mri_align($2,$4); } ++ | ALIGNMOD NAME '=' exp ++ { mri_alignmod($2,$4); } ++ | ALIGNMOD NAME ',' exp ++ { mri_alignmod($2,$4); } ++ | ABSOLUTE mri_abs_name_list ++ | LOAD mri_load_name_list ++ | NAMEWORD NAME ++ { mri_name($2); } ++ | ALIAS NAME ',' NAME ++ { mri_alias($2,$4,0);} ++ | ALIAS NAME ',' INT ++ { mri_alias ($2, 0, (int) $4.integer); } ++ | BASE exp ++ { mri_base($2); } ++ | TRUNCATE INT ++ { mri_truncate ((unsigned int) $2.integer); } ++ | CASE casesymlist ++ | EXTERN extern_name_list ++ | INCLUDE filename ++ { ldfile_open_command_file ($2); } ++ mri_script_lines END ++ | START NAME ++ { lang_add_entry ($2, false); } ++ | ++ ; ++ ++ordernamelist: ++ ordernamelist ',' NAME { mri_order($3); } ++ | ordernamelist NAME { mri_order($2); } ++ | ++ ; ++ ++mri_load_name_list: ++ NAME ++ { mri_load($1); } ++ | mri_load_name_list ',' NAME { mri_load($3); } ++ ; ++ ++mri_abs_name_list: ++ NAME ++ { mri_only_load($1); } ++ | mri_abs_name_list ',' NAME ++ { mri_only_load($3); } ++ ; ++ ++casesymlist: ++ /* empty */ { $$ = NULL; } ++ | NAME ++ | casesymlist ',' NAME ++ ; ++ ++extern_name_list: ++ NAME ++ { ldlang_add_undef ($1, false); } ++ | extern_name_list NAME ++ { ldlang_add_undef ($2, false); } ++ | extern_name_list ',' NAME ++ { ldlang_add_undef ($3, false); } ++ ; ++ ++script_file: ++ { ldlex_script (); } ++ ifile_list ++ { ldlex_popstate (); } ++ ; ++ ++ifile_list: ++ ifile_list ifile_p1 ++ | ++ ; ++ ++ ++ifile_p1: ++ memory ++ | sections ++ | phdrs ++ | startup ++ | high_level_library ++ | low_level_library ++ | floating_point_support ++ | statement_anywhere ++ | version ++ | ';' ++ | TARGET_K '(' NAME ')' ++ { lang_add_target($3); } ++ | SEARCH_DIR '(' filename ')' ++ { ldfile_add_library_path ($3, false); } ++ | OUTPUT '(' filename ')' ++ { lang_add_output($3, 1); } ++ | OUTPUT_FORMAT '(' NAME ')' ++ { lang_add_output_format ($3, (char *) NULL, ++ (char *) NULL, 1); } ++ | OUTPUT_FORMAT '(' NAME ',' NAME ',' NAME ')' ++ { lang_add_output_format ($3, $5, $7, 1); } ++ | OUTPUT_ARCH '(' NAME ')' ++ { ldfile_set_output_arch ($3, bfd_arch_unknown); } ++ | FORCE_COMMON_ALLOCATION ++ { command_line.force_common_definition = true ; } ++ | FORCE_GROUP_ALLOCATION ++ { command_line.force_group_allocation = true ; } ++ | INHIBIT_COMMON_ALLOCATION ++ { link_info.inhibit_common_definition = true ; } ++ | INPUT '(' input_list ')' ++ | GROUP ++ { lang_enter_group (); } ++ '(' input_list ')' ++ { lang_leave_group (); } ++ | MAP '(' filename ')' ++ { lang_add_map($3); } ++ | INCLUDE filename ++ { ldfile_open_command_file ($2); } ++ ifile_list END ++ | NOCROSSREFS '(' nocrossref_list ')' ++ { ++ lang_add_nocrossref ($3); ++ } ++ | NOCROSSREFS_TO '(' nocrossref_list ')' ++ { ++ lang_add_nocrossref_to ($3); ++ } ++ | EXTERN '(' { ldlex_expression (); } extern_name_list ')' ++ { ldlex_popstate (); } ++ | INSERT_K AFTER NAME ++ { lang_add_insert ($3, 0); } ++ | INSERT_K BEFORE NAME ++ { lang_add_insert ($3, 1); } ++ | REGION_ALIAS '(' NAME ',' NAME ')' ++ { lang_memory_region_alias ($3, $5); } ++ | LD_FEATURE '(' NAME ')' ++ { lang_ld_feature ($3); } ++ ; ++ ++input_list: ++ { ldlex_inputlist(); } ++ input_list1 ++ { ldlex_popstate(); } ++ ++input_list1: ++ NAME ++ { lang_add_input_file($1,lang_input_file_is_search_file_enum, ++ (char *)NULL); } ++ | input_list1 ',' NAME ++ { lang_add_input_file($3,lang_input_file_is_search_file_enum, ++ (char *)NULL); } ++ | input_list1 NAME ++ { lang_add_input_file($2,lang_input_file_is_search_file_enum, ++ (char *)NULL); } ++ | LNAME ++ { lang_add_input_file($1,lang_input_file_is_l_enum, ++ (char *)NULL); } ++ | input_list1 ',' LNAME ++ { lang_add_input_file($3,lang_input_file_is_l_enum, ++ (char *)NULL); } ++ | input_list1 LNAME ++ { lang_add_input_file($2,lang_input_file_is_l_enum, ++ (char *)NULL); } ++ | AS_NEEDED '(' ++ { $$ = input_flags.add_DT_NEEDED_for_regular; ++ input_flags.add_DT_NEEDED_for_regular = true; } ++ input_list1 ')' ++ { input_flags.add_DT_NEEDED_for_regular = $3; } ++ | input_list1 ',' AS_NEEDED '(' ++ { $$ = input_flags.add_DT_NEEDED_for_regular; ++ input_flags.add_DT_NEEDED_for_regular = true; } ++ input_list1 ')' ++ { input_flags.add_DT_NEEDED_for_regular = $5; } ++ | input_list1 AS_NEEDED '(' ++ { $$ = input_flags.add_DT_NEEDED_for_regular; ++ input_flags.add_DT_NEEDED_for_regular = true; } ++ input_list1 ')' ++ { input_flags.add_DT_NEEDED_for_regular = $4; } ++ ; ++ ++sections: ++ SECTIONS '{' sec_or_group_p1 '}' ++ ; ++ ++sec_or_group_p1: ++ sec_or_group_p1 section ++ | sec_or_group_p1 statement_anywhere ++ | ++ ; ++ ++statement_anywhere: ++ ENTRY '(' NAME ')' ++ { lang_add_entry ($3, false); } ++ | assignment separator ++ | ASSERT_K {ldlex_expression ();} '(' exp ',' NAME ')' ++ { ldlex_popstate (); ++ lang_add_assignment (exp_assert ($4, $6)); } ++ ; ++ ++wildcard_name: ++ NAME ++ { ++ $$ = $1; ++ } ++ ; ++ ++wildcard_maybe_exclude: ++ wildcard_name ++ { ++ $$.name = $1; ++ $$.sorted = none; ++ $$.exclude_name_list = NULL; ++ $$.section_flag_list = NULL; ++ } ++ | EXCLUDE_FILE '(' exclude_name_list ')' wildcard_name ++ { ++ $$.name = $5; ++ $$.sorted = none; ++ $$.exclude_name_list = $3; ++ $$.section_flag_list = NULL; ++ } ++ ; ++ ++filename_spec: ++ wildcard_maybe_exclude ++ | SORT_BY_NAME '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_name; ++ } ++ | SORT_NONE '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_none; ++ } ++ ; ++ ++section_name_spec: ++ wildcard_maybe_exclude ++ | SORT_BY_NAME '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_name; ++ } ++ | SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_alignment; ++ } ++ | SORT_NONE '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_none; ++ } ++ | SORT_BY_NAME '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')' ++ { ++ $$ = $5; ++ $$.sorted = by_name_alignment; ++ } ++ | SORT_BY_NAME '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')' ++ { ++ $$ = $5; ++ $$.sorted = by_name; ++ } ++ | SORT_BY_ALIGNMENT '(' SORT_BY_NAME '(' wildcard_maybe_exclude ')' ')' ++ { ++ $$ = $5; ++ $$.sorted = by_alignment_name; ++ } ++ | SORT_BY_ALIGNMENT '(' SORT_BY_ALIGNMENT '(' wildcard_maybe_exclude ')' ')' ++ { ++ $$ = $5; ++ $$.sorted = by_alignment; ++ } ++ | SORT_BY_INIT_PRIORITY '(' wildcard_maybe_exclude ')' ++ { ++ $$ = $3; ++ $$.sorted = by_init_priority; ++ } ++ ; ++ ++sect_flag_list: NAME ++ { ++ struct flag_info_list *n; ++ n = ((struct flag_info_list *) xmalloc (sizeof *n)); ++ if ($1[0] == '!') ++ { ++ n->with = without_flags; ++ n->name = &$1[1]; ++ } ++ else ++ { ++ n->with = with_flags; ++ n->name = $1; ++ } ++ n->valid = false; ++ n->next = NULL; ++ $$ = n; ++ } ++ | sect_flag_list '&' NAME ++ { ++ struct flag_info_list *n; ++ n = ((struct flag_info_list *) xmalloc (sizeof *n)); ++ if ($3[0] == '!') ++ { ++ n->with = without_flags; ++ n->name = &$3[1]; ++ } ++ else ++ { ++ n->with = with_flags; ++ n->name = $3; ++ } ++ n->valid = false; ++ n->next = $1; ++ $$ = n; ++ } ++ ; ++ ++sect_flags: ++ INPUT_SECTION_FLAGS '(' sect_flag_list ')' ++ { ++ struct flag_info *n; ++ n = ((struct flag_info *) xmalloc (sizeof *n)); ++ n->flag_list = $3; ++ n->flags_initialized = false; ++ n->not_with_flags = 0; ++ n->only_with_flags = 0; ++ $$ = n; ++ } ++ ; ++ ++exclude_name_list: ++ exclude_name_list wildcard_name ++ { ++ struct name_list *tmp; ++ tmp = (struct name_list *) xmalloc (sizeof *tmp); ++ tmp->name = $2; ++ tmp->next = $1; ++ $$ = tmp; ++ } ++ | ++ wildcard_name ++ { ++ struct name_list *tmp; ++ tmp = (struct name_list *) xmalloc (sizeof *tmp); ++ tmp->name = $1; ++ tmp->next = NULL; ++ $$ = tmp; ++ } ++ ; ++ ++section_name_list: ++ section_name_list opt_comma section_name_spec ++ { ++ struct wildcard_list *tmp; ++ tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); ++ tmp->next = $1; ++ tmp->spec = $3; ++ $$ = tmp; ++ } ++ | ++ section_name_spec ++ { ++ struct wildcard_list *tmp; ++ tmp = (struct wildcard_list *) xmalloc (sizeof *tmp); ++ tmp->next = NULL; ++ tmp->spec = $1; ++ $$ = tmp; ++ } ++ ; ++ ++input_section_spec_no_keep: ++ NAME ++ { ++ struct wildcard_spec tmp; ++ tmp.name = $1; ++ tmp.exclude_name_list = NULL; ++ tmp.sorted = none; ++ tmp.section_flag_list = NULL; ++ lang_add_wild (&tmp, NULL, ldgram_had_keep); ++ } ++ | sect_flags NAME ++ { ++ struct wildcard_spec tmp; ++ tmp.name = $2; ++ tmp.exclude_name_list = NULL; ++ tmp.sorted = none; ++ tmp.section_flag_list = $1; ++ lang_add_wild (&tmp, NULL, ldgram_had_keep); ++ } ++ | '[' section_name_list ']' ++ { ++ lang_add_wild (NULL, $2, ldgram_had_keep); ++ } ++ | sect_flags '[' section_name_list ']' ++ { ++ struct wildcard_spec tmp; ++ tmp.name = NULL; ++ tmp.exclude_name_list = NULL; ++ tmp.sorted = none; ++ tmp.section_flag_list = $1; ++ lang_add_wild (&tmp, $3, ldgram_had_keep); ++ } ++ | filename_spec '(' section_name_list ')' ++ { ++ lang_add_wild (&$1, $3, ldgram_had_keep); ++ } ++ | sect_flags filename_spec '(' section_name_list ')' ++ { ++ $2.section_flag_list = $1; ++ lang_add_wild (&$2, $4, ldgram_had_keep); ++ } ++ ; ++ ++input_section_spec: ++ input_section_spec_no_keep ++ | KEEP '(' ++ { ldgram_had_keep = true; } ++ input_section_spec_no_keep ')' ++ { ldgram_had_keep = false; } ++ ; ++ ++statement: ++ ';' ++ | assignment separator ++ | CREATE_OBJECT_SYMBOLS ++ { ++ lang_add_attribute (lang_object_symbols_statement_enum); ++ } ++ | CONSTRUCTORS ++ { ++ lang_add_attribute (lang_constructors_statement_enum); ++ } ++ | SORT_BY_NAME '(' CONSTRUCTORS ')' ++ { ++ constructors_sorted = true; ++ lang_add_attribute (lang_constructors_statement_enum); ++ } ++ | input_section_spec ++ | length '(' mustbe_exp ')' ++ { ++ lang_add_data ((int) $1, $3); ++ } ++ | ASCIZ NAME ++ { ++ lang_add_string ($2); ++ } ++ | FILL '(' fill_exp ')' ++ { ++ lang_add_fill ($3); ++ } ++ | LINKER_VERSION ++ { ++ lang_add_version_string (); ++ } ++ | ASSERT_K ++ { ldlex_expression (); } ++ '(' exp ',' NAME ')' separator ++ { ++ ldlex_popstate (); ++ lang_add_assignment (exp_assert ($4, $6)); ++ } ++ | INCLUDE filename ++ { ++ ldfile_open_command_file ($2); ++ } ++ statement_list_opt END ++ ; ++ ++statement_list: ++ statement_list statement ++ | statement ++ ; ++ ++statement_list_opt: ++ /* empty */ ++ | statement_list ++ ; ++ ++length: ++ QUAD ++ { $$ = $1; } ++ | SQUAD ++ { $$ = $1; } ++ | LONG ++ { $$ = $1; } ++ | SHORT ++ { $$ = $1; } ++ | BYTE ++ { $$ = $1; } ++ ; ++ ++fill_exp: ++ mustbe_exp ++ { ++ $$ = exp_get_fill ($1, 0, _("fill value")); ++ } ++ ; ++ ++fill_opt: ++ '=' fill_exp ++ { $$ = $2; } ++ | { $$ = (fill_type *) 0; } ++ ; ++ ++assign_op: ++ PLUSEQ ++ { $$ = '+'; } ++ | MINUSEQ ++ { $$ = '-'; } ++ | MULTEQ ++ { $$ = '*'; } ++ | DIVEQ ++ { $$ = '/'; } ++ | LSHIFTEQ ++ { $$ = LSHIFT; } ++ | RSHIFTEQ ++ { $$ = RSHIFT; } ++ | ANDEQ ++ { $$ = '&'; } ++ | OREQ ++ { $$ = '|'; } ++ ++ ; ++ ++separator: ';' | ',' ++ ; ++ ++ ++assignment: ++ NAME '=' mustbe_exp ++ { ++ lang_add_assignment (exp_assign ($1, $3, false)); ++ } ++ | NAME assign_op mustbe_exp ++ { ++ lang_add_assignment (exp_assign ($1, ++ exp_binop ($2, ++ exp_nameop (NAME, ++ $1), ++ $3), false)); ++ } ++ | HIDDEN '(' NAME '=' mustbe_exp ')' ++ { ++ lang_add_assignment (exp_assign ($3, $5, true)); ++ } ++ | PROVIDE '(' NAME '=' mustbe_exp ')' ++ { ++ lang_add_assignment (exp_provide ($3, $5, false)); ++ } ++ | PROVIDE_HIDDEN '(' NAME '=' mustbe_exp ')' ++ { ++ lang_add_assignment (exp_provide ($3, $5, true)); ++ } ++ ; ++ ++ ++opt_comma: ++ ',' | ; ++ ++ ++memory: ++ MEMORY '{' memory_spec_list_opt '}' ++ ; ++ ++memory_spec_list_opt: memory_spec_list | ; ++ ++memory_spec_list: ++ memory_spec_list opt_comma memory_spec ++ | memory_spec ++ ; ++ ++ ++memory_spec: NAME ++ { region = lang_memory_region_lookup ($1, true); } ++ attributes_opt ':' ++ origin_spec opt_comma length_spec ++ {} ++ | INCLUDE filename ++ { ldfile_open_command_file ($2); } ++ memory_spec_list_opt END ++ ; ++ ++origin_spec: ++ ORIGIN '=' mustbe_exp ++ { ++ region->origin_exp = $3; ++ } ++ ; ++ ++length_spec: ++ LENGTH '=' mustbe_exp ++ { ++ if (yychar == NAME) ++ { ++ yyclearin; ++ ldlex_backup (); ++ } ++ region->length_exp = $3; ++ } ++ ; ++ ++attributes_opt: ++ /* empty */ ++ { /* dummy action to avoid bison 1.25 error message */ } ++ | '(' attributes_list ')' ++ ; ++ ++attributes_list: ++ attributes_string ++ | attributes_list attributes_string ++ ; ++ ++attributes_string: ++ NAME ++ { lang_set_flags (region, $1, 0); } ++ | '!' NAME ++ { lang_set_flags (region, $2, 1); } ++ ; ++ ++startup: ++ STARTUP '(' filename ')' ++ { lang_startup($3); } ++ ; ++ ++high_level_library: ++ HLL '(' high_level_library_NAME_list ')' ++ | HLL '(' ')' ++ { ldemul_hll((char *)NULL); } ++ ; ++ ++high_level_library_NAME_list: ++ high_level_library_NAME_list opt_comma filename ++ { ldemul_hll($3); } ++ | filename ++ { ldemul_hll($1); } ++ ; ++ ++low_level_library: ++ SYSLIB '(' low_level_library_NAME_list ')' ++ ; ++ ++low_level_library_NAME_list: ++ low_level_library_NAME_list opt_comma filename ++ { ldemul_syslib($3); } ++ | ++ ; ++ ++floating_point_support: ++ FLOAT ++ { lang_float(true); } ++ | NOFLOAT ++ { lang_float(false); } ++ ; ++ ++nocrossref_list: ++ /* empty */ ++ { ++ $$ = NULL; ++ } ++ | NAME nocrossref_list ++ { ++ struct lang_nocrossref *n; ++ ++ n = (struct lang_nocrossref *) xmalloc (sizeof *n); ++ n->name = $1; ++ n->next = $2; ++ $$ = n; ++ } ++ | NAME ',' nocrossref_list ++ { ++ struct lang_nocrossref *n; ++ ++ n = (struct lang_nocrossref *) xmalloc (sizeof *n); ++ n->name = $1; ++ n->next = $3; ++ $$ = n; ++ } ++ ; ++ ++paren_script_name: { ldlex_script (); } ++ '(' NAME ')' ++ { ldlex_popstate (); $$ = $3; } ++ ++mustbe_exp: { ldlex_expression (); } ++ exp ++ { ldlex_popstate (); $$ = $2; } ++ ; ++ ++exp : ++ '-' exp %prec UNARY ++ { $$ = exp_unop ('-', $2); } ++ | '(' exp ')' ++ { $$ = $2; } ++ | NEXT '(' exp ')' %prec UNARY ++ { $$ = exp_unop ((int) $1,$3); } ++ | '!' exp %prec UNARY ++ { $$ = exp_unop ('!', $2); } ++ | '+' exp %prec UNARY ++ { $$ = $2; } ++ | '~' exp %prec UNARY ++ { $$ = exp_unop ('~', $2);} ++ ++ | exp '*' exp ++ { $$ = exp_binop ('*', $1, $3); } ++ | exp '/' exp ++ { $$ = exp_binop ('/', $1, $3); } ++ | exp '%' exp ++ { $$ = exp_binop ('%', $1, $3); } ++ | exp '+' exp ++ { $$ = exp_binop ('+', $1, $3); } ++ | exp '-' exp ++ { $$ = exp_binop ('-' , $1, $3); } ++ | exp LSHIFT exp ++ { $$ = exp_binop (LSHIFT , $1, $3); } ++ | exp RSHIFT exp ++ { $$ = exp_binop (RSHIFT , $1, $3); } ++ | exp EQ exp ++ { $$ = exp_binop (EQ , $1, $3); } ++ | exp NE exp ++ { $$ = exp_binop (NE , $1, $3); } ++ | exp LE exp ++ { $$ = exp_binop (LE , $1, $3); } ++ | exp GE exp ++ { $$ = exp_binop (GE , $1, $3); } ++ | exp '<' exp ++ { $$ = exp_binop ('<' , $1, $3); } ++ | exp '>' exp ++ { $$ = exp_binop ('>' , $1, $3); } ++ | exp '&' exp ++ { $$ = exp_binop ('&' , $1, $3); } ++ | exp '^' exp ++ { $$ = exp_binop ('^' , $1, $3); } ++ | exp '|' exp ++ { $$ = exp_binop ('|' , $1, $3); } ++ | exp '?' exp ':' exp ++ { $$ = exp_trinop ('?' , $1, $3, $5); } ++ | exp ANDAND exp ++ { $$ = exp_binop (ANDAND , $1, $3); } ++ | exp OROR exp ++ { $$ = exp_binop (OROR , $1, $3); } ++ | DEFINED '(' NAME ')' ++ { $$ = exp_nameop (DEFINED, $3); } ++ | INT ++ { $$ = exp_bigintop ($1.integer, $1.str); } ++ | SIZEOF_HEADERS ++ { $$ = exp_nameop (SIZEOF_HEADERS,0); } ++ ++ | ALIGNOF paren_script_name ++ { $$ = exp_nameop (ALIGNOF, $2); } ++ | SIZEOF paren_script_name ++ { $$ = exp_nameop (SIZEOF, $2); } ++ | ADDR paren_script_name ++ { $$ = exp_nameop (ADDR, $2); } ++ | LOADADDR paren_script_name ++ { $$ = exp_nameop (LOADADDR, $2); } ++ | CONSTANT '(' NAME ')' ++ { $$ = exp_nameop (CONSTANT,$3); } ++ | ABSOLUTE '(' exp ')' ++ { $$ = exp_unop (ABSOLUTE, $3); } ++ | ALIGN_K '(' exp ')' ++ { $$ = exp_unop (ALIGN_K,$3); } ++ | ALIGN_K '(' exp ',' exp ')' ++ { $$ = exp_binop (ALIGN_K,$3,$5); } ++ | DATA_SEGMENT_ALIGN '(' exp ',' exp ')' ++ { $$ = exp_binop (DATA_SEGMENT_ALIGN, $3, $5); } ++ | DATA_SEGMENT_RELRO_END '(' exp ',' exp ')' ++ { $$ = exp_binop (DATA_SEGMENT_RELRO_END, $5, $3); } ++ | DATA_SEGMENT_END '(' exp ')' ++ { $$ = exp_unop (DATA_SEGMENT_END, $3); } ++ | SEGMENT_START { ldlex_script (); } '(' NAME ++ { ldlex_popstate (); } ',' exp ')' ++ { /* The operands to the expression node are ++ placed in the opposite order from the way ++ in which they appear in the script as ++ that allows us to reuse more code in ++ fold_binary. */ ++ $$ = exp_binop (SEGMENT_START, ++ $7, ++ exp_nameop (NAME, $4)); } ++ | BLOCK '(' exp ')' ++ { $$ = exp_unop (ALIGN_K,$3); } ++ | NAME ++ { $$ = exp_nameop (NAME,$1); } ++ | MAX_K '(' exp ',' exp ')' ++ { $$ = exp_binop (MAX_K, $3, $5 ); } ++ | MIN_K '(' exp ',' exp ')' ++ { $$ = exp_binop (MIN_K, $3, $5 ); } ++ | ASSERT_K '(' exp ',' NAME ')' ++ { $$ = exp_assert ($3, $5); } ++ | ORIGIN paren_script_name ++ { $$ = exp_nameop (ORIGIN, $2); } ++ | LENGTH paren_script_name ++ { $$ = exp_nameop (LENGTH, $2); } ++ | LOG2CEIL '(' exp ')' ++ { $$ = exp_unop (LOG2CEIL, $3); } ++ ; ++ ++ ++memspec_at_opt: ++ AT '>' NAME { $$ = $3; } ++ | { $$ = 0; } ++ ; ++ ++opt_at: ++ AT '(' exp ')' { $$ = $3; } ++ | { $$ = 0; } ++ ; ++ ++opt_align: ++ ALIGN_K '(' exp ')' { $$ = $3; } ++ | { $$ = 0; } ++ ; ++ ++opt_align_with_input: ++ ALIGN_WITH_INPUT { $$ = ALIGN_WITH_INPUT; } ++ | { $$ = 0; } ++ ; ++ ++opt_subalign: ++ SUBALIGN '(' exp ')' { $$ = $3; } ++ | { $$ = 0; } ++ ; ++ ++sect_constraint: ++ ONLY_IF_RO { $$ = ONLY_IF_RO; } ++ | ONLY_IF_RW { $$ = ONLY_IF_RW; } ++ | SPECIAL { $$ = SPECIAL; } ++ | { $$ = 0; } ++ ; ++ ++section: NAME ++ { ldlex_expression(); } ++ opt_exp_with_type ++ opt_at ++ opt_align ++ opt_align_with_input ++ opt_subalign ++ sect_constraint ++ { ++ ldlex_popstate (); ++ ldlex_wild (); ++ lang_enter_output_section_statement ($1, $3, sectype, ++ sectype_value, $5, $7, $4, $8, $6); ++ } ++ '{' ++ statement_list_opt ++ '}' ++ { ldlex_popstate (); } ++ memspec_opt memspec_at_opt phdr_opt fill_opt ++ { ++ /* fill_opt may have switched the lexer into ++ expression state, and back again, but in ++ order to find the end of the fill ++ expression the parser must look ahead one ++ token. If it is a NAME, throw it away as ++ it will have been lexed in the wrong ++ state. */ ++ if (yychar == NAME) ++ { ++ yyclearin; ++ ldlex_backup (); ++ } ++ lang_leave_output_section_statement ($17, $14, ++ $16, $15); ++ } ++ opt_comma ++ | OVERLAY ++ { ldlex_expression (); } ++ opt_exp_without_type opt_nocrossrefs opt_at opt_subalign ++ { ldlex_popstate (); } ++ '{' ++ { ++ lang_enter_overlay ($3, $6); ++ } ++ overlay_section ++ '}' ++ memspec_opt memspec_at_opt phdr_opt fill_opt ++ { ++ if (yychar == NAME) ++ { ++ yyclearin; ++ ldlex_backup (); ++ } ++ lang_leave_overlay ($5, (int) $4, ++ $15, $12, $14, $13); ++ } ++ opt_comma ++ | /* The GROUP case is just enough to support the gcc ++ svr3.ifile script. It is not intended to be full ++ support. I'm not even sure what GROUP is supposed ++ to mean. */ ++ GROUP ++ { ldlex_expression (); } ++ opt_exp_with_type ++ { ++ ldlex_popstate (); ++ lang_add_assignment (exp_assign (".", $3, false)); ++ } ++ '{' sec_or_group_p1 '}' ++ | INCLUDE filename ++ { ++ ldfile_open_command_file ($2); ++ } ++ sec_or_group_p1 END ++ ; ++ ++type: ++ NOLOAD { sectype = noload_section; } ++ | DSECT { sectype = noalloc_section; } ++ | COPY { sectype = noalloc_section; } ++ | INFO { sectype = noalloc_section; } ++ | OVERLAY { sectype = noalloc_section; } ++ | READONLY '(' TYPE '=' exp ')' { sectype = typed_readonly_section; sectype_value = $5; } ++ | READONLY { sectype = readonly_section; } ++ | TYPE '=' exp { sectype = type_section; sectype_value = $3; } ++ ; ++ ++atype: ++ '(' type ')' ++ | /* EMPTY */ { sectype = normal_section; } ++ | '(' ')' { sectype = normal_section; } ++ ; ++ ++opt_exp_with_type: ++ exp atype ':' { $$ = $1; } ++ | atype ':' { $$ = (etree_type *)NULL; } ++ | /* The BIND cases are to support the gcc svr3.ifile ++ script. They aren't intended to implement full ++ support for the BIND keyword. I'm not even sure ++ what BIND is supposed to mean. */ ++ BIND '(' exp ')' atype ':' { $$ = $3; } ++ | BIND '(' exp ')' BLOCK '(' exp ')' atype ':' ++ { $$ = $3; } ++ ; ++ ++opt_exp_without_type: ++ exp ':' { $$ = $1; } ++ | ':' { $$ = (etree_type *) NULL; } ++ ; ++ ++opt_nocrossrefs: ++ /* empty */ ++ { $$ = 0; } ++ | NOCROSSREFS ++ { $$ = 1; } ++ ; ++ ++memspec_opt: ++ '>' NAME ++ { $$ = $2; } ++ | { $$ = DEFAULT_MEMORY_REGION; } ++ ; ++ ++phdr_opt: ++ /* empty */ ++ { ++ $$ = NULL; ++ } ++ | phdr_opt ':' NAME ++ { ++ struct lang_output_section_phdr_list *n; ++ ++ n = ((struct lang_output_section_phdr_list *) ++ xmalloc (sizeof *n)); ++ n->name = $3; ++ n->used = false; ++ n->next = $1; ++ $$ = n; ++ } ++ ; ++ ++overlay_section: ++ /* empty */ ++ | overlay_section ++ NAME ++ { ++ ldlex_wild (); ++ lang_enter_overlay_section ($2); ++ } ++ '{' ++ statement_list_opt ++ '}' ++ { ldlex_popstate (); } ++ phdr_opt fill_opt ++ { ++ if (yychar == NAME) ++ { ++ yyclearin; ++ ldlex_backup (); ++ } ++ lang_leave_overlay_section ($9, $8); ++ } ++ opt_comma ++ ; ++ ++phdrs: ++ PHDRS '{' phdr_list '}' ++ ; ++ ++phdr_list: ++ /* empty */ ++ | phdr_list phdr ++ ; ++ ++phdr: ++ NAME { ldlex_expression (); } ++ phdr_type phdr_qualifiers { ldlex_popstate (); } ++ ';' ++ { ++ lang_new_phdr ($1, $3, $4.filehdr, $4.phdrs, $4.at, ++ $4.flags); ++ } ++ ; ++ ++phdr_type: ++ exp ++ { ++ $$ = $1; ++ ++ if ($1->type.node_class == etree_name ++ && $1->type.node_code == NAME) ++ { ++ const char *s; ++ unsigned int i; ++ static const char * const phdr_types[] = ++ { ++ "PT_NULL", "PT_LOAD", "PT_DYNAMIC", ++ "PT_INTERP", "PT_NOTE", "PT_SHLIB", ++ "PT_PHDR", "PT_TLS" ++ }; ++ ++ s = $1->name.name; ++ for (i = 0; ++ i < sizeof phdr_types / sizeof phdr_types[0]; ++ i++) ++ if (strcmp (s, phdr_types[i]) == 0) ++ { ++ $$ = exp_intop (i); ++ break; ++ } ++ if (i == sizeof phdr_types / sizeof phdr_types[0]) ++ { ++ if (strcmp (s, "PT_GNU_EH_FRAME") == 0) ++ $$ = exp_intop (0x6474e550); ++ else if (strcmp (s, "PT_GNU_STACK") == 0) ++ $$ = exp_intop (0x6474e551); ++ else if (strcmp (s, "PT_GNU_RELRO") == 0) ++ $$ = exp_intop (0x6474e552); ++ else if (strcmp (s, "PT_GNU_PROPERTY") == 0) ++ $$ = exp_intop (0x6474e553); ++ else ++ { ++ einfo (_("\ ++%X%P:%pS: unknown phdr type `%s' (try integer literal)\n"), ++ NULL, s); ++ $$ = exp_intop (0); ++ } ++ } ++ } ++ } ++ ; ++ ++phdr_qualifiers: ++ /* empty */ ++ { ++ memset (&$$, 0, sizeof (struct phdr_info)); ++ } ++ | NAME phdr_val phdr_qualifiers ++ { ++ $$ = $3; ++ if (strcmp ($1, "FILEHDR") == 0 && $2 == NULL) ++ $$.filehdr = true; ++ else if (strcmp ($1, "PHDRS") == 0 && $2 == NULL) ++ $$.phdrs = true; ++ else if (strcmp ($1, "FLAGS") == 0 && $2 != NULL) ++ $$.flags = $2; ++ else ++ einfo (_("%X%P:%pS: PHDRS syntax error at `%s'\n"), ++ NULL, $1); ++ } ++ | AT '(' exp ')' phdr_qualifiers ++ { ++ $$ = $5; ++ $$.at = $3; ++ } ++ ; ++ ++phdr_val: ++ /* empty */ ++ { ++ $$ = NULL; ++ } ++ | '(' exp ')' ++ { ++ $$ = $2; ++ } ++ ; ++ ++dynamic_list_file: ++ { ++ ldlex_version_file (); ++ PUSH_ERROR (_("dynamic list")); ++ } ++ dynamic_list_nodes ++ { ++ ldlex_popstate (); ++ POP_ERROR (); ++ } ++ ; ++ ++dynamic_list_nodes: ++ dynamic_list_node ++ | dynamic_list_nodes dynamic_list_node ++ ; ++ ++dynamic_list_node: ++ '{' dynamic_list_tag '}' ';' ++ ; ++ ++dynamic_list_tag: ++ vers_defns ';' ++ { ++ lang_append_dynamic_list (current_dynamic_list_p, $1); ++ } ++ ; ++ ++/* This syntax is used within an external version script file. */ ++ ++version_script_file: ++ { ++ ldlex_version_file (); ++ PUSH_ERROR (_("VERSION script")); ++ } ++ vers_nodes ++ { ++ ldlex_popstate (); ++ POP_ERROR (); ++ } ++ ; ++ ++/* This is used within a normal linker script file. */ ++ ++version: ++ { ++ ldlex_version_script (); ++ } ++ VERSIONK '{' vers_nodes '}' ++ { ++ ldlex_popstate (); ++ } ++ ; ++ ++vers_nodes: ++ vers_node ++ | vers_nodes vers_node ++ ; ++ ++vers_node: ++ '{' vers_tag '}' ';' ++ { ++ lang_register_vers_node (NULL, $2, NULL); ++ } ++ | VERS_TAG '{' vers_tag '}' ';' ++ { ++ lang_register_vers_node ($1, $3, NULL); ++ } ++ | VERS_TAG '{' vers_tag '}' verdep ';' ++ { ++ lang_register_vers_node ($1, $3, $5); ++ } ++ ; ++ ++verdep: ++ VERS_TAG ++ { ++ $$ = lang_add_vers_depend (NULL, $1); ++ } ++ | verdep VERS_TAG ++ { ++ $$ = lang_add_vers_depend ($1, $2); ++ } ++ ; ++ ++vers_tag: ++ /* empty */ ++ { ++ $$ = lang_new_vers_node (NULL, NULL); ++ } ++ | vers_defns ';' ++ { ++ $$ = lang_new_vers_node ($1, NULL); ++ } ++ | GLOBAL ':' vers_defns ';' ++ { ++ $$ = lang_new_vers_node ($3, NULL); ++ } ++ | LOCAL ':' vers_defns ';' ++ { ++ $$ = lang_new_vers_node (NULL, $3); ++ } ++ | GLOBAL ':' vers_defns ';' LOCAL ':' vers_defns ';' ++ { ++ $$ = lang_new_vers_node ($3, $7); ++ } ++ ; ++ ++vers_defns: ++ VERS_IDENTIFIER ++ { ++ $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, false); ++ } ++ | NAME ++ { ++ $$ = lang_new_vers_pattern (NULL, $1, ldgram_vers_current_lang, true); ++ } ++ | vers_defns ';' VERS_IDENTIFIER ++ { ++ $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, false); ++ } ++ | vers_defns ';' NAME ++ { ++ $$ = lang_new_vers_pattern ($1, $3, ldgram_vers_current_lang, true); ++ } ++ | vers_defns ';' EXTERN NAME '{' ++ { ++ $$ = ldgram_vers_current_lang; ++ ldgram_vers_current_lang = $4; ++ } ++ vers_defns opt_semicolon '}' ++ { ++ struct bfd_elf_version_expr *pat; ++ for (pat = $7; pat->next != NULL; pat = pat->next); ++ pat->next = $1; ++ $$ = $7; ++ ldgram_vers_current_lang = $6; ++ } ++ | EXTERN NAME '{' ++ { ++ $$ = ldgram_vers_current_lang; ++ ldgram_vers_current_lang = $2; ++ } ++ vers_defns opt_semicolon '}' ++ { ++ $$ = $5; ++ ldgram_vers_current_lang = $4; ++ } ++ | GLOBAL ++ { ++ $$ = lang_new_vers_pattern (NULL, "global", ldgram_vers_current_lang, false); ++ } ++ | vers_defns ';' GLOBAL ++ { ++ $$ = lang_new_vers_pattern ($1, "global", ldgram_vers_current_lang, false); ++ } ++ | LOCAL ++ { ++ $$ = lang_new_vers_pattern (NULL, "local", ldgram_vers_current_lang, false); ++ } ++ | vers_defns ';' LOCAL ++ { ++ $$ = lang_new_vers_pattern ($1, "local", ldgram_vers_current_lang, false); ++ } ++ | EXTERN ++ { ++ $$ = lang_new_vers_pattern (NULL, "extern", ldgram_vers_current_lang, false); ++ } ++ | vers_defns ';' EXTERN ++ { ++ $$ = lang_new_vers_pattern ($1, "extern", ldgram_vers_current_lang, false); ++ } ++ ; ++ ++opt_semicolon: ++ /* empty */ ++ | ';' ++ ; ++ ++%% ++void ++yyerror(arg) ++ const char *arg; ++{ ++ if (ldfile_assumed_script) ++ einfo (_("%P:%s: file format not recognized; treating as linker script\n"), ++ ldlex_filename ()); ++ if (error_index > 0 && error_index < ERROR_NAME_MAX) ++ einfo (_("%F%P:%pS: %s in %s\n"), NULL, arg, error_names[error_index - 1]); ++ else ++ einfo ("%F%P:%pS: %s\n", NULL, arg); ++} +diff -rupN binutils.orig/ld/ldlang.c binutils-2.41/ld/ldlang.c +--- binutils.orig/ld/ldlang.c 2024-05-13 13:03:47.804601777 +0100 ++++ binutils-2.41/ld/ldlang.c 2024-05-13 13:04:08.599633306 +0100 +@@ -1282,6 +1282,7 @@ output_section_statement_newfunc (struct + ret->s.output_section_statement.section_alignment = NULL; + ret->s.output_section_statement.block_value = 1; + lang_list_init (&ret->s.output_section_statement.children); ++ lang_list_init (&ret->s.output_section_statement.sort_children); + lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); + + /* For every output section statement added to the list, except the +@@ -7566,13 +7567,22 @@ lang_enter_output_section_statement (con + lang_output_section_statement_type *os; + + os = lang_output_section_statement_lookup (output_section_statement_name, +- constraint, 2); ++ constraint, ++ in_section_ordering ? 0 : 2); ++ if (os == NULL) /* && in_section_ordering */ ++ einfo (_("%F%P:%pS: error: output section '%s' must already exist\n"), ++ NULL, output_section_statement_name); + current_section = os; + ++ /* Make next things chain into subchain of this. */ ++ push_stat_ptr (in_section_ordering ? &os->sort_children : &os->children); ++ ++ if (in_section_ordering) ++ return os; ++ + if (os->addr_tree == NULL) +- { +- os->addr_tree = address_exp; +- } ++ os->addr_tree = address_exp; ++ + os->sectype = sectype; + if (sectype == type_section || sectype == typed_readonly_section) + os->sectype_value = sectype_value; +@@ -7582,9 +7592,6 @@ lang_enter_output_section_statement (con + os->flags = SEC_NO_FLAGS; + os->block_value = 1; + +- /* Make next things chain into subchain of this. */ +- push_stat_ptr (&os->children); +- + os->align_lma_with_input = align_with_input == ALIGN_WITH_INPUT; + if (os->align_lma_with_input && align != NULL) + einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"), +@@ -7924,21 +7931,6 @@ find_rescan_insertion (lang_input_statem + return iter; + } + +-/* Insert SRCLIST into DESTLIST after given element by chaining +- on FIELD as the next-pointer. (Counterintuitively does not need +- a pointer to the actual after-node itself, just its chain field.) */ +- +-static void +-lang_list_insert_after (lang_statement_list_type *destlist, +- lang_statement_list_type *srclist, +- lang_statement_union_type **field) +-{ +- *(srclist->tail) = *field; +- *field = srclist->head; +- if (destlist->tail == field) +- destlist->tail = srclist->tail; +-} +- + /* Detach new nodes added to DESTLIST since the time ORIGLIST + was taken as a copy of it and leave them in ORIGLIST. */ + +@@ -7986,6 +7978,21 @@ find_next_input_statement (lang_statemen + } + #endif /* BFD_SUPPORTS_PLUGINS */ + ++/* Insert SRCLIST into DESTLIST after given element by chaining ++ on FIELD as the next-pointer. (Counterintuitively does not need ++ a pointer to the actual after-node itself, just its chain field.) */ ++ ++static void ++lang_list_insert_after (lang_statement_list_type *destlist, ++ lang_statement_list_type *srclist, ++ lang_statement_union_type **field) ++{ ++ *(srclist->tail) = *field; ++ *field = srclist->head; ++ if (destlist->tail == field) ++ destlist->tail = srclist->tail; ++} ++ + /* Add NAME to the list of garbage collection entry points. */ + + void +@@ -8080,9 +8087,34 @@ reset_resolved_wilds (void) + lang_for_each_statement (reset_one_wild); + } + ++/* For each output section statement, splice any entries on the ++ sort_children list before the first wild statement on the children ++ list. */ ++ ++static void ++lang_os_merge_sort_children (void) ++{ ++ lang_output_section_statement_type *os; ++ for (os = (void *) lang_os_list.head; os != NULL; os = os->next) ++ { ++ if (os->sort_children.head != NULL) ++ { ++ lang_statement_union_type **where; ++ for (where = &os->children.head; ++ *where != NULL; ++ where = &(*where)->header.next) ++ if ((*where)->header.type == lang_wild_statement_enum) ++ break; ++ lang_list_insert_after (&os->children, &os->sort_children, where); ++ } ++ } ++} ++ + void + lang_process (void) + { ++ lang_os_merge_sort_children (); ++ + /* Finalize dynamic list. */ + if (link_info.dynamic_list) + lang_finalize_version_expr_head (&link_info.dynamic_list->head); +@@ -8764,6 +8796,10 @@ lang_leave_output_section_statement (fil + lang_output_section_phdr_list *phdrs, + const char *lma_memspec) + { ++ pop_stat_ptr (); ++ if (in_section_ordering) ++ return; ++ + lang_get_regions (¤t_section->region, + ¤t_section->lma_region, + memspec, lma_memspec, +@@ -8772,7 +8808,6 @@ lang_leave_output_section_statement (fil + + current_section->fill = fill; + current_section->phdrs = phdrs; +- pop_stat_ptr (); + } + + /* Set the output format type. -oformat overrides scripts. */ +diff -rupN binutils.orig/ld/ldlang.c.orig binutils-2.41/ld/ldlang.c.orig +--- binutils.orig/ld/ldlang.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ldlang.c.orig 2023-07-03 00:00:00.000000000 +0100 +@@ -0,0 +1,9907 @@ ++/* Linker command language support. ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include ++#include "bfd.h" ++#include "libiberty.h" ++#include "filenames.h" ++#include "safe-ctype.h" ++#include "obstack.h" ++#include "bfdlink.h" ++#include "ctf-api.h" ++#include "ld.h" ++#include "ldmain.h" ++#include "ldexp.h" ++#include "ldlang.h" ++#include ++#include "ldlex.h" ++#include "ldmisc.h" ++#include "ldctor.h" ++#include "ldfile.h" ++#include "ldemul.h" ++#include "fnmatch.h" ++#include "demangle.h" ++#include "hashtab.h" ++#include "elf-bfd.h" ++#include "bfdver.h" ++ ++#if BFD_SUPPORTS_PLUGINS ++#include "plugin.h" ++#endif ++ ++#ifndef offsetof ++#define offsetof(TYPE, MEMBER) ((size_t) & (((TYPE*) 0)->MEMBER)) ++#endif ++ ++/* Convert between addresses in bytes and sizes in octets. ++ For currently supported targets, octets_per_byte is always a power ++ of two, so we can use shifts. */ ++#define TO_ADDR(X) ((X) >> opb_shift) ++#define TO_SIZE(X) ((X) << opb_shift) ++ ++/* Local variables. */ ++static struct obstack stat_obstack; ++static struct obstack map_obstack; ++static struct obstack pt_obstack; ++ ++#define obstack_chunk_alloc xmalloc ++#define obstack_chunk_free free ++static const char *entry_symbol_default = "start"; ++static bool map_head_is_link_order = false; ++static lang_output_section_statement_type *default_common_section; ++static bool map_option_f; ++static bfd_vma print_dot; ++static lang_input_statement_type *first_file; ++static const char *current_target; ++static lang_statement_list_type *stat_save[10]; ++static lang_statement_list_type **stat_save_ptr = &stat_save[0]; ++static struct unique_sections *unique_section_list; ++static struct asneeded_minfo *asneeded_list_head; ++static unsigned int opb_shift = 0; ++ ++/* Forward declarations. */ ++static void exp_init_os (etree_type *); ++static lang_input_statement_type *lookup_name (const char *); ++static bool wont_add_section_p (asection *, ++ lang_output_section_statement_type *); ++static void insert_undefined (const char *); ++static bool sort_def_symbol (struct bfd_link_hash_entry *, void *); ++static lang_statement_union_type *new_statement (enum statement_enum type, ++ size_t size, ++ lang_statement_list_type *list); ++static void print_statement (lang_statement_union_type *, ++ lang_output_section_statement_type *); ++static void print_statement_list (lang_statement_union_type *, ++ lang_output_section_statement_type *); ++static void print_statements (void); ++static void print_input_section (asection *, bool); ++static bool lang_one_common (struct bfd_link_hash_entry *, void *); ++static void lang_record_phdrs (void); ++static void lang_do_version_exports_section (void); ++static void lang_finalize_version_expr_head ++ (struct bfd_elf_version_expr_head *); ++static void lang_do_memory_regions (bool); ++ ++/* Exported variables. */ ++const char *output_target; ++lang_output_section_statement_type *abs_output_section; ++/* Header for list of statements corresponding to any files involved in the ++ link, either specified from the command-line or added implicitely (eg. ++ archive member used to resolved undefined symbol, wildcard statement from ++ linker script, etc.). Next pointer is in next field of a ++ lang_statement_header_type (reached via header field in a ++ lang_statement_union). */ ++lang_statement_list_type statement_list; ++lang_statement_list_type lang_os_list; ++lang_statement_list_type *stat_ptr = &statement_list; ++/* Header for list of statements corresponding to files used in the final ++ executable. This can be either object file specified on the command-line ++ or library member resolving an undefined reference. Next pointer is in next ++ field of a lang_input_statement_type (reached via input_statement field in a ++ lang_statement_union). */ ++lang_statement_list_type file_chain = { NULL, NULL }; ++/* Header for list of statements corresponding to files specified on the ++ command-line for linking. It thus contains real object files and archive ++ but not archive members. Next pointer is in next_real_file field of a ++ lang_input_statement_type statement (reached via input_statement field in a ++ lang_statement_union). */ ++lang_statement_list_type input_file_chain; ++static const char *current_input_file; ++struct bfd_elf_dynamic_list **current_dynamic_list_p; ++struct bfd_sym_chain entry_symbol = { NULL, NULL }; ++const char *entry_section = ".text"; ++struct lang_input_statement_flags input_flags; ++bool entry_from_cmdline; ++bool lang_has_input_file = false; ++bool had_output_filename = false; ++bool lang_float_flag = false; ++bool delete_output_file_on_failure = false; ++bool enable_linker_version = false; ++struct lang_phdr *lang_phdr_list; ++struct lang_nocrossrefs *nocrossref_list; ++struct asneeded_minfo **asneeded_list_tail; ++#ifdef ENABLE_LIBCTF ++static ctf_dict_t *ctf_output; ++#endif ++ ++/* Functions that traverse the linker script and might evaluate ++ DEFINED() need to increment this at the start of the traversal. */ ++int lang_statement_iteration = 0; ++ ++/* Count times through one_lang_size_sections_pass after mark phase. */ ++static int lang_sizing_iteration = 0; ++ ++/* Return TRUE if the PATTERN argument is a wildcard pattern. ++ Although backslashes are treated specially if a pattern contains ++ wildcards, we do not consider the mere presence of a backslash to ++ be enough to cause the pattern to be treated as a wildcard. ++ That lets us handle DOS filenames more naturally. */ ++#define wildcardp(pattern) (strpbrk ((pattern), "?*[") != NULL) ++ ++#define new_stat(x, y) \ ++ (x##_type *) new_statement (x##_enum, sizeof (x##_type), y) ++ ++#define outside_section_address(q) \ ++ ((q)->output_offset + (q)->output_section->vma) ++ ++#define outside_symbol_address(q) \ ++ ((q)->value + outside_section_address (q->section)) ++ ++/* CTF sections smaller than this are not compressed: compression of ++ dictionaries this small doesn't gain much, and this lets consumers mmap the ++ sections directly out of the ELF file and use them with no decompression ++ overhead if they want to. */ ++#define CTF_COMPRESSION_THRESHOLD 4096 ++ ++void * ++stat_alloc (size_t size) ++{ ++ return obstack_alloc (&stat_obstack, size); ++} ++ ++/* Code for handling simple wildcards without going through fnmatch, ++ which can be expensive because of charset translations etc. */ ++ ++/* A simple wild is a literal string followed by a single '*', ++ where the literal part is at least 4 characters long. */ ++ ++static bool ++is_simple_wild (const char *name) ++{ ++ size_t len = strcspn (name, "*?["); ++ return len >= 4 && name[len] == '*' && name[len + 1] == '\0'; ++} ++ ++static bool ++match_simple_wild (const char *pattern, const char *name) ++{ ++ /* The first four characters of the pattern are guaranteed valid ++ non-wildcard characters. So we can go faster. */ ++ if (pattern[0] != name[0] || pattern[1] != name[1] ++ || pattern[2] != name[2] || pattern[3] != name[3]) ++ return false; ++ ++ pattern += 4; ++ name += 4; ++ while (*pattern != '*') ++ if (*name++ != *pattern++) ++ return false; ++ ++ return true; ++} ++ ++static int ++name_match (const char *pattern, const char *name) ++{ ++ if (is_simple_wild (pattern)) ++ return !match_simple_wild (pattern, name); ++ if (wildcardp (pattern)) ++ return fnmatch (pattern, name, 0); ++ return strcmp (pattern, name); ++} ++ ++/* Given an analyzed wildcard_spec SPEC, match it against NAME, ++ returns zero on a match, non-zero if there's no match. */ ++ ++static int ++spec_match (const struct wildcard_spec *spec, const char *name) ++{ ++ size_t nl = spec->namelen; ++ size_t pl = spec->prefixlen; ++ size_t sl = spec->suffixlen; ++ size_t inputlen = strlen (name); ++ int r; ++ ++ if (pl) ++ { ++ if (inputlen < pl) ++ return 1; ++ ++ r = memcmp (spec->name, name, pl); ++ if (r) ++ return r; ++ } ++ ++ if (sl) ++ { ++ if (inputlen < sl) ++ return 1; ++ ++ r = memcmp (spec->name + nl - sl, name + inputlen - sl, sl); ++ if (r) ++ return r; ++ } ++ ++ if (nl == pl + sl + 1 && spec->name[pl] == '*') ++ return 0; ++ ++ if (nl > pl) ++ return fnmatch (spec->name + pl, name + pl, 0); ++ ++ if (inputlen >= nl) ++ return name[nl]; ++ ++ return 0; ++} ++ ++static char * ++ldirname (const char *name) ++{ ++ const char *base = lbasename (name); ++ char *dirname; ++ ++ while (base > name && IS_DIR_SEPARATOR (base[-1])) ++ --base; ++ if (base == name) ++ return strdup ("."); ++ dirname = strdup (name); ++ dirname[base - name] = '\0'; ++ return dirname; ++} ++ ++/* If PATTERN is of the form archive:file, return a pointer to the ++ separator. If not, return NULL. */ ++ ++static char * ++archive_path (const char *pattern) ++{ ++ char *p = NULL; ++ ++ if (link_info.path_separator == 0) ++ return p; ++ ++ p = strchr (pattern, link_info.path_separator); ++#ifdef HAVE_DOS_BASED_FILE_SYSTEM ++ if (p == NULL || link_info.path_separator != ':') ++ return p; ++ ++ /* Assume a match on the second char is part of drive specifier, ++ as in "c:\silly.dos". */ ++ if (p == pattern + 1 && ISALPHA (*pattern)) ++ p = strchr (p + 1, link_info.path_separator); ++#endif ++ return p; ++} ++ ++/* Given that FILE_SPEC results in a non-NULL SEP result from archive_path, ++ return whether F matches FILE_SPEC. */ ++ ++static bool ++input_statement_is_archive_path (const char *file_spec, char *sep, ++ lang_input_statement_type *f) ++{ ++ bool match = false; ++ ++ if ((*(sep + 1) == 0 ++ || name_match (sep + 1, f->filename) == 0) ++ && ((sep != file_spec) ++ == (f->the_bfd != NULL && f->the_bfd->my_archive != NULL))) ++ { ++ match = true; ++ ++ if (sep != file_spec) ++ { ++ const char *aname = bfd_get_filename (f->the_bfd->my_archive); ++ *sep = 0; ++ match = name_match (file_spec, aname) == 0; ++ *sep = link_info.path_separator; ++ } ++ } ++ return match; ++} ++ ++static bool ++unique_section_p (const asection *sec, ++ const lang_output_section_statement_type *os) ++{ ++ struct unique_sections *unam; ++ const char *secnam; ++ ++ if (!link_info.resolve_section_groups ++ && sec->owner != NULL ++ && bfd_is_group_section (sec->owner, sec)) ++ return !(os != NULL ++ && strcmp (os->name, DISCARD_SECTION_NAME) == 0); ++ ++ secnam = sec->name; ++ for (unam = unique_section_list; unam; unam = unam->next) ++ if (name_match (unam->name, secnam) == 0) ++ return true; ++ ++ return false; ++} ++ ++/* Generic traversal routines for finding matching sections. */ ++ ++/* Return true if FILE matches a pattern in EXCLUDE_LIST, otherwise return ++ false. */ ++ ++static bool ++walk_wild_file_in_exclude_list (struct name_list *exclude_list, ++ lang_input_statement_type *file) ++{ ++ struct name_list *list_tmp; ++ ++ for (list_tmp = exclude_list; ++ list_tmp; ++ list_tmp = list_tmp->next) ++ { ++ char *p = archive_path (list_tmp->name); ++ ++ if (p != NULL) ++ { ++ if (input_statement_is_archive_path (list_tmp->name, p, file)) ++ return true; ++ } ++ ++ else if (name_match (list_tmp->name, file->filename) == 0) ++ return true; ++ ++ /* FIXME: Perhaps remove the following at some stage? Matching ++ unadorned archives like this was never documented and has ++ been superceded by the archive:path syntax. */ ++ else if (file->the_bfd != NULL ++ && file->the_bfd->my_archive != NULL ++ && name_match (list_tmp->name, ++ bfd_get_filename (file->the_bfd->my_archive)) == 0) ++ return true; ++ } ++ ++ return false; ++} ++ ++/* Add SECTION (from input FILE) to the list of matching sections ++ within PTR (the matching wildcard is SEC). */ ++ ++static void ++add_matching_section (lang_wild_statement_type *ptr, ++ struct wildcard_list *sec, ++ asection *section, ++ lang_input_statement_type *file) ++{ ++ lang_input_matcher_type *new_section; ++ /* Add a section reference to the list. */ ++ new_section = new_stat (lang_input_matcher, &ptr->matching_sections); ++ new_section->section = section; ++ new_section->pattern = sec; ++ new_section->input_stmt = file; ++} ++ ++/* Process section S (from input file FILE) in relation to wildcard ++ statement PTR. We already know that a prefix of the name of S matches ++ some wildcard in PTR's wildcard list. Here we check if the filename ++ matches as well (if it's specified) and if any of the wildcards in fact ++ does match. */ ++ ++static void ++walk_wild_section_match (lang_wild_statement_type *ptr, ++ lang_input_statement_type *file, ++ asection *s) ++{ ++ struct wildcard_list *sec; ++ const char *file_spec = ptr->filename; ++ char *p; ++ ++ /* Check if filenames match. */ ++ if (file_spec == NULL) ++ ; ++ else if ((p = archive_path (file_spec)) != NULL) ++ { ++ if (!input_statement_is_archive_path (file_spec, p, file)) ++ return; ++ } ++ else if (wildcardp (file_spec)) ++ { ++ if (fnmatch (file_spec, file->filename, 0) != 0) ++ return; ++ } ++ else ++ { ++ /* XXX Matching against non-wildcard filename in wild statements ++ was done by going through lookup_name, which uses ++ ->local_sym_name to compare against, not ->filename. We retain ++ this behaviour even though the above code paths use filename. ++ It would be more logical to use it here as well, in which ++ case the above wildcard() arm could be folded into this by using ++ name_match. This would also solve the worry of what to do ++ about unset local_sym_name (in which case lookup_name simply adds ++ the input file again). */ ++ const char *filename = file->local_sym_name; ++ lang_input_statement_type *arch_is; ++ if (filename && filename_cmp (filename, file_spec) == 0) ++ ; ++ /* FIXME: see also walk_wild_file_in_exclude_list for why we ++ also check parents BFD (local_sym_)name to match input statements ++ with unadorned archive names. */ ++ else if (file->the_bfd ++ && file->the_bfd->my_archive ++ && (arch_is = bfd_usrdata (file->the_bfd->my_archive)) ++ && arch_is->local_sym_name ++ && filename_cmp (arch_is->local_sym_name, file_spec) == 0) ++ ; ++ else ++ return; ++ } ++ ++ /* If filename is excluded we're done. */ ++ if (walk_wild_file_in_exclude_list (ptr->exclude_name_list, file)) ++ return; ++ ++ /* Check section name against each wildcard spec. If there's no ++ wildcard all sections match. */ ++ sec = ptr->section_list; ++ if (sec == NULL) ++ add_matching_section (ptr, sec, s, file); ++ else ++ { ++ const char *sname = bfd_section_name (s); ++ for (; sec != NULL; sec = sec->next) ++ { ++ if (sec->spec.name != NULL ++ && spec_match (&sec->spec, sname) != 0) ++ continue; ++ ++ /* Don't process sections from files which were excluded. */ ++ if (!walk_wild_file_in_exclude_list (sec->spec.exclude_name_list, ++ file)) ++ add_matching_section (ptr, sec, s, file); ++ } ++ } ++} ++ ++/* Return the numerical value of the init_priority attribute from ++ section name NAME. */ ++ ++static int ++get_init_priority (const asection *sec) ++{ ++ const char *name = bfd_section_name (sec); ++ const char *dot; ++ ++ /* GCC uses the following section names for the init_priority ++ attribute with numerical values 101 to 65535 inclusive. A ++ lower value means a higher priority. ++ ++ 1: .init_array.NNNNN/.fini_array.NNNNN: Where NNNNN is the ++ decimal numerical value of the init_priority attribute. ++ The order of execution in .init_array is forward and ++ .fini_array is backward. ++ 2: .ctors.NNNNN/.dtors.NNNNN: Where NNNNN is 65535 minus the ++ decimal numerical value of the init_priority attribute. ++ The order of execution in .ctors is backward and .dtors ++ is forward. ++ ++ .init_array.NNNNN sections would normally be placed in an output ++ .init_array section, .fini_array.NNNNN in .fini_array, ++ .ctors.NNNNN in .ctors, and .dtors.NNNNN in .dtors. This means ++ we should sort by increasing number (and could just use ++ SORT_BY_NAME in scripts). However if .ctors.NNNNN sections are ++ being placed in .init_array (which may also contain ++ .init_array.NNNNN sections) or .dtors.NNNNN sections are being ++ placed in .fini_array then we need to extract the init_priority ++ attribute and sort on that. */ ++ dot = strrchr (name, '.'); ++ if (dot != NULL && ISDIGIT (dot[1])) ++ { ++ char *end; ++ unsigned long init_priority = strtoul (dot + 1, &end, 10); ++ if (*end == 0) ++ { ++ if (dot == name + 6 ++ && (strncmp (name, ".ctors", 6) == 0 ++ || strncmp (name, ".dtors", 6) == 0)) ++ init_priority = 65535 - init_priority; ++ if (init_priority <= INT_MAX) ++ return init_priority; ++ } ++ } ++ return -1; ++} ++ ++/* Compare sections ASEC and BSEC according to SORT. */ ++ ++static int ++compare_section (sort_type sort, asection *asec, asection *bsec) ++{ ++ int ret; ++ int a_priority, b_priority; ++ ++ switch (sort) ++ { ++ default: ++ abort (); ++ ++ case by_init_priority: ++ a_priority = get_init_priority (asec); ++ b_priority = get_init_priority (bsec); ++ if (a_priority < 0 || b_priority < 0) ++ goto sort_by_name; ++ ret = a_priority - b_priority; ++ if (ret) ++ break; ++ else ++ goto sort_by_name; ++ ++ case by_alignment_name: ++ ret = bfd_section_alignment (bsec) - bfd_section_alignment (asec); ++ if (ret) ++ break; ++ /* Fall through. */ ++ ++ case by_name: ++ sort_by_name: ++ ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec)); ++ break; ++ ++ case by_name_alignment: ++ ret = strcmp (bfd_section_name (asec), bfd_section_name (bsec)); ++ if (ret) ++ break; ++ /* Fall through. */ ++ ++ case by_alignment: ++ ret = bfd_section_alignment (bsec) - bfd_section_alignment (asec); ++ break; ++ } ++ ++ return ret; ++} ++ ++/* PE puts the sort key in the input statement. */ ++ ++static const char * ++sort_filename (bfd *abfd) ++{ ++ lang_input_statement_type *is = bfd_usrdata (abfd); ++ if (is->sort_key) ++ return is->sort_key; ++ return bfd_get_filename (abfd); ++} ++ ++/* Handle wildcard sorting. This returns the place in a binary search tree ++ where this FILE:SECTION should be inserted for wild statement WILD where ++ the spec SEC was the matching one. The tree is later linearized. */ ++ ++static lang_section_bst_type ** ++wild_sort (lang_wild_statement_type *wild, ++ struct wildcard_list *sec, ++ lang_input_statement_type *file, ++ asection *section) ++{ ++ lang_section_bst_type **tree; ++ ++ if (!wild->filenames_sorted ++ && (sec == NULL || sec->spec.sorted == none ++ || sec->spec.sorted == by_none)) ++ { ++ /* We might be called even if _this_ spec doesn't need sorting, ++ in which case we simply append at the right end of tree. */ ++ return wild->rightmost; ++ } ++ ++ tree = &wild->tree; ++ while (*tree) ++ { ++ /* Sorting by filename takes precedence over sorting by section ++ name. */ ++ ++ if (wild->filenames_sorted) ++ { ++ const char *fn, *ln; ++ bool fa, la; ++ int i; ++ asection *lsec = (*tree)->section; ++ ++ /* The PE support for the .idata section as generated by ++ dlltool assumes that files will be sorted by the name of ++ the archive and then the name of the file within the ++ archive. */ ++ ++ fa = file->the_bfd->my_archive != NULL; ++ if (fa) ++ fn = sort_filename (file->the_bfd->my_archive); ++ else ++ fn = sort_filename (file->the_bfd); ++ ++ la = lsec->owner->my_archive != NULL; ++ if (la) ++ ln = sort_filename (lsec->owner->my_archive); ++ else ++ ln = sort_filename (lsec->owner); ++ ++ i = filename_cmp (fn, ln); ++ if (i > 0) ++ { tree = &((*tree)->right); continue; } ++ else if (i < 0) ++ { tree = &((*tree)->left); continue; } ++ ++ if (fa || la) ++ { ++ if (fa) ++ fn = sort_filename (file->the_bfd); ++ if (la) ++ ln = sort_filename (lsec->owner); ++ ++ i = filename_cmp (fn, ln); ++ if (i > 0) ++ { tree = &((*tree)->right); continue; } ++ else if (i < 0) ++ { tree = &((*tree)->left); continue; } ++ } ++ } ++ ++ /* Here either the files are not sorted by name, or we are ++ looking at the sections for this file. */ ++ ++ /* Find the correct node to append this section. */ ++ if (sec && sec->spec.sorted != none && sec->spec.sorted != by_none ++ && compare_section (sec->spec.sorted, section, (*tree)->section) < 0) ++ tree = &((*tree)->left); ++ else ++ tree = &((*tree)->right); ++ } ++ ++ return tree; ++} ++ ++/* Use wild_sort to build a BST to sort sections. */ ++ ++static void ++output_section_callback_sort (lang_wild_statement_type *ptr, ++ struct wildcard_list *sec, ++ asection *section, ++ lang_input_statement_type *file, ++ void *output) ++{ ++ lang_section_bst_type *node; ++ lang_section_bst_type **tree; ++ lang_output_section_statement_type *os; ++ ++ os = (lang_output_section_statement_type *) output; ++ ++ if (unique_section_p (section, os)) ++ return; ++ ++ /* Don't add sections to the tree when we already know that ++ lang_add_section won't do anything with it. */ ++ if (wont_add_section_p (section, os)) ++ return; ++ ++ node = (lang_section_bst_type *) xmalloc (sizeof (lang_section_bst_type)); ++ node->left = 0; ++ node->right = 0; ++ node->section = section; ++ node->pattern = ptr->section_list; ++ ++ tree = wild_sort (ptr, sec, file, section); ++ if (tree != NULL) ++ { ++ *tree = node; ++ if (tree == ptr->rightmost) ++ ptr->rightmost = &node->right; ++ } ++} ++ ++/* Convert a sorted sections' BST back to list form. */ ++ ++static void ++output_section_callback_tree_to_list (lang_wild_statement_type *ptr, ++ lang_section_bst_type *tree, ++ void *output) ++{ ++ if (tree->left) ++ output_section_callback_tree_to_list (ptr, tree->left, output); ++ ++ lang_add_section (&ptr->children, tree->section, tree->pattern, ++ ptr->section_flag_list, ++ (lang_output_section_statement_type *) output); ++ ++ if (tree->right) ++ output_section_callback_tree_to_list (ptr, tree->right, output); ++ ++ free (tree); ++} ++ ++ ++/* Sections are matched against wildcard statements via a prefix tree. ++ The prefix tree holds prefixes of all matching patterns (up to the first ++ wildcard character), and the wild statement from which those patterns ++ came. When matching a section name against the tree we're walking through ++ the tree character by character. Each statement we hit is one that ++ potentially matches. This is checked by actually going through the ++ (glob) matching routines. ++ ++ When the section name turns out to actually match we record that section ++ in the wild statements list of matching sections. */ ++ ++/* A prefix can be matched by multiple statement, so we need a list of them. */ ++struct wild_stmt_list ++{ ++ lang_wild_statement_type *stmt; ++ struct wild_stmt_list *next; ++}; ++ ++/* The prefix tree itself. */ ++struct prefixtree ++{ ++ /* The list of all children (linked via .next). */ ++ struct prefixtree *child; ++ struct prefixtree *next; ++ /* This tree node is responsible for the prefix of parent plus 'c'. */ ++ char c; ++ /* The statements that potentially can match this prefix. */ ++ struct wild_stmt_list *stmt; ++}; ++ ++/* We always have a root node in the prefix tree. It corresponds to the ++ empty prefix. E.g. a glob like "*" would sit in this root. */ ++static struct prefixtree the_root, *ptroot = &the_root; ++ ++/* Given a prefix tree in *TREE, corresponding to prefix P, find or ++ INSERT the tree node corresponding to prefix P+C. */ ++ ++static struct prefixtree * ++get_prefix_tree (struct prefixtree **tree, char c, bool insert) ++{ ++ struct prefixtree *t; ++ for (t = *tree; t; t = t->next) ++ if (t->c == c) ++ return t; ++ if (!insert) ++ return NULL; ++ t = (struct prefixtree *) obstack_alloc (&pt_obstack, sizeof *t); ++ t->child = NULL; ++ t->next = *tree; ++ t->c = c; ++ t->stmt = NULL; ++ *tree = t; ++ return t; ++} ++ ++/* Add STMT to the set of statements that can be matched by the prefix ++ corresponding to prefix tree T. */ ++ ++static void ++pt_add_stmt (struct prefixtree *t, lang_wild_statement_type *stmt) ++{ ++ struct wild_stmt_list *sl, **psl; ++ sl = (struct wild_stmt_list *) obstack_alloc (&pt_obstack, sizeof *sl); ++ sl->stmt = stmt; ++ sl->next = NULL; ++ psl = &t->stmt; ++ while (*psl) ++ psl = &(*psl)->next; ++ *psl = sl; ++} ++ ++/* Insert STMT into the global prefix tree. */ ++ ++static void ++insert_prefix_tree (lang_wild_statement_type *stmt) ++{ ++ struct wildcard_list *sec; ++ struct prefixtree *t; ++ ++ if (!stmt->section_list) ++ { ++ /* If we have no section_list (no wildcards in the wild STMT), ++ then every section name will match, so add this to the root. */ ++ pt_add_stmt (ptroot, stmt); ++ return; ++ } ++ ++ for (sec = stmt->section_list; sec; sec = sec->next) ++ { ++ const char *name = sec->spec.name ? sec->spec.name : "*"; ++ char c; ++ t = ptroot; ++ for (; (c = *name); name++) ++ { ++ if (c == '*' || c == '[' || c == '?') ++ break; ++ t = get_prefix_tree (&t->child, c, true); ++ } ++ /* If we hit a glob character, the matching prefix is what we saw ++ until now. If we hit the end of pattern (hence it's no glob) then ++ we can do better: we only need to record a match when a section name ++ completely matches, not merely a prefix, so record the trailing 0 ++ as well. */ ++ if (!c) ++ t = get_prefix_tree (&t->child, 0, true); ++ pt_add_stmt (t, stmt); ++ } ++} ++ ++/* Dump T indented by INDENT spaces. */ ++ ++static void ++debug_prefix_tree_rec (struct prefixtree *t, int indent) ++{ ++ for (; t; t = t->next) ++ { ++ struct wild_stmt_list *sl; ++ printf ("%*s %c", indent, "", t->c); ++ for (sl = t->stmt; sl; sl = sl->next) ++ { ++ struct wildcard_list *curr; ++ printf (" %p ", sl->stmt); ++ for (curr = sl->stmt->section_list; curr; curr = curr->next) ++ printf ("%s ", curr->spec.name ? curr->spec.name : "*"); ++ } ++ printf ("\n"); ++ debug_prefix_tree_rec (t->child, indent + 2); ++ } ++} ++ ++/* Dump the global prefix tree. */ ++ ++static void ++debug_prefix_tree (void) ++{ ++ debug_prefix_tree_rec (ptroot, 2); ++} ++ ++/* Like strcspn() but start to look from the end to beginning of ++ S. Returns the length of the suffix of S consisting entirely ++ of characters not in REJECT. */ ++ ++static size_t ++rstrcspn (const char *s, const char *reject) ++{ ++ size_t len = strlen (s), sufflen = 0; ++ while (len--) ++ { ++ char c = s[len]; ++ if (strchr (reject, c) != 0) ++ break; ++ sufflen++; ++ } ++ return sufflen; ++} ++ ++/* Analyze the wildcards in wild statement PTR to setup various ++ things for quick matching. */ ++ ++static void ++analyze_walk_wild_section_handler (lang_wild_statement_type *ptr) ++{ ++ struct wildcard_list *sec; ++ ++ ptr->tree = NULL; ++ ptr->rightmost = &ptr->tree; ++ ++ for (sec = ptr->section_list; sec != NULL; sec = sec->next) ++ { ++ if (sec->spec.name) ++ { ++ sec->spec.namelen = strlen (sec->spec.name); ++ sec->spec.prefixlen = strcspn (sec->spec.name, "?*["); ++ sec->spec.suffixlen = rstrcspn (sec->spec.name + sec->spec.prefixlen, ++ "?*]"); ++ } ++ else ++ sec->spec.namelen = sec->spec.prefixlen = sec->spec.suffixlen = 0; ++ } ++ ++ insert_prefix_tree (ptr); ++} ++ ++/* Match all sections from FILE against the global prefix tree, ++ and record them into each wild statement that has a match. */ ++ ++static void ++resolve_wild_sections (lang_input_statement_type *file) ++{ ++ asection *s; ++ ++ if (file->flags.just_syms) ++ return; ++ ++ for (s = file->the_bfd->sections; s != NULL; s = s->next) ++ { ++ const char *sname = bfd_section_name (s); ++ char c = 1; ++ struct prefixtree *t = ptroot; ++ //printf (" YYY consider %s of %s\n", sname, file->the_bfd->filename); ++ do ++ { ++ if (t->stmt) ++ { ++ struct wild_stmt_list *sl; ++ for (sl = t->stmt; sl; sl = sl->next) ++ { ++ walk_wild_section_match (sl->stmt, file, s); ++ //printf (" ZZZ maybe place into %p\n", sl->stmt); ++ } ++ } ++ if (!c) ++ break; ++ c = *sname++; ++ t = get_prefix_tree (&t->child, c, false); ++ } ++ while (t); ++ } ++} ++ ++/* Match all sections from all input files against the global prefix tree. */ ++ ++static void ++resolve_wilds (void) ++{ ++ LANG_FOR_EACH_INPUT_STATEMENT (f) ++ { ++ //printf("XXX %s\n", f->filename); ++ if (f->the_bfd == NULL ++ || !bfd_check_format (f->the_bfd, bfd_archive)) ++ resolve_wild_sections (f); ++ else ++ { ++ bfd *member; ++ ++ /* This is an archive file. We must map each member of the ++ archive separately. */ ++ member = bfd_openr_next_archived_file (f->the_bfd, NULL); ++ while (member != NULL) ++ { ++ /* When lookup_name is called, it will call the add_symbols ++ entry point for the archive. For each element of the ++ archive which is included, BFD will call ldlang_add_file, ++ which will set the usrdata field of the member to the ++ lang_input_statement. */ ++ if (bfd_usrdata (member) != NULL) ++ resolve_wild_sections (bfd_usrdata (member)); ++ ++ member = bfd_openr_next_archived_file (f->the_bfd, member); ++ } ++ } ++ } ++} ++ ++/* For each input section that matches wild statement S calls ++ CALLBACK with DATA. */ ++ ++static void ++walk_wild (lang_wild_statement_type *s, callback_t callback, void *data) ++{ ++ lang_statement_union_type *l; ++ ++ for (l = s->matching_sections.head; l; l = l->header.next) ++ { ++ (*callback) (s, l->input_matcher.pattern, l->input_matcher.section, ++ l->input_matcher.input_stmt, data); ++ } ++} ++ ++/* lang_for_each_statement walks the parse tree and calls the provided ++ function for each node, except those inside output section statements ++ with constraint set to -1. */ ++ ++void ++lang_for_each_statement_worker (void (*func) (lang_statement_union_type *), ++ lang_statement_union_type *s) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ func (s); ++ ++ switch (s->header.type) ++ { ++ case lang_constructors_statement_enum: ++ lang_for_each_statement_worker (func, constructor_list.head); ++ break; ++ case lang_output_section_statement_enum: ++ if (s->output_section_statement.constraint != -1) ++ lang_for_each_statement_worker ++ (func, s->output_section_statement.children.head); ++ break; ++ case lang_wild_statement_enum: ++ lang_for_each_statement_worker (func, ++ s->wild_statement.children.head); ++ break; ++ case lang_group_statement_enum: ++ lang_for_each_statement_worker (func, ++ s->group_statement.children.head); ++ break; ++ case lang_data_statement_enum: ++ case lang_reloc_statement_enum: ++ case lang_object_symbols_statement_enum: ++ case lang_output_statement_enum: ++ case lang_target_statement_enum: ++ case lang_input_section_enum: ++ case lang_input_statement_enum: ++ case lang_assignment_statement_enum: ++ case lang_padding_statement_enum: ++ case lang_address_statement_enum: ++ case lang_fill_statement_enum: ++ case lang_insert_statement_enum: ++ break; ++ default: ++ FAIL (); ++ break; ++ } ++ } ++} ++ ++void ++lang_for_each_statement (void (*func) (lang_statement_union_type *)) ++{ ++ lang_for_each_statement_worker (func, statement_list.head); ++} ++ ++/*----------------------------------------------------------------------*/ ++ ++void ++lang_list_init (lang_statement_list_type *list) ++{ ++ list->head = NULL; ++ list->tail = &list->head; ++} ++ ++static void ++lang_statement_append (lang_statement_list_type *list, ++ void *element, ++ void *field) ++{ ++ *(list->tail) = element; ++ list->tail = field; ++} ++ ++void ++push_stat_ptr (lang_statement_list_type *new_ptr) ++{ ++ if (stat_save_ptr >= stat_save + sizeof (stat_save) / sizeof (stat_save[0])) ++ abort (); ++ *stat_save_ptr++ = stat_ptr; ++ stat_ptr = new_ptr; ++} ++ ++void ++pop_stat_ptr (void) ++{ ++ if (stat_save_ptr <= stat_save) ++ abort (); ++ stat_ptr = *--stat_save_ptr; ++} ++ ++/* Build a new statement node for the parse tree. */ ++ ++static lang_statement_union_type * ++new_statement (enum statement_enum type, ++ size_t size, ++ lang_statement_list_type *list) ++{ ++ lang_statement_union_type *new_stmt; ++ ++ new_stmt = stat_alloc (size); ++ new_stmt->header.type = type; ++ new_stmt->header.next = NULL; ++ lang_statement_append (list, new_stmt, &new_stmt->header.next); ++ return new_stmt; ++} ++ ++/* Build a new input file node for the language. There are several ++ ways in which we treat an input file, eg, we only look at symbols, ++ or prefix it with a -l etc. ++ ++ We can be supplied with requests for input files more than once; ++ they may, for example be split over several lines like foo.o(.text) ++ foo.o(.data) etc, so when asked for a file we check that we haven't ++ got it already so we don't duplicate the bfd. */ ++ ++static lang_input_statement_type * ++new_afile (const char *name, ++ lang_input_file_enum_type file_type, ++ const char *target, ++ const char *from_filename) ++{ ++ lang_input_statement_type *p; ++ ++ lang_has_input_file = true; ++ ++ /* PR 30632: It is OK for name to be NULL. For example ++ see the initialization of first_file in lang_init(). */ ++ if (name != NULL) ++ { ++ name = ldfile_possibly_remap_input (name); ++ /* But if a name is remapped to NULL, it should be ignored. */ ++ if (name == NULL) ++ return NULL; ++ } ++ ++ p = new_stat (lang_input_statement, stat_ptr); ++ memset (&p->the_bfd, 0, ++ sizeof (*p) - offsetof (lang_input_statement_type, the_bfd)); ++ p->extra_search_path = NULL; ++ p->target = target; ++ p->flags.dynamic = input_flags.dynamic; ++ p->flags.add_DT_NEEDED_for_dynamic = input_flags.add_DT_NEEDED_for_dynamic; ++ p->flags.add_DT_NEEDED_for_regular = input_flags.add_DT_NEEDED_for_regular; ++ p->flags.whole_archive = input_flags.whole_archive; ++ p->flags.sysrooted = input_flags.sysrooted; ++ p->sort_key = NULL; ++ ++ switch (file_type) ++ { ++ case lang_input_file_is_symbols_only_enum: ++ p->filename = name; ++ p->local_sym_name = name; ++ p->flags.real = true; ++ p->flags.just_syms = true; ++ break; ++ case lang_input_file_is_fake_enum: ++ p->filename = name; ++ p->local_sym_name = name; ++ break; ++ case lang_input_file_is_l_enum: ++ if (name[0] == ':' && name[1] != '\0') ++ { ++ p->filename = name + 1; ++ p->flags.full_name_provided = true; ++ } ++ else ++ p->filename = name; ++ p->local_sym_name = concat ("-l", name, (const char *) NULL); ++ p->flags.maybe_archive = true; ++ p->flags.real = true; ++ p->flags.search_dirs = true; ++ break; ++ case lang_input_file_is_marker_enum: ++ p->filename = name; ++ p->local_sym_name = name; ++ p->flags.search_dirs = true; ++ break; ++ case lang_input_file_is_search_file_enum: ++ p->filename = name; ++ p->local_sym_name = name; ++ /* If name is a relative path, search the directory of the current linker ++ script first. */ ++ if (from_filename && !IS_ABSOLUTE_PATH (name)) ++ p->extra_search_path = ldirname (from_filename); ++ p->flags.real = true; ++ p->flags.search_dirs = true; ++ break; ++ case lang_input_file_is_file_enum: ++ p->filename = name; ++ p->local_sym_name = name; ++ p->flags.real = true; ++ break; ++ default: ++ FAIL (); ++ } ++ ++ lang_statement_append (&input_file_chain, p, &p->next_real_file); ++ return p; ++} ++ ++lang_input_statement_type * ++lang_add_input_file (const char *name, ++ lang_input_file_enum_type file_type, ++ const char *target) ++{ ++ if (name != NULL ++ && (*name == '=' || startswith (name, "$SYSROOT"))) ++ { ++ lang_input_statement_type *ret; ++ char *sysrooted_name ++ = concat (ld_sysroot, ++ name + (*name == '=' ? 1 : strlen ("$SYSROOT")), ++ (const char *) NULL); ++ ++ /* We've now forcibly prepended the sysroot, making the input ++ file independent of the context. Therefore, temporarily ++ force a non-sysrooted context for this statement, so it won't ++ get the sysroot prepended again when opened. (N.B. if it's a ++ script, any child nodes with input files starting with "/" ++ will be handled as "sysrooted" as they'll be found to be ++ within the sysroot subdirectory.) */ ++ unsigned int outer_sysrooted = input_flags.sysrooted; ++ input_flags.sysrooted = 0; ++ ret = new_afile (sysrooted_name, file_type, target, NULL); ++ input_flags.sysrooted = outer_sysrooted; ++ return ret; ++ } ++ ++ return new_afile (name, file_type, target, current_input_file); ++} ++ ++struct out_section_hash_entry ++{ ++ struct bfd_hash_entry root; ++ lang_statement_union_type s; ++}; ++ ++/* The hash table. */ ++ ++static struct bfd_hash_table output_section_statement_table; ++ ++/* Support routines for the hash table used by lang_output_section_find, ++ initialize the table, fill in an entry and remove the table. */ ++ ++static struct bfd_hash_entry * ++output_section_statement_newfunc (struct bfd_hash_entry *entry, ++ struct bfd_hash_table *table, ++ const char *string) ++{ ++ lang_output_section_statement_type **nextp; ++ struct out_section_hash_entry *ret; ++ ++ if (entry == NULL) ++ { ++ entry = (struct bfd_hash_entry *) bfd_hash_allocate (table, ++ sizeof (*ret)); ++ if (entry == NULL) ++ return entry; ++ } ++ ++ entry = bfd_hash_newfunc (entry, table, string); ++ if (entry == NULL) ++ return entry; ++ ++ ret = (struct out_section_hash_entry *) entry; ++ memset (&ret->s, 0, sizeof (ret->s)); ++ ret->s.header.type = lang_output_section_statement_enum; ++ ret->s.output_section_statement.subsection_alignment = NULL; ++ ret->s.output_section_statement.section_alignment = NULL; ++ ret->s.output_section_statement.block_value = 1; ++ lang_list_init (&ret->s.output_section_statement.children); ++ lang_statement_append (stat_ptr, &ret->s, &ret->s.header.next); ++ ++ /* For every output section statement added to the list, except the ++ first one, lang_os_list.tail points to the "next" ++ field of the last element of the list. */ ++ if (lang_os_list.head != NULL) ++ ret->s.output_section_statement.prev ++ = ((lang_output_section_statement_type *) ++ ((char *) lang_os_list.tail ++ - offsetof (lang_output_section_statement_type, next))); ++ ++ /* GCC's strict aliasing rules prevent us from just casting the ++ address, so we store the pointer in a variable and cast that ++ instead. */ ++ nextp = &ret->s.output_section_statement.next; ++ lang_statement_append (&lang_os_list, &ret->s, nextp); ++ return &ret->root; ++} ++ ++static void ++output_section_statement_table_init (void) ++{ ++ if (!bfd_hash_table_init_n (&output_section_statement_table, ++ output_section_statement_newfunc, ++ sizeof (struct out_section_hash_entry), ++ 61)) ++ einfo (_("%F%P: can not create hash table: %E\n")); ++} ++ ++static void ++output_section_statement_table_free (void) ++{ ++ bfd_hash_table_free (&output_section_statement_table); ++} ++ ++/* Build enough state so that the parser can build its tree. */ ++ ++void ++lang_init (void) ++{ ++ obstack_begin (&stat_obstack, 1000); ++ obstack_init (&pt_obstack); ++ ++ stat_ptr = &statement_list; ++ ++ output_section_statement_table_init (); ++ ++ lang_list_init (stat_ptr); ++ ++ lang_list_init (&input_file_chain); ++ lang_list_init (&lang_os_list); ++ lang_list_init (&file_chain); ++ first_file = lang_add_input_file (NULL, lang_input_file_is_marker_enum, ++ NULL); ++ abs_output_section = ++ lang_output_section_statement_lookup (BFD_ABS_SECTION_NAME, 0, 1); ++ ++ abs_output_section->bfd_section = bfd_abs_section_ptr; ++ ++ asneeded_list_head = NULL; ++ asneeded_list_tail = &asneeded_list_head; ++} ++ ++void ++lang_finish (void) ++{ ++ output_section_statement_table_free (); ++ ldfile_remap_input_free (); ++} ++ ++/*---------------------------------------------------------------------- ++ A region is an area of memory declared with the ++ MEMORY { name:org=exp, len=exp ... } ++ syntax. ++ ++ We maintain a list of all the regions here. ++ ++ If no regions are specified in the script, then the default is used ++ which is created when looked up to be the entire data space. ++ ++ If create is true we are creating a region inside a MEMORY block. ++ In this case it is probably an error to create a region that has ++ already been created. If we are not inside a MEMORY block it is ++ dubious to use an undeclared region name (except DEFAULT_MEMORY_REGION) ++ and so we issue a warning. ++ ++ Each region has at least one name. The first name is either ++ DEFAULT_MEMORY_REGION or the name given in the MEMORY block. You can add ++ alias names to an existing region within a script with ++ REGION_ALIAS (alias, region_name). Each name corresponds to at most one ++ region. */ ++ ++static lang_memory_region_type *lang_memory_region_list; ++static lang_memory_region_type **lang_memory_region_list_tail ++ = &lang_memory_region_list; ++ ++lang_memory_region_type * ++lang_memory_region_lookup (const char *const name, bool create) ++{ ++ lang_memory_region_name *n; ++ lang_memory_region_type *r; ++ lang_memory_region_type *new_region; ++ ++ /* NAME is NULL for LMA memspecs if no region was specified. */ ++ if (name == NULL) ++ return NULL; ++ ++ for (r = lang_memory_region_list; r != NULL; r = r->next) ++ for (n = &r->name_list; n != NULL; n = n->next) ++ if (strcmp (n->name, name) == 0) ++ { ++ if (create) ++ einfo (_("%P:%pS: warning: redeclaration of memory region `%s'\n"), ++ NULL, name); ++ return r; ++ } ++ ++ if (!create && strcmp (name, DEFAULT_MEMORY_REGION)) ++ einfo (_("%P:%pS: warning: memory region `%s' not declared\n"), ++ NULL, name); ++ ++ new_region = stat_alloc (sizeof (lang_memory_region_type)); ++ ++ new_region->name_list.name = xstrdup (name); ++ new_region->name_list.next = NULL; ++ new_region->next = NULL; ++ new_region->origin_exp = NULL; ++ new_region->origin = 0; ++ new_region->length_exp = NULL; ++ new_region->length = ~(bfd_size_type) 0; ++ new_region->current = 0; ++ new_region->last_os = NULL; ++ new_region->flags = 0; ++ new_region->not_flags = 0; ++ new_region->had_full_message = false; ++ ++ *lang_memory_region_list_tail = new_region; ++ lang_memory_region_list_tail = &new_region->next; ++ ++ return new_region; ++} ++ ++void ++lang_memory_region_alias (const char *alias, const char *region_name) ++{ ++ lang_memory_region_name *n; ++ lang_memory_region_type *r; ++ lang_memory_region_type *region; ++ ++ /* The default region must be unique. This ensures that it is not necessary ++ to iterate through the name list if someone wants the check if a region is ++ the default memory region. */ ++ if (strcmp (region_name, DEFAULT_MEMORY_REGION) == 0 ++ || strcmp (alias, DEFAULT_MEMORY_REGION) == 0) ++ einfo (_("%F%P:%pS: error: alias for default memory region\n"), NULL); ++ ++ /* Look for the target region and check if the alias is not already ++ in use. */ ++ region = NULL; ++ for (r = lang_memory_region_list; r != NULL; r = r->next) ++ for (n = &r->name_list; n != NULL; n = n->next) ++ { ++ if (region == NULL && strcmp (n->name, region_name) == 0) ++ region = r; ++ if (strcmp (n->name, alias) == 0) ++ einfo (_("%F%P:%pS: error: redefinition of memory region " ++ "alias `%s'\n"), ++ NULL, alias); ++ } ++ ++ /* Check if the target region exists. */ ++ if (region == NULL) ++ einfo (_("%F%P:%pS: error: memory region `%s' " ++ "for alias `%s' does not exist\n"), ++ NULL, region_name, alias); ++ ++ /* Add alias to region name list. */ ++ n = stat_alloc (sizeof (lang_memory_region_name)); ++ n->name = xstrdup (alias); ++ n->next = region->name_list.next; ++ region->name_list.next = n; ++} ++ ++static lang_memory_region_type * ++lang_memory_default (asection *section) ++{ ++ lang_memory_region_type *p; ++ ++ flagword sec_flags = section->flags; ++ ++ /* Override SEC_DATA to mean a writable section. */ ++ if ((sec_flags & (SEC_ALLOC | SEC_READONLY | SEC_CODE)) == SEC_ALLOC) ++ sec_flags |= SEC_DATA; ++ ++ for (p = lang_memory_region_list; p != NULL; p = p->next) ++ { ++ if ((p->flags & sec_flags) != 0 ++ && (p->not_flags & sec_flags) == 0) ++ { ++ return p; ++ } ++ } ++ return lang_memory_region_lookup (DEFAULT_MEMORY_REGION, false); ++} ++ ++/* Get the output section statement directly from the userdata. */ ++ ++lang_output_section_statement_type * ++lang_output_section_get (const asection *output_section) ++{ ++ return bfd_section_userdata (output_section); ++} ++ ++/* Find or create an output_section_statement with the given NAME. ++ If CONSTRAINT is non-zero match one with that constraint, otherwise ++ match any non-negative constraint. If CREATE is 0 return NULL when ++ no match exists. If CREATE is 1, create an output_section_statement ++ when no match exists or if CONSTRAINT is SPECIAL. If CREATE is 2, ++ always make a new output_section_statement. */ ++ ++lang_output_section_statement_type * ++lang_output_section_statement_lookup (const char *name, ++ int constraint, ++ int create) ++{ ++ struct out_section_hash_entry *entry; ++ ++ entry = ((struct out_section_hash_entry *) ++ bfd_hash_lookup (&output_section_statement_table, name, ++ create != 0, false)); ++ if (entry == NULL) ++ { ++ if (create) ++ einfo (_("%F%P: failed creating section `%s': %E\n"), name); ++ return NULL; ++ } ++ ++ if (entry->s.output_section_statement.name != NULL) ++ { ++ /* We have a section of this name, but it might not have the correct ++ constraint. */ ++ struct out_section_hash_entry *last_ent; ++ ++ name = entry->s.output_section_statement.name; ++ do ++ { ++ if (create != 2 ++ && !(create && constraint == SPECIAL) ++ && (constraint == entry->s.output_section_statement.constraint ++ || (constraint == 0 ++ && entry->s.output_section_statement.constraint >= 0))) ++ return &entry->s.output_section_statement; ++ last_ent = entry; ++ entry = (struct out_section_hash_entry *) entry->root.next; ++ } ++ while (entry != NULL ++ && name == entry->s.output_section_statement.name); ++ ++ if (!create) ++ return NULL; ++ ++ entry ++ = ((struct out_section_hash_entry *) ++ output_section_statement_newfunc (NULL, ++ &output_section_statement_table, ++ name)); ++ if (entry == NULL) ++ { ++ einfo (_("%F%P: failed creating section `%s': %E\n"), name); ++ return NULL; ++ } ++ entry->root = last_ent->root; ++ last_ent->root.next = &entry->root; ++ } ++ ++ entry->s.output_section_statement.name = name; ++ entry->s.output_section_statement.constraint = constraint; ++ entry->s.output_section_statement.dup_output = (create == 2 ++ || constraint == SPECIAL); ++ return &entry->s.output_section_statement; ++} ++ ++/* Find the next output_section_statement with the same name as OS. ++ If CONSTRAINT is non-zero, find one with that constraint otherwise ++ match any non-negative constraint. */ ++ ++lang_output_section_statement_type * ++next_matching_output_section_statement (lang_output_section_statement_type *os, ++ int constraint) ++{ ++ /* All output_section_statements are actually part of a ++ struct out_section_hash_entry. */ ++ struct out_section_hash_entry *entry = (struct out_section_hash_entry *) ++ ((char *) os ++ - offsetof (struct out_section_hash_entry, s.output_section_statement)); ++ const char *name = os->name; ++ ++ ASSERT (name == entry->root.string); ++ do ++ { ++ entry = (struct out_section_hash_entry *) entry->root.next; ++ if (entry == NULL ++ || name != entry->s.output_section_statement.name) ++ return NULL; ++ } ++ while (constraint != entry->s.output_section_statement.constraint ++ && (constraint != 0 ++ || entry->s.output_section_statement.constraint < 0)); ++ ++ return &entry->s.output_section_statement; ++} ++ ++/* A variant of lang_output_section_find used by place_orphan. ++ Returns the output statement that should precede a new output ++ statement for SEC. If an exact match is found on certain flags, ++ sets *EXACT too. */ ++ ++lang_output_section_statement_type * ++lang_output_section_find_by_flags (const asection *sec, ++ flagword sec_flags, ++ lang_output_section_statement_type **exact, ++ lang_match_sec_type_func match_type) ++{ ++ lang_output_section_statement_type *first, *look, *found; ++ flagword look_flags, differ; ++ ++ /* We know the first statement on this list is *ABS*. May as well ++ skip it. */ ++ first = (void *) lang_os_list.head; ++ first = first->next; ++ ++ /* First try for an exact match. */ ++ found = NULL; ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_READONLY ++ | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) ++ found = look; ++ } ++ if (found != NULL) ++ { ++ if (exact != NULL) ++ *exact = found; ++ return found; ++ } ++ ++ if ((sec_flags & SEC_CODE) != 0 ++ && (sec_flags & SEC_ALLOC) != 0) ++ { ++ /* Try for a rw code section. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD ++ | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) ++ found = look; ++ } ++ } ++ else if ((sec_flags & SEC_READONLY) != 0 ++ && (sec_flags & SEC_ALLOC) != 0) ++ { ++ /* .rodata can go after .text, .sdata2 after .rodata. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD ++ | SEC_READONLY | SEC_SMALL_DATA)) ++ || (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD ++ | SEC_READONLY)) ++ && !(look_flags & SEC_SMALL_DATA))) ++ found = look; ++ } ++ } ++ else if ((sec_flags & SEC_THREAD_LOCAL) != 0 ++ && (sec_flags & SEC_ALLOC) != 0) ++ { ++ /* .tdata can go after .data, .tbss after .tdata. Treat .tbss ++ as if it were a loaded section, and don't use match_type. */ ++ bool seen_thread_local = false; ++ ++ match_type = NULL; ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ look_flags = look->bfd_section->flags; ++ ++ differ = look_flags ^ (sec_flags | SEC_LOAD | SEC_HAS_CONTENTS); ++ if (!(differ & (SEC_THREAD_LOCAL | SEC_ALLOC))) ++ { ++ /* .tdata and .tbss must be adjacent and in that order. */ ++ if (!(look_flags & SEC_LOAD) ++ && (sec_flags & SEC_LOAD)) ++ /* ..so if we're at a .tbss section and we're placing ++ a .tdata section stop looking and return the ++ previous section. */ ++ break; ++ found = look; ++ seen_thread_local = true; ++ } ++ else if (seen_thread_local) ++ break; ++ else if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD))) ++ found = look; ++ } ++ } ++ else if ((sec_flags & SEC_SMALL_DATA) != 0 ++ && (sec_flags & SEC_ALLOC) != 0) ++ { ++ /* .sdata goes after .data, .sbss after .sdata. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD ++ | SEC_THREAD_LOCAL)) ++ || ((look_flags & SEC_SMALL_DATA) ++ && !(sec_flags & SEC_HAS_CONTENTS))) ++ found = look; ++ } ++ } ++ else if ((sec_flags & SEC_HAS_CONTENTS) != 0 ++ && (sec_flags & SEC_ALLOC) != 0) ++ { ++ /* .data goes after .rodata. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD ++ | SEC_SMALL_DATA | SEC_THREAD_LOCAL))) ++ found = look; ++ } ++ } ++ else if ((sec_flags & SEC_ALLOC) != 0) ++ { ++ /* .bss goes after any other alloc section. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ { ++ look_flags = look->bfd_section->flags; ++ if (match_type && !match_type (link_info.output_bfd, ++ look->bfd_section, ++ sec->owner, sec)) ++ continue; ++ } ++ differ = look_flags ^ sec_flags; ++ if (!(differ & SEC_ALLOC)) ++ found = look; ++ } ++ } ++ else ++ { ++ /* non-alloc go last. */ ++ for (look = first; look; look = look->next) ++ { ++ look_flags = look->flags; ++ if (look->bfd_section != NULL) ++ look_flags = look->bfd_section->flags; ++ differ = look_flags ^ sec_flags; ++ if (!(differ & SEC_DEBUGGING)) ++ found = look; ++ } ++ return found; ++ } ++ ++ if (found || !match_type) ++ return found; ++ ++ return lang_output_section_find_by_flags (sec, sec_flags, NULL, NULL); ++} ++ ++/* Find the last output section before given output statement. ++ Used by place_orphan. */ ++ ++static asection * ++output_prev_sec_find (lang_output_section_statement_type *os) ++{ ++ lang_output_section_statement_type *lookup; ++ ++ for (lookup = os->prev; lookup != NULL; lookup = lookup->prev) ++ { ++ if (lookup->constraint < 0) ++ continue; ++ ++ if (lookup->bfd_section != NULL) ++ return lookup->bfd_section; ++ } ++ ++ return NULL; ++} ++ ++/* Look for a suitable place for a new output section statement. The ++ idea is to skip over anything that might be inside a SECTIONS {} ++ statement in a script, before we find another output section ++ statement. Assignments to "dot" before an output section statement ++ are assumed to belong to it, except in two cases; The first ++ assignment to dot, and assignments before non-alloc sections. ++ Otherwise we might put an orphan before . = . + SIZEOF_HEADERS or ++ similar assignments that set the initial address, or we might ++ insert non-alloc note sections among assignments setting end of ++ image symbols. */ ++ ++static lang_statement_union_type ** ++insert_os_after (lang_statement_union_type *after) ++{ ++ lang_statement_union_type **where; ++ lang_statement_union_type **assign = NULL; ++ bool ignore_first; ++ ++ ignore_first = after == lang_os_list.head; ++ ++ for (where = &after->header.next; ++ *where != NULL; ++ where = &(*where)->header.next) ++ { ++ switch ((*where)->header.type) ++ { ++ case lang_assignment_statement_enum: ++ if (assign == NULL) ++ { ++ lang_assignment_statement_type *ass; ++ ++ ass = &(*where)->assignment_statement; ++ if (ass->exp->type.node_class != etree_assert ++ && ass->exp->assign.dst[0] == '.' ++ && ass->exp->assign.dst[1] == 0) ++ { ++ if (!ignore_first) ++ assign = where; ++ ignore_first = false; ++ } ++ } ++ continue; ++ case lang_wild_statement_enum: ++ case lang_input_section_enum: ++ case lang_object_symbols_statement_enum: ++ case lang_fill_statement_enum: ++ case lang_data_statement_enum: ++ case lang_reloc_statement_enum: ++ case lang_padding_statement_enum: ++ case lang_constructors_statement_enum: ++ assign = NULL; ++ ignore_first = false; ++ continue; ++ case lang_output_section_statement_enum: ++ if (assign != NULL) ++ { ++ asection *s = (*where)->output_section_statement.bfd_section; ++ ++ if (s == NULL ++ || s->map_head.s == NULL ++ || (s->flags & SEC_ALLOC) != 0) ++ where = assign; ++ } ++ break; ++ case lang_input_statement_enum: ++ case lang_address_statement_enum: ++ case lang_target_statement_enum: ++ case lang_output_statement_enum: ++ case lang_group_statement_enum: ++ case lang_insert_statement_enum: ++ continue; ++ case lang_input_matcher_enum: ++ FAIL (); ++ } ++ break; ++ } ++ ++ return where; ++} ++ ++lang_output_section_statement_type * ++lang_insert_orphan (asection *s, ++ const char *secname, ++ int constraint, ++ lang_output_section_statement_type *after, ++ struct orphan_save *place, ++ etree_type *address, ++ lang_statement_list_type *add_child) ++{ ++ lang_statement_list_type add; ++ lang_output_section_statement_type *os; ++ lang_output_section_statement_type **os_tail; ++ ++ /* If we have found an appropriate place for the output section ++ statements for this orphan, add them to our own private list, ++ inserting them later into the global statement list. */ ++ if (after != NULL) ++ { ++ lang_list_init (&add); ++ push_stat_ptr (&add); ++ } ++ ++ if (bfd_link_relocatable (&link_info) ++ || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0) ++ address = exp_intop (0); ++ ++ os_tail = (lang_output_section_statement_type **) lang_os_list.tail; ++ os = lang_enter_output_section_statement ( ++ secname, address, normal_section, 0, NULL, NULL, NULL, constraint, 0); ++ ++ if (add_child == NULL) ++ add_child = &os->children; ++ lang_add_section (add_child, s, NULL, NULL, os); ++ ++ if (after && (s->flags & (SEC_LOAD | SEC_ALLOC)) != 0) ++ { ++ const char *region = (after->region ++ ? after->region->name_list.name ++ : DEFAULT_MEMORY_REGION); ++ const char *lma_region = (after->lma_region ++ ? after->lma_region->name_list.name ++ : NULL); ++ lang_leave_output_section_statement (NULL, region, after->phdrs, ++ lma_region); ++ } ++ else ++ lang_leave_output_section_statement (NULL, DEFAULT_MEMORY_REGION, NULL, ++ NULL); ++ ++ /* Restore the global list pointer. */ ++ if (after != NULL) ++ pop_stat_ptr (); ++ ++ if (after != NULL && os->bfd_section != NULL) ++ { ++ asection *snew, *as; ++ bool place_after = place->stmt == NULL; ++ bool insert_after = true; ++ ++ snew = os->bfd_section; ++ ++ /* Shuffle the bfd section list to make the output file look ++ neater. This is really only cosmetic. */ ++ if (place->section == NULL ++ && after != (void *) lang_os_list.head) ++ { ++ asection *bfd_section = after->bfd_section; ++ ++ /* If the output statement hasn't been used to place any input ++ sections (and thus doesn't have an output bfd_section), ++ look for the closest prior output statement having an ++ output section. */ ++ if (bfd_section == NULL) ++ bfd_section = output_prev_sec_find (after); ++ ++ if (bfd_section != NULL ++ && bfd_section->owner != NULL ++ && bfd_section != snew) ++ place->section = &bfd_section->next; ++ } ++ ++ if (place->section == NULL) ++ place->section = &link_info.output_bfd->sections; ++ ++ as = *place->section; ++ ++ if (!as) ++ { ++ /* Put the section at the end of the list. */ ++ ++ /* Unlink the section. */ ++ bfd_section_list_remove (link_info.output_bfd, snew); ++ ++ /* Now tack it back on in the right place. */ ++ bfd_section_list_append (link_info.output_bfd, snew); ++ } ++ else if ((bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_elf_flavour) ++ && (bfd_get_flavour (s->owner) ++ == bfd_target_elf_flavour) ++ && ((elf_section_type (s) == SHT_NOTE ++ && (s->flags & SEC_LOAD) != 0) ++ || (elf_section_type (as) == SHT_NOTE ++ && (as->flags & SEC_LOAD) != 0))) ++ { ++ /* Make sure that output note sections are grouped and sorted ++ by alignments when inserting a note section or insert a ++ section after a note section, */ ++ asection *sec; ++ /* A specific section after which the output note section ++ should be placed. */ ++ asection *after_sec; ++ /* True if we need to insert the orphan section after a ++ specific section to maintain output note section order. */ ++ bool after_sec_note = false; ++ ++ static asection *first_orphan_note = NULL; ++ ++ /* Group and sort output note section by alignments in ++ ascending order. */ ++ after_sec = NULL; ++ if (elf_section_type (s) == SHT_NOTE ++ && (s->flags & SEC_LOAD) != 0) ++ { ++ /* Search from the beginning for the last output note ++ section with equal or larger alignments. NB: Don't ++ place orphan note section after non-note sections. */ ++ ++ first_orphan_note = NULL; ++ for (sec = link_info.output_bfd->sections; ++ (sec != NULL ++ && !bfd_is_abs_section (sec)); ++ sec = sec->next) ++ if (sec != snew ++ && elf_section_type (sec) == SHT_NOTE ++ && (sec->flags & SEC_LOAD) != 0) ++ { ++ if (!first_orphan_note) ++ first_orphan_note = sec; ++ if (sec->alignment_power >= s->alignment_power) ++ after_sec = sec; ++ } ++ else if (first_orphan_note) ++ { ++ /* Stop if there is non-note section after the first ++ orphan note section. */ ++ break; ++ } ++ ++ /* If this will be the first orphan note section, it can ++ be placed at the default location. */ ++ after_sec_note = first_orphan_note != NULL; ++ if (after_sec == NULL && after_sec_note) ++ { ++ /* If all output note sections have smaller ++ alignments, place the section before all ++ output orphan note sections. */ ++ after_sec = first_orphan_note; ++ insert_after = false; ++ } ++ } ++ else if (first_orphan_note) ++ { ++ /* Don't place non-note sections in the middle of orphan ++ note sections. */ ++ after_sec_note = true; ++ after_sec = as; ++ for (sec = as->next; ++ (sec != NULL ++ && !bfd_is_abs_section (sec)); ++ sec = sec->next) ++ if (elf_section_type (sec) == SHT_NOTE ++ && (sec->flags & SEC_LOAD) != 0) ++ after_sec = sec; ++ } ++ ++ if (after_sec_note) ++ { ++ if (after_sec) ++ { ++ /* Search forward to insert OS after AFTER_SEC output ++ statement. */ ++ lang_output_section_statement_type *stmt, *next; ++ bool found = false; ++ for (stmt = after; stmt != NULL; stmt = next) ++ { ++ next = stmt->next; ++ if (insert_after) ++ { ++ if (stmt->bfd_section == after_sec) ++ { ++ place_after = true; ++ found = true; ++ after = stmt; ++ break; ++ } ++ } ++ else ++ { ++ /* If INSERT_AFTER is FALSE, place OS before ++ AFTER_SEC output statement. */ ++ if (next && next->bfd_section == after_sec) ++ { ++ place_after = true; ++ found = true; ++ after = stmt; ++ break; ++ } ++ } ++ } ++ ++ /* Search backward to insert OS after AFTER_SEC output ++ statement. */ ++ if (!found) ++ for (stmt = after; stmt != NULL; stmt = stmt->prev) ++ { ++ if (insert_after) ++ { ++ if (stmt->bfd_section == after_sec) ++ { ++ place_after = true; ++ after = stmt; ++ break; ++ } ++ } ++ else ++ { ++ /* If INSERT_AFTER is FALSE, place OS before ++ AFTER_SEC output statement. */ ++ if (stmt->next->bfd_section == after_sec) ++ { ++ place_after = true; ++ after = stmt; ++ break; ++ } ++ } ++ } ++ } ++ ++ if (after_sec == NULL ++ || (insert_after && after_sec->next != snew) ++ || (!insert_after && after_sec->prev != snew)) ++ { ++ /* Unlink the section. */ ++ bfd_section_list_remove (link_info.output_bfd, snew); ++ ++ /* Place SNEW after AFTER_SEC. If AFTER_SEC is NULL, ++ prepend SNEW. */ ++ if (after_sec) ++ { ++ if (insert_after) ++ bfd_section_list_insert_after (link_info.output_bfd, ++ after_sec, snew); ++ else ++ bfd_section_list_insert_before (link_info.output_bfd, ++ after_sec, snew); ++ } ++ else ++ bfd_section_list_prepend (link_info.output_bfd, snew); ++ } ++ } ++ else if (as != snew && as->prev != snew) ++ { ++ /* Unlink the section. */ ++ bfd_section_list_remove (link_info.output_bfd, snew); ++ ++ /* Now tack it back on in the right place. */ ++ bfd_section_list_insert_before (link_info.output_bfd, ++ as, snew); ++ } ++ } ++ else if (as != snew && as->prev != snew) ++ { ++ /* Unlink the section. */ ++ bfd_section_list_remove (link_info.output_bfd, snew); ++ ++ /* Now tack it back on in the right place. */ ++ bfd_section_list_insert_before (link_info.output_bfd, as, snew); ++ } ++ ++ /* Save the end of this list. Further ophans of this type will ++ follow the one we've just added. */ ++ place->section = &snew->next; ++ ++ /* The following is non-cosmetic. We try to put the output ++ statements in some sort of reasonable order here, because they ++ determine the final load addresses of the orphan sections. ++ In addition, placing output statements in the wrong order may ++ require extra segments. For instance, given a typical ++ situation of all read-only sections placed in one segment and ++ following that a segment containing all the read-write ++ sections, we wouldn't want to place an orphan read/write ++ section before or amongst the read-only ones. */ ++ if (add.head != NULL) ++ { ++ lang_output_section_statement_type *newly_added_os; ++ ++ /* Place OS after AFTER if AFTER_NOTE is TRUE. */ ++ if (place_after) ++ { ++ lang_statement_union_type **where; ++ ++ where = insert_os_after ((lang_statement_union_type *) after); ++ *add.tail = *where; ++ *where = add.head; ++ ++ place->os_tail = &after->next; ++ } ++ else ++ { ++ /* Put it after the last orphan statement we added. */ ++ *add.tail = *place->stmt; ++ *place->stmt = add.head; ++ } ++ ++ /* Fix the global list pointer if we happened to tack our ++ new list at the tail. */ ++ if (*stat_ptr->tail == add.head) ++ stat_ptr->tail = add.tail; ++ ++ /* Save the end of this list. */ ++ place->stmt = add.tail; ++ ++ /* Do the same for the list of output section statements. */ ++ newly_added_os = *os_tail; ++ *os_tail = NULL; ++ newly_added_os->prev = (lang_output_section_statement_type *) ++ ((char *) place->os_tail ++ - offsetof (lang_output_section_statement_type, next)); ++ newly_added_os->next = *place->os_tail; ++ if (newly_added_os->next != NULL) ++ newly_added_os->next->prev = newly_added_os; ++ *place->os_tail = newly_added_os; ++ place->os_tail = &newly_added_os->next; ++ ++ /* Fixing the global list pointer here is a little different. ++ We added to the list in lang_enter_output_section_statement, ++ trimmed off the new output_section_statment above when ++ assigning *os_tail = NULL, but possibly added it back in ++ the same place when assigning *place->os_tail. */ ++ if (*os_tail == NULL) ++ lang_os_list.tail = (lang_statement_union_type **) os_tail; ++ } ++ } ++ return os; ++} ++ ++static void ++lang_print_asneeded (void) ++{ ++ struct asneeded_minfo *m; ++ ++ if (asneeded_list_head == NULL) ++ return; ++ ++ minfo (_("\nAs-needed library included to satisfy reference by file (symbol)\n\n")); ++ ++ for (m = asneeded_list_head; m != NULL; m = m->next) ++ { ++ int len; ++ ++ minfo ("%s", m->soname); ++ len = strlen (m->soname); ++ ++ if (len >= 29) ++ { ++ print_nl (); ++ len = 0; ++ } ++ print_spaces (30 - len); ++ ++ if (m->ref != NULL) ++ minfo ("%pB ", m->ref); ++ minfo ("(%pT)\n", m->name); ++ } ++} ++ ++static void ++lang_map_flags (flagword flag) ++{ ++ if (flag & SEC_ALLOC) ++ minfo ("a"); ++ ++ if (flag & SEC_CODE) ++ minfo ("x"); ++ ++ if (flag & SEC_READONLY) ++ minfo ("r"); ++ ++ if (flag & SEC_DATA) ++ minfo ("w"); ++ ++ if (flag & SEC_LOAD) ++ minfo ("l"); ++} ++ ++void ++lang_map (void) ++{ ++ lang_memory_region_type *m; ++ bool dis_header_printed = false; ++ ++ ldfile_print_input_remaps (); ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ asection *s; ++ ++ if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0 ++ || file->flags.just_syms) ++ continue; ++ ++ if (config.print_map_discarded) ++ for (s = file->the_bfd->sections; s != NULL; s = s->next) ++ if ((s->output_section == NULL ++ || s->output_section->owner != link_info.output_bfd) ++ && (s->flags & (SEC_LINKER_CREATED | SEC_KEEP)) == 0) ++ { ++ if (! dis_header_printed) ++ { ++ minfo (_("\nDiscarded input sections\n\n")); ++ dis_header_printed = true; ++ } ++ ++ print_input_section (s, true); ++ } ++ } ++ if (config.print_map_discarded && ! dis_header_printed) ++ minfo (_("\nThere are no discarded input sections\n")); ++ ++ minfo (_("\nMemory Configuration\n\n")); ++ fprintf (config.map_file, "%-16s %-18s %-18s %s\n", ++ _("Name"), _("Origin"), _("Length"), _("Attributes")); ++ ++ for (m = lang_memory_region_list; m != NULL; m = m->next) ++ { ++ fprintf (config.map_file, "%-16s", m->name_list.name); ++ ++ char buf[32]; ++ bfd_sprintf_vma (link_info.output_bfd, buf, m->origin); ++ fprintf (config.map_file, " 0x%-16s", buf); ++ bfd_sprintf_vma (link_info.output_bfd, buf, m->length); ++ fprintf (config.map_file, ++ " 0x%*s", m->flags || m->not_flags ? -17 : 0, buf); ++ if (m->flags) ++ lang_map_flags (m->flags); ++ ++ if (m->not_flags) ++ { ++ minfo ("!"); ++ lang_map_flags (m->not_flags); ++ } ++ ++ print_nl (); ++ } ++ ++ minfo (_("\nLinker script and memory map\n\n")); ++ ++ if (!link_info.reduce_memory_overheads) ++ { ++ obstack_begin (&map_obstack, 1000); ++ bfd_link_hash_traverse (link_info.hash, sort_def_symbol, 0); ++ } ++ expld.phase = lang_fixed_phase_enum; ++ lang_statement_iteration++; ++ print_statements (); ++ ++ ldemul_extra_map_file_text (link_info.output_bfd, &link_info, ++ config.map_file); ++} ++ ++static bool ++sort_def_symbol (struct bfd_link_hash_entry *hash_entry, ++ void *info ATTRIBUTE_UNUSED) ++{ ++ if ((hash_entry->type == bfd_link_hash_defined ++ || hash_entry->type == bfd_link_hash_defweak) ++ && hash_entry->u.def.section->owner != link_info.output_bfd ++ && hash_entry->u.def.section->owner != NULL) ++ { ++ input_section_userdata_type *ud; ++ struct map_symbol_def *def; ++ ++ ud = bfd_section_userdata (hash_entry->u.def.section); ++ if (!ud) ++ { ++ ud = stat_alloc (sizeof (*ud)); ++ bfd_set_section_userdata (hash_entry->u.def.section, ud); ++ ud->map_symbol_def_tail = &ud->map_symbol_def_head; ++ ud->map_symbol_def_count = 0; ++ } ++ else if (!ud->map_symbol_def_tail) ++ ud->map_symbol_def_tail = &ud->map_symbol_def_head; ++ ++ def = (struct map_symbol_def *) obstack_alloc (&map_obstack, sizeof *def); ++ def->entry = hash_entry; ++ *(ud->map_symbol_def_tail) = def; ++ ud->map_symbol_def_tail = &def->next; ++ ud->map_symbol_def_count++; ++ } ++ return true; ++} ++ ++/* Initialize an output section. */ ++ ++static void ++init_os (lang_output_section_statement_type *s, flagword flags) ++{ ++ if (strcmp (s->name, DISCARD_SECTION_NAME) == 0) ++ einfo (_("%F%P: illegal use of `%s' section\n"), DISCARD_SECTION_NAME); ++ ++ if (!s->dup_output) ++ s->bfd_section = bfd_get_section_by_name (link_info.output_bfd, s->name); ++ if (s->bfd_section == NULL) ++ s->bfd_section = bfd_make_section_anyway_with_flags (link_info.output_bfd, ++ s->name, flags); ++ if (s->bfd_section == NULL) ++ { ++ einfo (_("%F%P: output format %s cannot represent section" ++ " called %s: %E\n"), ++ link_info.output_bfd->xvec->name, s->name); ++ } ++ s->bfd_section->output_section = s->bfd_section; ++ s->bfd_section->output_offset = 0; ++ ++ /* Set the userdata of the output section to the output section ++ statement to avoid lookup. */ ++ bfd_set_section_userdata (s->bfd_section, s); ++ ++ /* If there is a base address, make sure that any sections it might ++ mention are initialized. */ ++ if (s->addr_tree != NULL) ++ exp_init_os (s->addr_tree); ++ ++ if (s->load_base != NULL) ++ exp_init_os (s->load_base); ++ ++ /* If supplied an alignment, set it. */ ++ if (s->section_alignment != NULL) ++ s->bfd_section->alignment_power = exp_get_power (s->section_alignment, ++ "section alignment"); ++} ++ ++/* Make sure that all output sections mentioned in an expression are ++ initialized. */ ++ ++static void ++exp_init_os (etree_type *exp) ++{ ++ switch (exp->type.node_class) ++ { ++ case etree_assign: ++ case etree_provide: ++ case etree_provided: ++ exp_init_os (exp->assign.src); ++ break; ++ ++ case etree_binary: ++ exp_init_os (exp->binary.lhs); ++ exp_init_os (exp->binary.rhs); ++ break; ++ ++ case etree_trinary: ++ exp_init_os (exp->trinary.cond); ++ exp_init_os (exp->trinary.lhs); ++ exp_init_os (exp->trinary.rhs); ++ break; ++ ++ case etree_assert: ++ exp_init_os (exp->assert_s.child); ++ break; ++ ++ case etree_unary: ++ exp_init_os (exp->unary.child); ++ break; ++ ++ case etree_name: ++ switch (exp->type.node_code) ++ { ++ case ADDR: ++ case LOADADDR: ++ { ++ lang_output_section_statement_type *os; ++ ++ os = lang_output_section_find (exp->name.name); ++ if (os != NULL && os->bfd_section == NULL) ++ init_os (os, 0); ++ } ++ } ++ break; ++ ++ default: ++ break; ++ } ++} ++ ++static void ++section_already_linked (bfd *abfd, asection *sec, void *data) ++{ ++ lang_input_statement_type *entry = (lang_input_statement_type *) data; ++ ++ /* If we are only reading symbols from this object, then we want to ++ discard all sections. */ ++ if (entry->flags.just_syms) ++ { ++ bfd_link_just_syms (abfd, sec, &link_info); ++ return; ++ } ++ ++ /* Deal with SHF_EXCLUDE ELF sections. */ ++ if (!bfd_link_relocatable (&link_info) ++ && (abfd->flags & BFD_PLUGIN) == 0 ++ && (sec->flags & (SEC_GROUP | SEC_KEEP | SEC_EXCLUDE)) == SEC_EXCLUDE) ++ sec->output_section = bfd_abs_section_ptr; ++ ++ if (!(abfd->flags & DYNAMIC)) ++ bfd_section_already_linked (abfd, sec, &link_info); ++} ++ ++ ++/* Returns true if SECTION is one we know will be discarded based on its ++ section flags, otherwise returns false. */ ++ ++static bool ++lang_discard_section_p (asection *section) ++{ ++ bool discard; ++ flagword flags = section->flags; ++ ++ /* Discard sections marked with SEC_EXCLUDE. */ ++ discard = (flags & SEC_EXCLUDE) != 0; ++ ++ /* Discard the group descriptor sections when we're finally placing the ++ sections from within the group. */ ++ if ((flags & SEC_GROUP) != 0 ++ && link_info.resolve_section_groups) ++ discard = true; ++ ++ /* Discard debugging sections if we are stripping debugging ++ information. */ ++ if ((link_info.strip == strip_debugger || link_info.strip == strip_all) ++ && (flags & SEC_DEBUGGING) != 0) ++ discard = true; ++ ++ /* Discard non-alloc sections if we are stripping section headers. */ ++ else if (config.no_section_header && (flags & SEC_ALLOC) == 0) ++ discard = true; ++ ++ return discard; ++} ++ ++/* Return TRUE if SECTION is never going to be added to output statement ++ OUTPUT. lang_add_section() definitely won't do anything with SECTION ++ if this returns TRUE. It may do something (or not) if this returns FALSE. ++ ++ Can be used as early-out to filter matches. This may set ++ output_section of SECTION, if it was unset, to the abs section in case ++ we discover SECTION to be always discarded. This may also give ++ warning messages. */ ++ ++static bool ++wont_add_section_p (asection *section, ++ lang_output_section_statement_type *output) ++{ ++ bool discard; ++ ++ /* Is this section one we know should be discarded? */ ++ discard = lang_discard_section_p (section); ++ ++ /* Discard input sections which are assigned to a section named ++ DISCARD_SECTION_NAME. */ ++ if (strcmp (output->name, DISCARD_SECTION_NAME) == 0) ++ discard = true; ++ ++ if (discard) ++ { ++ if (section->output_section == NULL) ++ { ++ /* This prevents future calls from assigning this section or ++ warning about it again. */ ++ section->output_section = bfd_abs_section_ptr; ++ } ++ else if (bfd_is_abs_section (section->output_section)) ++ ; ++ else if (link_info.non_contiguous_regions_warnings) ++ einfo (_("%P:%pS: warning: --enable-non-contiguous-regions makes " ++ "section `%pA' from `%pB' match /DISCARD/ clause.\n"), ++ NULL, section, section->owner); ++ ++ return true; ++ } ++ ++ if (section->output_section != NULL) ++ { ++ if (!link_info.non_contiguous_regions) ++ return true; ++ ++ /* SECTION has already been handled in a special way ++ (eg. LINK_ONCE): skip it. */ ++ if (bfd_is_abs_section (section->output_section)) ++ return true; ++ ++ /* Already assigned to the same output section, do not process ++ it again, to avoid creating loops between duplicate sections ++ later. */ ++ if (section->output_section == output->bfd_section) ++ return true; ++ ++ if (link_info.non_contiguous_regions_warnings && output->bfd_section) ++ einfo (_("%P:%pS: warning: --enable-non-contiguous-regions may " ++ "change behaviour for section `%pA' from `%pB' (assigned to " ++ "%pA, but additional match: %pA)\n"), ++ NULL, section, section->owner, section->output_section, ++ output->bfd_section); ++ ++ /* SECTION has already been assigned to an output section, but ++ the user allows it to be mapped to another one in case it ++ overflows. We'll later update the actual output section in ++ size_input_section as appropriate. */ ++ } ++ ++ return false; ++} ++ ++/* The wild routines. ++ ++ These expand statements like *(.text) and foo.o to a list of ++ explicit actions, like foo.o(.text), bar.o(.text) and ++ foo.o(.text, .data). */ ++ ++/* Add SECTION to the output section OUTPUT. Do this by creating a ++ lang_input_section statement which is placed at PTR. */ ++ ++void ++lang_add_section (lang_statement_list_type *ptr, ++ asection *section, ++ struct wildcard_list *pattern, ++ struct flag_info *sflag_info, ++ lang_output_section_statement_type *output) ++{ ++ flagword flags = section->flags; ++ ++ lang_input_section_type *new_section; ++ bfd *abfd = link_info.output_bfd; ++ ++ if (wont_add_section_p (section, output)) ++ return; ++ ++ if (sflag_info) ++ { ++ bool keep; ++ ++ keep = bfd_lookup_section_flags (&link_info, sflag_info, section); ++ if (!keep) ++ return; ++ } ++ ++ /* We don't copy the SEC_NEVER_LOAD flag from an input section ++ to an output section, because we want to be able to include a ++ SEC_NEVER_LOAD section in the middle of an otherwise loaded ++ section (I don't know why we want to do this, but we do). ++ build_link_order in ldwrite.c handles this case by turning ++ the embedded SEC_NEVER_LOAD section into a fill. */ ++ flags &= ~ SEC_NEVER_LOAD; ++ ++ /* If final link, don't copy the SEC_LINK_ONCE flags, they've ++ already been processed. One reason to do this is that on pe ++ format targets, .text$foo sections go into .text and it's odd ++ to see .text with SEC_LINK_ONCE set. */ ++ if ((flags & (SEC_LINK_ONCE | SEC_GROUP)) == (SEC_LINK_ONCE | SEC_GROUP)) ++ { ++ if (link_info.resolve_section_groups) ++ flags &= ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC); ++ else ++ flags &= ~(SEC_LINK_DUPLICATES | SEC_RELOC); ++ } ++ else if (!bfd_link_relocatable (&link_info)) ++ flags &= ~(SEC_LINK_ONCE | SEC_LINK_DUPLICATES | SEC_RELOC); ++ ++ switch (output->sectype) ++ { ++ case normal_section: ++ case overlay_section: ++ case first_overlay_section: ++ case type_section: ++ break; ++ case noalloc_section: ++ flags &= ~SEC_ALLOC; ++ break; ++ case typed_readonly_section: ++ case readonly_section: ++ flags |= SEC_READONLY; ++ break; ++ case noload_section: ++ flags &= ~SEC_LOAD; ++ flags |= SEC_NEVER_LOAD; ++ /* Unfortunately GNU ld has managed to evolve two different ++ meanings to NOLOAD in scripts. ELF gets a .bss style noload, ++ alloc, no contents section. All others get a noload, noalloc ++ section. */ ++ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour) ++ flags &= ~SEC_HAS_CONTENTS; ++ else ++ flags &= ~SEC_ALLOC; ++ break; ++ } ++ ++ if (output->bfd_section == NULL) ++ init_os (output, flags); ++ ++ /* If SEC_READONLY is not set in the input section, then clear ++ it from the output section. */ ++ output->bfd_section->flags &= flags | ~SEC_READONLY; ++ ++ if (output->bfd_section->linker_has_input) ++ { ++ /* Only set SEC_READONLY flag on the first input section. */ ++ flags &= ~ SEC_READONLY; ++ ++ /* Keep SEC_MERGE and SEC_STRINGS only if they are the same. */ ++ if ((output->bfd_section->flags & (SEC_MERGE | SEC_STRINGS)) ++ != (flags & (SEC_MERGE | SEC_STRINGS)) ++ || ((flags & SEC_MERGE) != 0 ++ && output->bfd_section->entsize != section->entsize)) ++ { ++ output->bfd_section->flags &= ~ (SEC_MERGE | SEC_STRINGS); ++ flags &= ~ (SEC_MERGE | SEC_STRINGS); ++ } ++ } ++ output->bfd_section->flags |= flags; ++ ++ if (!output->bfd_section->linker_has_input) ++ { ++ output->bfd_section->linker_has_input = 1; ++ /* This must happen after flags have been updated. The output ++ section may have been created before we saw its first input ++ section, eg. for a data statement. */ ++ bfd_init_private_section_data (section->owner, section, ++ link_info.output_bfd, ++ output->bfd_section, ++ &link_info); ++ if ((flags & SEC_MERGE) != 0) ++ output->bfd_section->entsize = section->entsize; ++ } ++ ++ if ((flags & SEC_TIC54X_BLOCK) != 0 ++ && bfd_get_arch (section->owner) == bfd_arch_tic54x) ++ { ++ /* FIXME: This value should really be obtained from the bfd... */ ++ output->block_value = 128; ++ } ++ ++ /* When a .ctors section is placed in .init_array it must be copied ++ in reverse order. Similarly for .dtors. Set that up. */ ++ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour ++ && ((startswith (section->name, ".ctors") ++ && strcmp (output->bfd_section->name, ".init_array") == 0) ++ || (startswith (section->name, ".dtors") ++ && strcmp (output->bfd_section->name, ".fini_array") == 0)) ++ && (section->name[6] == 0 || section->name[6] == '.')) ++ section->flags |= SEC_ELF_REVERSE_COPY; ++ ++ if (section->alignment_power > output->bfd_section->alignment_power) ++ output->bfd_section->alignment_power = section->alignment_power; ++ ++ section->output_section = output->bfd_section; ++ ++ if (!map_head_is_link_order) ++ { ++ asection *s = output->bfd_section->map_tail.s; ++ output->bfd_section->map_tail.s = section; ++ section->map_head.s = NULL; ++ section->map_tail.s = s; ++ if (s != NULL) ++ s->map_head.s = section; ++ else ++ output->bfd_section->map_head.s = section; ++ } ++ ++ /* Add a section reference to the list. */ ++ new_section = new_stat (lang_input_section, ptr); ++ new_section->section = section; ++ new_section->pattern = pattern; ++} ++ ++/* Expand a wild statement for a particular FILE. SECTION may be ++ NULL, in which case it is a wild card. This assumes that the ++ wild statement doesn't need any sorting (of filenames or sections). */ ++ ++static void ++output_section_callback_nosort (lang_wild_statement_type *ptr, ++ struct wildcard_list *sec ATTRIBUTE_UNUSED, ++ asection *section, ++ lang_input_statement_type *file ATTRIBUTE_UNUSED, ++ void *output) ++{ ++ lang_output_section_statement_type *os; ++ ++ os = (lang_output_section_statement_type *) output; ++ ++ /* Exclude sections that match UNIQUE_SECTION_LIST. */ ++ if (unique_section_p (section, os)) ++ return; ++ ++ lang_add_section (&ptr->children, section, ptr->section_list, ++ ptr->section_flag_list, os); ++} ++ ++/* Check if all sections in a wild statement for a particular FILE ++ are readonly. */ ++ ++static void ++check_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED, ++ struct wildcard_list *sec ATTRIBUTE_UNUSED, ++ asection *section, ++ lang_input_statement_type *file ATTRIBUTE_UNUSED, ++ void *output) ++{ ++ lang_output_section_statement_type *os; ++ ++ os = (lang_output_section_statement_type *) output; ++ ++ /* Exclude sections that match UNIQUE_SECTION_LIST. */ ++ if (unique_section_p (section, os)) ++ return; ++ ++ if (section->output_section == NULL && (section->flags & SEC_READONLY) == 0) ++ os->all_input_readonly = false; ++} ++ ++/* This is passed a file name which must have been seen already and ++ added to the statement tree. We will see if it has been opened ++ already and had its symbols read. If not then we'll read it. */ ++ ++static lang_input_statement_type * ++lookup_name (const char *name) ++{ ++ lang_input_statement_type *search; ++ ++ for (search = (void *) input_file_chain.head; ++ search != NULL; ++ search = search->next_real_file) ++ { ++ /* Use the local_sym_name as the name of the file that has ++ already been loaded as filename might have been transformed ++ via the search directory lookup mechanism. */ ++ const char *filename = search->local_sym_name; ++ ++ if (filename != NULL ++ && filename_cmp (filename, name) == 0) ++ break; ++ } ++ ++ if (search == NULL) ++ { ++ /* Arrange to splice the input statement added by new_afile into ++ statement_list after the current input_file_chain tail. ++ We know input_file_chain is not an empty list, and that ++ lookup_name was called via open_input_bfds. Later calls to ++ lookup_name should always match an existing input_statement. */ ++ lang_statement_union_type **tail = stat_ptr->tail; ++ lang_statement_union_type **after ++ = (void *) ((char *) input_file_chain.tail ++ - offsetof (lang_input_statement_type, next_real_file) ++ + offsetof (lang_input_statement_type, header.next)); ++ lang_statement_union_type *rest = *after; ++ stat_ptr->tail = after; ++ search = new_afile (name, lang_input_file_is_search_file_enum, ++ default_target, NULL); ++ *stat_ptr->tail = rest; ++ if (*tail == NULL) ++ stat_ptr->tail = tail; ++ } ++ ++ /* If we have already added this file, or this file is not real ++ don't add this file. */ ++ if (search->flags.loaded || !search->flags.real) ++ return search; ++ ++ if (!load_symbols (search, NULL)) ++ return NULL; ++ ++ return search; ++} ++ ++/* Save LIST as a list of libraries whose symbols should not be exported. */ ++ ++struct excluded_lib ++{ ++ char *name; ++ struct excluded_lib *next; ++}; ++static struct excluded_lib *excluded_libs; ++ ++void ++add_excluded_libs (const char *list) ++{ ++ const char *p = list, *end; ++ ++ while (*p != '\0') ++ { ++ struct excluded_lib *entry; ++ end = strpbrk (p, ",:"); ++ if (end == NULL) ++ end = p + strlen (p); ++ entry = (struct excluded_lib *) xmalloc (sizeof (*entry)); ++ entry->next = excluded_libs; ++ entry->name = (char *) xmalloc (end - p + 1); ++ memcpy (entry->name, p, end - p); ++ entry->name[end - p] = '\0'; ++ excluded_libs = entry; ++ if (*end == '\0') ++ break; ++ p = end + 1; ++ } ++} ++ ++static void ++check_excluded_libs (bfd *abfd) ++{ ++ struct excluded_lib *lib = excluded_libs; ++ ++ while (lib) ++ { ++ int len = strlen (lib->name); ++ const char *filename = lbasename (bfd_get_filename (abfd)); ++ ++ if (strcmp (lib->name, "ALL") == 0) ++ { ++ abfd->no_export = true; ++ return; ++ } ++ ++ if (filename_ncmp (lib->name, filename, len) == 0 ++ && (filename[len] == '\0' ++ || (filename[len] == '.' && filename[len + 1] == 'a' ++ && filename[len + 2] == '\0'))) ++ { ++ abfd->no_export = true; ++ return; ++ } ++ ++ lib = lib->next; ++ } ++} ++ ++/* Get the symbols for an input file. */ ++ ++bool ++load_symbols (lang_input_statement_type *entry, ++ lang_statement_list_type *place) ++{ ++ char **matching; ++ ++ if (entry->flags.loaded) ++ return true; ++ ++ ldfile_open_file (entry); ++ ++ /* Do not process further if the file was missing. */ ++ if (entry->flags.missing_file) ++ return true; ++ ++ if (trace_files || verbose) ++ info_msg ("%pI\n", entry); ++ ++ if (!bfd_check_format (entry->the_bfd, bfd_archive) ++ && !bfd_check_format_matches (entry->the_bfd, bfd_object, &matching)) ++ { ++ bfd_error_type err; ++ struct lang_input_statement_flags save_flags; ++ extern FILE *yyin; ++ ++ err = bfd_get_error (); ++ ++ /* See if the emulation has some special knowledge. */ ++ if (ldemul_unrecognized_file (entry)) ++ { ++ if (err == bfd_error_file_ambiguously_recognized) ++ free (matching); ++ return true; ++ } ++ ++ if (err == bfd_error_file_ambiguously_recognized) ++ { ++ char **p; ++ ++ einfo (_("%P: %pB: file not recognized: %E;" ++ " matching formats:"), entry->the_bfd); ++ for (p = matching; *p != NULL; p++) ++ einfo (" %s", *p); ++ free (matching); ++ einfo ("%F\n"); ++ } ++ else if (err != bfd_error_file_not_recognized ++ || place == NULL) ++ einfo (_("%F%P: %pB: file not recognized: %E\n"), entry->the_bfd); ++ ++ bfd_close (entry->the_bfd); ++ entry->the_bfd = NULL; ++ ++ /* Try to interpret the file as a linker script. */ ++ save_flags = input_flags; ++ ldfile_open_command_file (entry->filename); ++ ++ push_stat_ptr (place); ++ input_flags.add_DT_NEEDED_for_regular ++ = entry->flags.add_DT_NEEDED_for_regular; ++ input_flags.add_DT_NEEDED_for_dynamic ++ = entry->flags.add_DT_NEEDED_for_dynamic; ++ input_flags.whole_archive = entry->flags.whole_archive; ++ input_flags.dynamic = entry->flags.dynamic; ++ ++ ldfile_assumed_script = true; ++ parser_input = input_script; ++ current_input_file = entry->filename; ++ yyparse (); ++ current_input_file = NULL; ++ ldfile_assumed_script = false; ++ ++ /* missing_file is sticky. sysrooted will already have been ++ restored when seeing EOF in yyparse, but no harm to restore ++ again. */ ++ save_flags.missing_file |= input_flags.missing_file; ++ input_flags = save_flags; ++ pop_stat_ptr (); ++ fclose (yyin); ++ yyin = NULL; ++ entry->flags.loaded = true; ++ ++ return true; ++ } ++ ++ if (ldemul_recognized_file (entry)) ++ return true; ++ ++ /* We don't call ldlang_add_file for an archive. Instead, the ++ add_symbols entry point will call ldlang_add_file, via the ++ add_archive_element callback, for each element of the archive ++ which is used. */ ++ switch (bfd_get_format (entry->the_bfd)) ++ { ++ default: ++ break; ++ ++ case bfd_object: ++ if (!entry->flags.reload) ++ ldlang_add_file (entry); ++ break; ++ ++ case bfd_archive: ++ check_excluded_libs (entry->the_bfd); ++ ++ bfd_set_usrdata (entry->the_bfd, entry); ++ if (entry->flags.whole_archive) ++ { ++ bfd *member = NULL; ++ bool loaded = true; ++ ++ for (;;) ++ { ++ bfd *subsbfd; ++ member = bfd_openr_next_archived_file (entry->the_bfd, member); ++ ++ if (member == NULL) ++ break; ++ ++ if (!bfd_check_format (member, bfd_object)) ++ { ++ einfo (_("%F%P: %pB: member %pB in archive is not an object\n"), ++ entry->the_bfd, member); ++ loaded = false; ++ } ++ ++ subsbfd = member; ++ if (!(*link_info.callbacks ++ ->add_archive_element) (&link_info, member, ++ "--whole-archive", &subsbfd)) ++ abort (); ++ ++ /* Potentially, the add_archive_element hook may have set a ++ substitute BFD for us. */ ++ if (!bfd_link_add_symbols (subsbfd, &link_info)) ++ { ++ einfo (_("%F%P: %pB: error adding symbols: %E\n"), member); ++ loaded = false; ++ } ++ } ++ ++ entry->flags.loaded = loaded; ++ return loaded; ++ } ++ break; ++ } ++ ++ if (bfd_link_add_symbols (entry->the_bfd, &link_info)) ++ entry->flags.loaded = true; ++ else ++ einfo (_("%F%P: %pB: error adding symbols: %E\n"), entry->the_bfd); ++ ++ return entry->flags.loaded; ++} ++ ++/* Handle a wild statement. S->FILENAME or S->SECTION_LIST or both ++ may be NULL, indicating that it is a wildcard. Separate ++ lang_input_section statements are created for each part of the ++ expansion; they are added after the wild statement S. OUTPUT is ++ the output section. */ ++ ++static void ++wild (lang_wild_statement_type *s, ++ const char *target ATTRIBUTE_UNUSED, ++ lang_output_section_statement_type *output) ++{ ++ struct wildcard_list *sec; ++ ++ if (s->filenames_sorted || s->any_specs_sorted) ++ { ++ lang_section_bst_type *tree; ++ ++ walk_wild (s, output_section_callback_sort, output); ++ ++ tree = s->tree; ++ if (tree) ++ { ++ output_section_callback_tree_to_list (s, tree, output); ++ s->tree = NULL; ++ s->rightmost = &s->tree; ++ } ++ } ++ else ++ walk_wild (s, output_section_callback_nosort, output); ++ ++ if (default_common_section == NULL) ++ for (sec = s->section_list; sec != NULL; sec = sec->next) ++ if (sec->spec.name != NULL && strcmp (sec->spec.name, "COMMON") == 0) ++ { ++ /* Remember the section that common is going to in case we ++ later get something which doesn't know where to put it. */ ++ default_common_section = output; ++ break; ++ } ++} ++ ++/* Return TRUE iff target is the sought target. */ ++ ++static int ++get_target (const bfd_target *target, void *data) ++{ ++ const char *sought = (const char *) data; ++ ++ return strcmp (target->name, sought) == 0; ++} ++ ++/* Like strcpy() but convert to lower case as well. */ ++ ++static void ++stricpy (char *dest, const char *src) ++{ ++ char c; ++ ++ while ((c = *src++) != 0) ++ *dest++ = TOLOWER (c); ++ ++ *dest = 0; ++} ++ ++/* Remove the first occurrence of needle (if any) in haystack ++ from haystack. */ ++ ++static void ++strcut (char *haystack, const char *needle) ++{ ++ haystack = strstr (haystack, needle); ++ ++ if (haystack) ++ { ++ char *src; ++ ++ for (src = haystack + strlen (needle); *src;) ++ *haystack++ = *src++; ++ ++ *haystack = 0; ++ } ++} ++ ++/* Compare two target format name strings. ++ Return a value indicating how "similar" they are. */ ++ ++static int ++name_compare (const char *first, const char *second) ++{ ++ char *copy1; ++ char *copy2; ++ int result; ++ ++ copy1 = (char *) xmalloc (strlen (first) + 1); ++ copy2 = (char *) xmalloc (strlen (second) + 1); ++ ++ /* Convert the names to lower case. */ ++ stricpy (copy1, first); ++ stricpy (copy2, second); ++ ++ /* Remove size and endian strings from the name. */ ++ strcut (copy1, "big"); ++ strcut (copy1, "little"); ++ strcut (copy2, "big"); ++ strcut (copy2, "little"); ++ ++ /* Return a value based on how many characters match, ++ starting from the beginning. If both strings are ++ the same then return 10 * their length. */ ++ for (result = 0; copy1[result] == copy2[result]; result++) ++ if (copy1[result] == 0) ++ { ++ result *= 10; ++ break; ++ } ++ ++ free (copy1); ++ free (copy2); ++ ++ return result; ++} ++ ++/* Set by closest_target_match() below. */ ++static const bfd_target *winner; ++ ++/* Scan all the valid bfd targets looking for one that has the endianness ++ requirement that was specified on the command line, and is the nearest ++ match to the original output target. */ ++ ++static int ++closest_target_match (const bfd_target *target, void *data) ++{ ++ const bfd_target *original = (const bfd_target *) data; ++ ++ if (command_line.endian == ENDIAN_BIG ++ && target->byteorder != BFD_ENDIAN_BIG) ++ return 0; ++ ++ if (command_line.endian == ENDIAN_LITTLE ++ && target->byteorder != BFD_ENDIAN_LITTLE) ++ return 0; ++ ++ /* Must be the same flavour. */ ++ if (target->flavour != original->flavour) ++ return 0; ++ ++ /* Ignore generic big and little endian elf vectors. */ ++ if (strcmp (target->name, "elf32-big") == 0 ++ || strcmp (target->name, "elf64-big") == 0 ++ || strcmp (target->name, "elf32-little") == 0 ++ || strcmp (target->name, "elf64-little") == 0) ++ return 0; ++ ++ /* If we have not found a potential winner yet, then record this one. */ ++ if (winner == NULL) ++ { ++ winner = target; ++ return 0; ++ } ++ ++ /* Oh dear, we now have two potential candidates for a successful match. ++ Compare their names and choose the better one. */ ++ if (name_compare (target->name, original->name) ++ > name_compare (winner->name, original->name)) ++ winner = target; ++ ++ /* Keep on searching until wqe have checked them all. */ ++ return 0; ++} ++ ++/* Return the BFD target format of the first input file. */ ++ ++static const char * ++get_first_input_target (void) ++{ ++ const char *target = NULL; ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (s) ++ { ++ if (s->header.type == lang_input_statement_enum ++ && s->flags.real) ++ { ++ ldfile_open_file (s); ++ ++ if (s->the_bfd != NULL ++ && bfd_check_format (s->the_bfd, bfd_object)) ++ { ++ target = bfd_get_target (s->the_bfd); ++ ++ if (target != NULL) ++ break; ++ } ++ } ++ } ++ ++ return target; ++} ++ ++const char * ++lang_get_output_target (void) ++{ ++ const char *target; ++ ++ /* Has the user told us which output format to use? */ ++ if (output_target != NULL) ++ return output_target; ++ ++ /* No - has the current target been set to something other than ++ the default? */ ++ if (current_target != default_target && current_target != NULL) ++ return current_target; ++ ++ /* No - can we determine the format of the first input file? */ ++ target = get_first_input_target (); ++ if (target != NULL) ++ return target; ++ ++ /* Failed - use the default output target. */ ++ return default_target; ++} ++ ++/* Open the output file. */ ++ ++static void ++open_output (const char *name) ++{ ++ lang_input_statement_type *f; ++ char *out = lrealpath (name); ++ ++ for (f = (void *) input_file_chain.head; ++ f != NULL; ++ f = f->next_real_file) ++ if (f->flags.real) ++ { ++ char *in = lrealpath (f->local_sym_name); ++ if (filename_cmp (in, out) == 0) ++ einfo (_("%F%P: input file '%s' is the same as output file\n"), ++ f->filename); ++ free (in); ++ } ++ free (out); ++ ++ output_target = lang_get_output_target (); ++ ++ /* Has the user requested a particular endianness on the command ++ line? */ ++ if (command_line.endian != ENDIAN_UNSET) ++ { ++ /* Get the chosen target. */ ++ const bfd_target *target ++ = bfd_iterate_over_targets (get_target, (void *) output_target); ++ ++ /* If the target is not supported, we cannot do anything. */ ++ if (target != NULL) ++ { ++ enum bfd_endian desired_endian; ++ ++ if (command_line.endian == ENDIAN_BIG) ++ desired_endian = BFD_ENDIAN_BIG; ++ else ++ desired_endian = BFD_ENDIAN_LITTLE; ++ ++ /* See if the target has the wrong endianness. This should ++ not happen if the linker script has provided big and ++ little endian alternatives, but some scrips don't do ++ this. */ ++ if (target->byteorder != desired_endian) ++ { ++ /* If it does, then see if the target provides ++ an alternative with the correct endianness. */ ++ if (target->alternative_target != NULL ++ && (target->alternative_target->byteorder == desired_endian)) ++ output_target = target->alternative_target->name; ++ else ++ { ++ /* Try to find a target as similar as possible to ++ the default target, but which has the desired ++ endian characteristic. */ ++ bfd_iterate_over_targets (closest_target_match, ++ (void *) target); ++ ++ /* Oh dear - we could not find any targets that ++ satisfy our requirements. */ ++ if (winner == NULL) ++ einfo (_("%P: warning: could not find any targets" ++ " that match endianness requirement\n")); ++ else ++ output_target = winner->name; ++ } ++ } ++ } ++ } ++ ++ link_info.output_bfd = bfd_openw (name, output_target); ++ ++ if (link_info.output_bfd == NULL) ++ { ++ if (bfd_get_error () == bfd_error_invalid_target) ++ einfo (_("%F%P: target %s not found\n"), output_target); ++ ++ einfo (_("%F%P: cannot open output file %s: %E\n"), name); ++ } ++ ++ delete_output_file_on_failure = true; ++ ++ if (!bfd_set_format (link_info.output_bfd, bfd_object)) ++ einfo (_("%F%P: %s: can not make object file: %E\n"), name); ++ if (!bfd_set_arch_mach (link_info.output_bfd, ++ ldfile_output_architecture, ++ ldfile_output_machine)) ++ einfo (_("%F%P: %s: can not set architecture: %E\n"), name); ++ ++ link_info.hash = bfd_link_hash_table_create (link_info.output_bfd); ++ if (link_info.hash == NULL) ++ einfo (_("%F%P: can not create hash table: %E\n")); ++ ++ bfd_set_gp_size (link_info.output_bfd, g_switch_value); ++} ++ ++static void ++ldlang_open_output (lang_statement_union_type *statement) ++{ ++ switch (statement->header.type) ++ { ++ case lang_output_statement_enum: ++ ASSERT (link_info.output_bfd == NULL); ++ open_output (statement->output_statement.name); ++ ldemul_set_output_arch (); ++ if (config.magic_demand_paged ++ && !bfd_link_relocatable (&link_info)) ++ link_info.output_bfd->flags |= D_PAGED; ++ else ++ link_info.output_bfd->flags &= ~D_PAGED; ++ if (config.text_read_only) ++ link_info.output_bfd->flags |= WP_TEXT; ++ else ++ link_info.output_bfd->flags &= ~WP_TEXT; ++ if (link_info.traditional_format) ++ link_info.output_bfd->flags |= BFD_TRADITIONAL_FORMAT; ++ else ++ link_info.output_bfd->flags &= ~BFD_TRADITIONAL_FORMAT; ++ if (config.no_section_header) ++ link_info.output_bfd->flags |= BFD_NO_SECTION_HEADER; ++ else ++ link_info.output_bfd->flags &= ~BFD_NO_SECTION_HEADER; ++ break; ++ ++ case lang_target_statement_enum: ++ current_target = statement->target_statement.target; ++ break; ++ default: ++ break; ++ } ++} ++ ++static void ++init_opb (asection *s) ++{ ++ unsigned int x; ++ ++ opb_shift = 0; ++ if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour ++ && s != NULL ++ && (s->flags & SEC_ELF_OCTETS) != 0) ++ return; ++ ++ x = bfd_arch_mach_octets_per_byte (ldfile_output_architecture, ++ ldfile_output_machine); ++ if (x > 1) ++ while ((x & 1) == 0) ++ { ++ x >>= 1; ++ ++opb_shift; ++ } ++ ASSERT (x == 1); ++} ++ ++/* Open all the input files. */ ++ ++enum open_bfd_mode ++ { ++ OPEN_BFD_NORMAL = 0, ++ OPEN_BFD_FORCE = 1, ++ OPEN_BFD_RESCAN = 2 ++ }; ++#if BFD_SUPPORTS_PLUGINS ++static lang_input_statement_type *plugin_insert = NULL; ++static struct bfd_link_hash_entry *plugin_undefs = NULL; ++#endif ++ ++static void ++open_input_bfds (lang_statement_union_type *s, enum open_bfd_mode mode) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ switch (s->header.type) ++ { ++ case lang_constructors_statement_enum: ++ open_input_bfds (constructor_list.head, mode); ++ break; ++ case lang_output_section_statement_enum: ++ open_input_bfds (s->output_section_statement.children.head, mode); ++ break; ++ case lang_wild_statement_enum: ++ /* Maybe we should load the file's symbols. */ ++ if ((mode & OPEN_BFD_RESCAN) == 0 ++ && s->wild_statement.filename ++ && !wildcardp (s->wild_statement.filename) ++ && !archive_path (s->wild_statement.filename)) ++ lookup_name (s->wild_statement.filename); ++ open_input_bfds (s->wild_statement.children.head, mode); ++ break; ++ case lang_group_statement_enum: ++ { ++ struct bfd_link_hash_entry *undefs; ++#if BFD_SUPPORTS_PLUGINS ++ lang_input_statement_type *plugin_insert_save; ++#endif ++ ++ /* We must continually search the entries in the group ++ until no new symbols are added to the list of undefined ++ symbols. */ ++ ++ do ++ { ++#if BFD_SUPPORTS_PLUGINS ++ plugin_insert_save = plugin_insert; ++#endif ++ undefs = link_info.hash->undefs_tail; ++ open_input_bfds (s->group_statement.children.head, ++ mode | OPEN_BFD_FORCE); ++ } ++ while (undefs != link_info.hash->undefs_tail ++#if BFD_SUPPORTS_PLUGINS ++ /* Objects inserted by a plugin, which are loaded ++ before we hit this loop, may have added new ++ undefs. */ ++ || (plugin_insert != plugin_insert_save && plugin_undefs) ++#endif ++ ); ++ } ++ break; ++ case lang_target_statement_enum: ++ current_target = s->target_statement.target; ++ break; ++ case lang_input_statement_enum: ++ if (s->input_statement.flags.real) ++ { ++ lang_statement_union_type **os_tail; ++ lang_statement_list_type add; ++ bfd *abfd; ++ ++ s->input_statement.target = current_target; ++ ++ /* If we are being called from within a group, and this ++ is an archive which has already been searched, then ++ force it to be researched unless the whole archive ++ has been loaded already. Do the same for a rescan. ++ Likewise reload --as-needed shared libs. */ ++ if (mode != OPEN_BFD_NORMAL ++#if BFD_SUPPORTS_PLUGINS ++ && ((mode & OPEN_BFD_RESCAN) == 0 ++ || plugin_insert == NULL) ++#endif ++ && s->input_statement.flags.loaded ++ && (abfd = s->input_statement.the_bfd) != NULL ++ && ((bfd_get_format (abfd) == bfd_archive ++ && !s->input_statement.flags.whole_archive) ++ || (bfd_get_format (abfd) == bfd_object ++ && ((abfd->flags) & DYNAMIC) != 0 ++ && s->input_statement.flags.add_DT_NEEDED_for_regular ++ && bfd_get_flavour (abfd) == bfd_target_elf_flavour ++ && (elf_dyn_lib_class (abfd) & DYN_AS_NEEDED) != 0))) ++ { ++ s->input_statement.flags.loaded = false; ++ s->input_statement.flags.reload = true; ++ } ++ ++ os_tail = lang_os_list.tail; ++ lang_list_init (&add); ++ ++ if (!load_symbols (&s->input_statement, &add)) ++ config.make_executable = false; ++ ++ if (add.head != NULL) ++ { ++ /* If this was a script with output sections then ++ tack any added statements on to the end of the ++ list. This avoids having to reorder the output ++ section statement list. Very likely the user ++ forgot -T, and whatever we do here will not meet ++ naive user expectations. */ ++ if (os_tail != lang_os_list.tail) ++ { ++ einfo (_("%P: warning: %s contains output sections;" ++ " did you forget -T?\n"), ++ s->input_statement.filename); ++ *stat_ptr->tail = add.head; ++ stat_ptr->tail = add.tail; ++ } ++ else ++ { ++ *add.tail = s->header.next; ++ s->header.next = add.head; ++ } ++ } ++ } ++#if BFD_SUPPORTS_PLUGINS ++ /* If we have found the point at which a plugin added new ++ files, clear plugin_insert to enable archive rescan. */ ++ if (&s->input_statement == plugin_insert) ++ plugin_insert = NULL; ++#endif ++ break; ++ case lang_assignment_statement_enum: ++ if (s->assignment_statement.exp->type.node_class != etree_assert) ++ exp_fold_tree_no_dot (s->assignment_statement.exp); ++ break; ++ default: ++ break; ++ } ++ } ++ ++ /* Exit if any of the files were missing. */ ++ if (input_flags.missing_file) ++ einfo ("%F"); ++} ++ ++#ifdef ENABLE_LIBCTF ++/* Emit CTF errors and warnings. fp can be NULL to report errors/warnings ++ that happened specifically at CTF open time. */ ++static void ++lang_ctf_errs_warnings (ctf_dict_t *fp) ++{ ++ ctf_next_t *i = NULL; ++ char *text; ++ int is_warning; ++ int err; ++ ++ while ((text = ctf_errwarning_next (fp, &i, &is_warning, &err)) != NULL) ++ { ++ einfo (_("%s: %s\n"), is_warning ? _("CTF warning"): _("CTF error"), ++ text); ++ free (text); ++ } ++ if (err != ECTF_NEXT_END) ++ { ++ einfo (_("CTF error: cannot get CTF errors: `%s'\n"), ++ ctf_errmsg (err)); ++ } ++ ++ /* `err' returns errors from the error/warning iterator in particular. ++ These never assert. But if we have an fp, that could have recorded ++ an assertion failure: assert if it has done so. */ ++ ASSERT (!fp || ctf_errno (fp) != ECTF_INTERNAL); ++} ++ ++/* Open the CTF sections in the input files with libctf: if any were opened, ++ create a fake input file that we'll write the merged CTF data to later ++ on. */ ++ ++static void ++ldlang_open_ctf (void) ++{ ++ int any_ctf = 0; ++ int err; ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ asection *sect; ++ ++ /* Incoming files from the compiler have a single ctf_dict_t in them ++ (which is presented to us by the libctf API in a ctf_archive_t ++ wrapper): files derived from a previous relocatable link have a CTF ++ archive containing possibly many CTF files. */ ++ ++ if ((file->the_ctf = ctf_bfdopen (file->the_bfd, &err)) == NULL) ++ { ++ if (err != ECTF_NOCTFDATA) ++ { ++ lang_ctf_errs_warnings (NULL); ++ einfo (_("%P: warning: CTF section in %pB not loaded; " ++ "its types will be discarded: %s\n"), file->the_bfd, ++ ctf_errmsg (err)); ++ } ++ continue; ++ } ++ ++ /* Prevent the contents of this section from being written, while ++ requiring the section itself to be duplicated in the output, but only ++ once. */ ++ /* This section must exist if ctf_bfdopen() succeeded. */ ++ sect = bfd_get_section_by_name (file->the_bfd, ".ctf"); ++ sect->size = 0; ++ sect->flags |= SEC_NEVER_LOAD | SEC_HAS_CONTENTS | SEC_LINKER_CREATED; ++ ++ if (any_ctf) ++ sect->flags |= SEC_EXCLUDE; ++ any_ctf = 1; ++ } ++ ++ if (!any_ctf) ++ { ++ ctf_output = NULL; ++ return; ++ } ++ ++ if ((ctf_output = ctf_create (&err)) != NULL) ++ return; ++ ++ einfo (_("%P: warning: CTF output not created: `%s'\n"), ++ ctf_errmsg (err)); ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (errfile) ++ ctf_close (errfile->the_ctf); ++} ++ ++/* Merge together CTF sections. After this, only the symtab-dependent ++ function and data object sections need adjustment. */ ++ ++static void ++lang_merge_ctf (void) ++{ ++ asection *output_sect; ++ int flags = 0; ++ ++ if (!ctf_output) ++ return; ++ ++ output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf"); ++ ++ /* If the section was discarded, don't waste time merging. */ ++ if (output_sect == NULL) ++ { ++ ctf_dict_close (ctf_output); ++ ctf_output = NULL; ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ ctf_close (file->the_ctf); ++ file->the_ctf = NULL; ++ } ++ return; ++ } ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ if (!file->the_ctf) ++ continue; ++ ++ /* Takes ownership of file->the_ctf. */ ++ if (ctf_link_add_ctf (ctf_output, file->the_ctf, file->filename) < 0) ++ { ++ einfo (_("%P: warning: CTF section in %pB cannot be linked: `%s'\n"), ++ file->the_bfd, ctf_errmsg (ctf_errno (ctf_output))); ++ ctf_close (file->the_ctf); ++ file->the_ctf = NULL; ++ continue; ++ } ++ } ++ ++ if (!config.ctf_share_duplicated) ++ flags = CTF_LINK_SHARE_UNCONFLICTED; ++ else ++ flags = CTF_LINK_SHARE_DUPLICATED; ++ if (!config.ctf_variables) ++ flags |= CTF_LINK_OMIT_VARIABLES_SECTION; ++ if (bfd_link_relocatable (&link_info)) ++ flags |= CTF_LINK_NO_FILTER_REPORTED_SYMS; ++ ++ if (ctf_link (ctf_output, flags) < 0) ++ { ++ lang_ctf_errs_warnings (ctf_output); ++ einfo (_("%P: warning: CTF linking failed; " ++ "output will have no CTF section: %s\n"), ++ ctf_errmsg (ctf_errno (ctf_output))); ++ if (output_sect) ++ { ++ output_sect->size = 0; ++ output_sect->flags |= SEC_EXCLUDE; ++ } ++ } ++ /* Output any lingering errors that didn't come from ctf_link. */ ++ lang_ctf_errs_warnings (ctf_output); ++} ++ ++/* Let the emulation acquire strings from the dynamic strtab to help it optimize ++ the CTF, if supported. */ ++ ++void ++ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab) ++{ ++ ldemul_acquire_strings_for_ctf (ctf_output, dynstrtab); ++} ++ ++/* Inform the emulation about the addition of a new dynamic symbol, in BFD ++ internal format. */ ++void ldlang_ctf_new_dynsym (int symidx, struct elf_internal_sym *sym) ++{ ++ ldemul_new_dynsym_for_ctf (ctf_output, symidx, sym); ++} ++ ++/* Write out the CTF section. Called early, if the emulation isn't going to ++ need to dedup against the strtab and symtab, then possibly called from the ++ target linker code if the dedup has happened. */ ++static void ++lang_write_ctf (int late) ++{ ++ size_t output_size; ++ asection *output_sect; ++ ++ if (!ctf_output) ++ return; ++ ++ if (late) ++ { ++ /* Emit CTF late if this emulation says it can do so. */ ++ if (ldemul_emit_ctf_early ()) ++ return; ++ } ++ else ++ { ++ if (!ldemul_emit_ctf_early ()) ++ return; ++ } ++ ++ /* Inform the emulation that all the symbols that will be received have ++ been. */ ++ ++ ldemul_new_dynsym_for_ctf (ctf_output, 0, NULL); ++ ++ /* Emit CTF. */ ++ ++ output_sect = bfd_get_section_by_name (link_info.output_bfd, ".ctf"); ++ if (output_sect) ++ { ++ output_sect->contents = ctf_link_write (ctf_output, &output_size, ++ CTF_COMPRESSION_THRESHOLD); ++ output_sect->size = output_size; ++ output_sect->flags |= SEC_IN_MEMORY | SEC_KEEP; ++ ++ lang_ctf_errs_warnings (ctf_output); ++ if (!output_sect->contents) ++ { ++ einfo (_("%P: warning: CTF section emission failed; " ++ "output will have no CTF section: %s\n"), ++ ctf_errmsg (ctf_errno (ctf_output))); ++ output_sect->size = 0; ++ output_sect->flags |= SEC_EXCLUDE; ++ } ++ } ++ ++ /* This also closes every CTF input file used in the link. */ ++ ctf_dict_close (ctf_output); ++ ctf_output = NULL; ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ file->the_ctf = NULL; ++} ++ ++/* Write out the CTF section late, if the emulation needs that. */ ++ ++void ++ldlang_write_ctf_late (void) ++{ ++ /* Trigger a "late call", if the emulation needs one. */ ++ ++ lang_write_ctf (1); ++} ++#else ++static void ++ldlang_open_ctf (void) ++{ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ asection *sect; ++ ++ /* If built without CTF, warn and delete all CTF sections from the output. ++ (The alternative would be to simply concatenate them, which does not ++ yield a valid CTF section.) */ ++ ++ if ((sect = bfd_get_section_by_name (file->the_bfd, ".ctf")) != NULL) ++ { ++ einfo (_("%P: warning: CTF section in %pB not linkable: " ++ "%P was built without support for CTF\n"), file->the_bfd); ++ sect->size = 0; ++ sect->flags |= SEC_EXCLUDE; ++ } ++ } ++} ++ ++static void lang_merge_ctf (void) {} ++void ++ldlang_ctf_acquire_strings (struct elf_strtab_hash *dynstrtab ++ ATTRIBUTE_UNUSED) {} ++void ++ldlang_ctf_new_dynsym (int symidx ATTRIBUTE_UNUSED, ++ struct elf_internal_sym *sym ATTRIBUTE_UNUSED) {} ++static void lang_write_ctf (int late ATTRIBUTE_UNUSED) {} ++void ldlang_write_ctf_late (void) {} ++#endif ++ ++/* Add the supplied name to the symbol table as an undefined reference. ++ This is a two step process as the symbol table doesn't even exist at ++ the time the ld command line is processed. First we put the name ++ on a list, then, once the output file has been opened, transfer the ++ name to the symbol table. */ ++ ++typedef struct bfd_sym_chain ldlang_undef_chain_list_type; ++ ++#define ldlang_undef_chain_list_head entry_symbol.next ++ ++void ++ldlang_add_undef (const char *const name, bool cmdline ATTRIBUTE_UNUSED) ++{ ++ ldlang_undef_chain_list_type *new_undef; ++ ++ new_undef = stat_alloc (sizeof (*new_undef)); ++ new_undef->next = ldlang_undef_chain_list_head; ++ ldlang_undef_chain_list_head = new_undef; ++ ++ new_undef->name = xstrdup (name); ++ ++ if (link_info.output_bfd != NULL) ++ insert_undefined (new_undef->name); ++} ++ ++/* Insert NAME as undefined in the symbol table. */ ++ ++static void ++insert_undefined (const char *name) ++{ ++ struct bfd_link_hash_entry *h; ++ ++ h = bfd_link_hash_lookup (link_info.hash, name, true, false, true); ++ if (h == NULL) ++ einfo (_("%F%P: bfd_link_hash_lookup failed: %E\n")); ++ if (h->type == bfd_link_hash_new) ++ { ++ h->type = bfd_link_hash_undefined; ++ h->u.undef.abfd = NULL; ++ h->non_ir_ref_regular = true; ++ bfd_link_add_undef (link_info.hash, h); ++ } ++} ++ ++/* Run through the list of undefineds created above and place them ++ into the linker hash table as undefined symbols belonging to the ++ script file. */ ++ ++static void ++lang_place_undefineds (void) ++{ ++ ldlang_undef_chain_list_type *ptr; ++ ++ for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next) ++ insert_undefined (ptr->name); ++} ++ ++/* Mark -u symbols against garbage collection. */ ++ ++static void ++lang_mark_undefineds (void) ++{ ++ ldlang_undef_chain_list_type *ptr; ++ ++ if (is_elf_hash_table (link_info.hash)) ++ for (ptr = ldlang_undef_chain_list_head; ptr != NULL; ptr = ptr->next) ++ { ++ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ++ bfd_link_hash_lookup (link_info.hash, ptr->name, false, false, true); ++ if (h != NULL) ++ h->mark = 1; ++ } ++} ++ ++/* Structure used to build the list of symbols that the user has required ++ be defined. */ ++ ++struct require_defined_symbol ++{ ++ const char *name; ++ struct require_defined_symbol *next; ++}; ++ ++/* The list of symbols that the user has required be defined. */ ++ ++static struct require_defined_symbol *require_defined_symbol_list; ++ ++/* Add a new symbol NAME to the list of symbols that are required to be ++ defined. */ ++ ++void ++ldlang_add_require_defined (const char *const name) ++{ ++ struct require_defined_symbol *ptr; ++ ++ ldlang_add_undef (name, true); ++ ptr = stat_alloc (sizeof (*ptr)); ++ ptr->next = require_defined_symbol_list; ++ ptr->name = strdup (name); ++ require_defined_symbol_list = ptr; ++} ++ ++/* Check that all symbols the user required to be defined, are defined, ++ raise an error if we find a symbol that is not defined. */ ++ ++static void ++ldlang_check_require_defined_symbols (void) ++{ ++ struct require_defined_symbol *ptr; ++ ++ for (ptr = require_defined_symbol_list; ptr != NULL; ptr = ptr->next) ++ { ++ struct bfd_link_hash_entry *h; ++ ++ h = bfd_link_hash_lookup (link_info.hash, ptr->name, ++ false, false, true); ++ if (h == NULL ++ || (h->type != bfd_link_hash_defined ++ && h->type != bfd_link_hash_defweak)) ++ einfo(_("%X%P: required symbol `%s' not defined\n"), ptr->name); ++ } ++} ++ ++/* Check for all readonly or some readwrite sections. */ ++ ++static void ++check_input_sections ++ (lang_statement_union_type *s, ++ lang_output_section_statement_type *output_section_statement) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ switch (s->header.type) ++ { ++ case lang_wild_statement_enum: ++ walk_wild (&s->wild_statement, check_section_callback, ++ output_section_statement); ++ if (!output_section_statement->all_input_readonly) ++ return; ++ break; ++ case lang_constructors_statement_enum: ++ check_input_sections (constructor_list.head, ++ output_section_statement); ++ if (!output_section_statement->all_input_readonly) ++ return; ++ break; ++ case lang_group_statement_enum: ++ check_input_sections (s->group_statement.children.head, ++ output_section_statement); ++ if (!output_section_statement->all_input_readonly) ++ return; ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++/* Update wildcard statements if needed. */ ++ ++static void ++update_wild_statements (lang_statement_union_type *s) ++{ ++ struct wildcard_list *sec; ++ ++ switch (sort_section) ++ { ++ default: ++ FAIL (); ++ ++ case none: ++ break; ++ ++ case by_name: ++ case by_alignment: ++ for (; s != NULL; s = s->header.next) ++ { ++ switch (s->header.type) ++ { ++ default: ++ break; ++ ++ case lang_wild_statement_enum: ++ for (sec = s->wild_statement.section_list; sec != NULL; ++ sec = sec->next) ++ /* Don't sort .init/.fini sections. */ ++ if (strcmp (sec->spec.name, ".init") != 0 ++ && strcmp (sec->spec.name, ".fini") != 0) ++ { ++ switch (sec->spec.sorted) ++ { ++ case none: ++ sec->spec.sorted = sort_section; ++ break; ++ case by_name: ++ if (sort_section == by_alignment) ++ sec->spec.sorted = by_name_alignment; ++ break; ++ case by_alignment: ++ if (sort_section == by_name) ++ sec->spec.sorted = by_alignment_name; ++ break; ++ default: ++ break; ++ } ++ s->wild_statement.any_specs_sorted = true; ++ } ++ break; ++ ++ case lang_constructors_statement_enum: ++ update_wild_statements (constructor_list.head); ++ break; ++ ++ case lang_output_section_statement_enum: ++ update_wild_statements ++ (s->output_section_statement.children.head); ++ break; ++ ++ case lang_group_statement_enum: ++ update_wild_statements (s->group_statement.children.head); ++ break; ++ } ++ } ++ break; ++ } ++} ++ ++/* Open input files and attach to output sections. */ ++ ++static void ++map_input_to_output_sections ++ (lang_statement_union_type *s, const char *target, ++ lang_output_section_statement_type *os) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ lang_output_section_statement_type *tos; ++ flagword flags; ++ unsigned int type = 0; ++ ++ switch (s->header.type) ++ { ++ case lang_wild_statement_enum: ++ wild (&s->wild_statement, target, os); ++ break; ++ case lang_constructors_statement_enum: ++ map_input_to_output_sections (constructor_list.head, ++ target, ++ os); ++ break; ++ case lang_output_section_statement_enum: ++ tos = &s->output_section_statement; ++ if (tos->constraint == ONLY_IF_RW ++ || tos->constraint == ONLY_IF_RO) ++ { ++ tos->all_input_readonly = true; ++ check_input_sections (tos->children.head, tos); ++ if (tos->all_input_readonly != (tos->constraint == ONLY_IF_RO)) ++ tos->constraint = -1; ++ } ++ if (tos->constraint >= 0) ++ map_input_to_output_sections (tos->children.head, ++ target, ++ tos); ++ break; ++ case lang_output_statement_enum: ++ break; ++ case lang_target_statement_enum: ++ target = s->target_statement.target; ++ break; ++ case lang_group_statement_enum: ++ map_input_to_output_sections (s->group_statement.children.head, ++ target, ++ os); ++ break; ++ case lang_data_statement_enum: ++ /* Make sure that any sections mentioned in the expression ++ are initialized. */ ++ exp_init_os (s->data_statement.exp); ++ /* The output section gets CONTENTS, ALLOC and LOAD, but ++ these may be overridden by the script. */ ++ flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD; ++ switch (os->sectype) ++ { ++ case normal_section: ++ case overlay_section: ++ case first_overlay_section: ++ break; ++ case noalloc_section: ++ flags = SEC_HAS_CONTENTS; ++ break; ++ case readonly_section: ++ flags |= SEC_READONLY; ++ break; ++ case typed_readonly_section: ++ flags |= SEC_READONLY; ++ /* Fall through. */ ++ case type_section: ++ if (os->sectype_value->type.node_class == etree_name ++ && os->sectype_value->type.node_code == NAME) ++ { ++ const char *name = os->sectype_value->name.name; ++ if (strcmp (name, "SHT_PROGBITS") == 0) ++ type = SHT_PROGBITS; ++ else if (strcmp (name, "SHT_STRTAB") == 0) ++ type = SHT_STRTAB; ++ else if (strcmp (name, "SHT_NOTE") == 0) ++ type = SHT_NOTE; ++ else if (strcmp (name, "SHT_NOBITS") == 0) ++ type = SHT_NOBITS; ++ else if (strcmp (name, "SHT_INIT_ARRAY") == 0) ++ type = SHT_INIT_ARRAY; ++ else if (strcmp (name, "SHT_FINI_ARRAY") == 0) ++ type = SHT_FINI_ARRAY; ++ else if (strcmp (name, "SHT_PREINIT_ARRAY") == 0) ++ type = SHT_PREINIT_ARRAY; ++ else ++ einfo (_ ("%F%P: invalid type for output section `%s'\n"), ++ os->name); ++ } ++ else ++ { ++ exp_fold_tree_no_dot (os->sectype_value); ++ if (expld.result.valid_p) ++ type = expld.result.value; ++ else ++ einfo (_ ("%F%P: invalid type for output section `%s'\n"), ++ os->name); ++ } ++ break; ++ case noload_section: ++ if (bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_elf_flavour) ++ flags = SEC_NEVER_LOAD | SEC_ALLOC; ++ else ++ flags = SEC_NEVER_LOAD | SEC_HAS_CONTENTS; ++ break; ++ } ++ if (os->bfd_section == NULL) ++ init_os (os, flags | SEC_READONLY); ++ else ++ os->bfd_section->flags |= flags; ++ os->bfd_section->type = type; ++ break; ++ case lang_input_section_enum: ++ break; ++ case lang_fill_statement_enum: ++ case lang_object_symbols_statement_enum: ++ case lang_reloc_statement_enum: ++ case lang_padding_statement_enum: ++ case lang_input_statement_enum: ++ if (os != NULL && os->bfd_section == NULL) ++ init_os (os, 0); ++ break; ++ case lang_assignment_statement_enum: ++ if (os != NULL && os->bfd_section == NULL) ++ init_os (os, 0); ++ ++ /* Make sure that any sections mentioned in the assignment ++ are initialized. */ ++ exp_init_os (s->assignment_statement.exp); ++ break; ++ case lang_address_statement_enum: ++ /* Mark the specified section with the supplied address. ++ If this section was actually a segment marker, then the ++ directive is ignored if the linker script explicitly ++ processed the segment marker. Originally, the linker ++ treated segment directives (like -Ttext on the ++ command-line) as section directives. We honor the ++ section directive semantics for backwards compatibility; ++ linker scripts that do not specifically check for ++ SEGMENT_START automatically get the old semantics. */ ++ if (!s->address_statement.segment ++ || !s->address_statement.segment->used) ++ { ++ const char *name = s->address_statement.section_name; ++ ++ /* Create the output section statement here so that ++ orphans with a set address will be placed after other ++ script sections. If we let the orphan placement code ++ place them in amongst other sections then the address ++ will affect following script sections, which is ++ likely to surprise naive users. */ ++ tos = lang_output_section_statement_lookup (name, 0, 1); ++ tos->addr_tree = s->address_statement.address; ++ if (tos->bfd_section == NULL) ++ init_os (tos, 0); ++ } ++ break; ++ case lang_insert_statement_enum: ++ break; ++ case lang_input_matcher_enum: ++ FAIL (); ++ } ++ } ++} ++ ++/* An insert statement snips out all the linker statements from the ++ start of the list and places them after the output section ++ statement specified by the insert. This operation is complicated ++ by the fact that we keep a doubly linked list of output section ++ statements as well as the singly linked list of all statements. ++ FIXME someday: Twiddling with the list not only moves statements ++ from the user's script but also input and group statements that are ++ built from command line object files and --start-group. We only ++ get away with this because the list pointers used by file_chain ++ and input_file_chain are not reordered, and processing via ++ statement_list after this point mostly ignores input statements. ++ One exception is the map file, where LOAD and START GROUP/END GROUP ++ can end up looking odd. */ ++ ++static void ++process_insert_statements (lang_statement_union_type **start) ++{ ++ lang_statement_union_type **s; ++ lang_output_section_statement_type *first_os = NULL; ++ lang_output_section_statement_type *last_os = NULL; ++ lang_output_section_statement_type *os; ++ ++ s = start; ++ while (*s != NULL) ++ { ++ if ((*s)->header.type == lang_output_section_statement_enum) ++ { ++ /* Keep pointers to the first and last output section ++ statement in the sequence we may be about to move. */ ++ os = &(*s)->output_section_statement; ++ ++ ASSERT (last_os == NULL || last_os->next == os); ++ last_os = os; ++ ++ /* Set constraint negative so that lang_output_section_find ++ won't match this output section statement. At this ++ stage in linking constraint has values in the range ++ [-1, ONLY_IN_RW]. */ ++ last_os->constraint = -2 - last_os->constraint; ++ if (first_os == NULL) ++ first_os = last_os; ++ } ++ else if ((*s)->header.type == lang_group_statement_enum) ++ { ++ /* A user might put -T between --start-group and ++ --end-group. One way this odd construct might arise is ++ from a wrapper around ld to change library search ++ behaviour. For example: ++ #! /bin/sh ++ exec real_ld --start-group "$@" --end-group ++ This isn't completely unreasonable so go looking inside a ++ group statement for insert statements. */ ++ process_insert_statements (&(*s)->group_statement.children.head); ++ } ++ else if ((*s)->header.type == lang_insert_statement_enum) ++ { ++ lang_insert_statement_type *i = &(*s)->insert_statement; ++ lang_output_section_statement_type *where; ++ lang_statement_union_type **ptr; ++ lang_statement_union_type *first; ++ ++ if (link_info.non_contiguous_regions) ++ { ++ einfo (_("warning: INSERT statement in linker script is " ++ "incompatible with --enable-non-contiguous-regions.\n")); ++ } ++ ++ where = lang_output_section_find (i->where); ++ if (where != NULL && i->is_before) ++ { ++ do ++ where = where->prev; ++ while (where != NULL && where->constraint < 0); ++ } ++ if (where == NULL) ++ { ++ einfo (_("%F%P: %s not found for insert\n"), i->where); ++ return; ++ } ++ ++ /* Deal with reordering the output section statement list. */ ++ if (last_os != NULL) ++ { ++ asection *first_sec, *last_sec; ++ struct lang_output_section_statement_struct **next; ++ ++ /* Snip out the output sections we are moving. */ ++ first_os->prev->next = last_os->next; ++ if (last_os->next == NULL) ++ { ++ next = &first_os->prev->next; ++ lang_os_list.tail = (lang_statement_union_type **) next; ++ } ++ else ++ last_os->next->prev = first_os->prev; ++ /* Add them in at the new position. */ ++ last_os->next = where->next; ++ if (where->next == NULL) ++ { ++ next = &last_os->next; ++ lang_os_list.tail = (lang_statement_union_type **) next; ++ } ++ else ++ where->next->prev = last_os; ++ first_os->prev = where; ++ where->next = first_os; ++ ++ /* Move the bfd sections in the same way. */ ++ first_sec = NULL; ++ last_sec = NULL; ++ for (os = first_os; os != NULL; os = os->next) ++ { ++ os->constraint = -2 - os->constraint; ++ if (os->bfd_section != NULL ++ && os->bfd_section->owner != NULL) ++ { ++ last_sec = os->bfd_section; ++ if (first_sec == NULL) ++ first_sec = last_sec; ++ } ++ if (os == last_os) ++ break; ++ } ++ if (last_sec != NULL) ++ { ++ asection *sec = where->bfd_section; ++ if (sec == NULL) ++ sec = output_prev_sec_find (where); ++ ++ /* The place we want to insert must come after the ++ sections we are moving. So if we find no ++ section or if the section is the same as our ++ last section, then no move is needed. */ ++ if (sec != NULL && sec != last_sec) ++ { ++ /* Trim them off. */ ++ if (first_sec->prev != NULL) ++ first_sec->prev->next = last_sec->next; ++ else ++ link_info.output_bfd->sections = last_sec->next; ++ if (last_sec->next != NULL) ++ last_sec->next->prev = first_sec->prev; ++ else ++ link_info.output_bfd->section_last = first_sec->prev; ++ /* Add back. */ ++ if (sec->owner == NULL) ++ /* SEC is the absolute section, from the ++ first dummy output section statement. Add ++ back the sections we trimmed off to the ++ start of the bfd sections. */ ++ sec = NULL; ++ if (sec != NULL) ++ last_sec->next = sec->next; ++ else ++ last_sec->next = link_info.output_bfd->sections; ++ if (last_sec->next != NULL) ++ last_sec->next->prev = last_sec; ++ else ++ link_info.output_bfd->section_last = last_sec; ++ first_sec->prev = sec; ++ if (first_sec->prev != NULL) ++ first_sec->prev->next = first_sec; ++ else ++ link_info.output_bfd->sections = first_sec; ++ } ++ } ++ } ++ ++ lang_statement_union_type *after = (void *) where; ++ if (where == &lang_os_list.head->output_section_statement ++ && where->next == first_os) ++ { ++ /* PR30155. Handle a corner case where the statement ++ list is something like the following: ++ . LOAD t.o ++ . .data 0x0000000000000000 0x0 ++ . [0x0000000000000000] b = . ++ . *(.data) ++ . .data 0x0000000000000000 0x0 t.o ++ . 0x0000000000000000 0x4 LONG 0x0 ++ . INSERT BEFORE .text.start ++ . [0x0000000000000004] a = . ++ . .text.start 0x0000000000000000 0x0 ++ . [0x0000000000000000] c = . ++ . OUTPUT(a.out elf64-x86-64) ++ Here we do not want to allow insert_os_after to ++ choose a point inside the list we are moving. ++ That would lose the list. Instead, let ++ insert_os_after work from the INSERT, which in this ++ particular example will result in inserting after ++ the assignment "a = .". */ ++ after = *s; ++ } ++ ptr = insert_os_after (after); ++ /* Snip everything from the start of the list, up to and ++ including the insert statement we are currently processing. */ ++ first = *start; ++ *start = (*s)->header.next; ++ /* Add them back where they belong, minus the insert. */ ++ *s = *ptr; ++ if (*s == NULL) ++ statement_list.tail = s; ++ *ptr = first; ++ s = start; ++ first_os = NULL; ++ last_os = NULL; ++ continue; ++ } ++ s = &(*s)->header.next; ++ } ++ ++ /* Undo constraint twiddling. */ ++ for (os = first_os; os != NULL; os = os->next) ++ { ++ os->constraint = -2 - os->constraint; ++ if (os == last_os) ++ break; ++ } ++} ++ ++/* An output section might have been removed after its statement was ++ added. For example, ldemul_before_allocation can remove dynamic ++ sections if they turn out to be not needed. Clean them up here. */ ++ ++void ++strip_excluded_output_sections (void) ++{ ++ lang_output_section_statement_type *os; ++ ++ /* Run lang_size_sections (if not already done). */ ++ if (expld.phase != lang_mark_phase_enum) ++ { ++ expld.phase = lang_mark_phase_enum; ++ expld.dataseg.phase = exp_seg_none; ++ one_lang_size_sections_pass (NULL, false); ++ lang_reset_memory_regions (); ++ } ++ ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ asection *output_section; ++ bool exclude; ++ ++ if (os->constraint < 0) ++ continue; ++ ++ output_section = os->bfd_section; ++ if (output_section == NULL) ++ continue; ++ ++ exclude = (output_section->rawsize == 0 ++ && (output_section->flags & SEC_KEEP) == 0 ++ && !bfd_section_removed_from_list (link_info.output_bfd, ++ output_section)); ++ ++ /* Some sections have not yet been sized, notably .gnu.version, ++ .dynsym, .dynstr and .hash. These all have SEC_LINKER_CREATED ++ input sections, so don't drop output sections that have such ++ input sections unless they are also marked SEC_EXCLUDE. */ ++ if (exclude && output_section->map_head.s != NULL) ++ { ++ asection *s; ++ ++ for (s = output_section->map_head.s; s != NULL; s = s->map_head.s) ++ if ((s->flags & SEC_EXCLUDE) == 0 ++ && ((s->flags & SEC_LINKER_CREATED) != 0 ++ || link_info.emitrelocations)) ++ { ++ exclude = false; ++ break; ++ } ++ } ++ ++ if (exclude) ++ { ++ /* We don't set bfd_section to NULL since bfd_section of the ++ removed output section statement may still be used. */ ++ if (!os->update_dot) ++ os->ignored = true; ++ output_section->flags |= SEC_EXCLUDE; ++ bfd_section_list_remove (link_info.output_bfd, output_section); ++ link_info.output_bfd->section_count--; ++ } ++ } ++} ++ ++/* Called from ldwrite to clear out asection.map_head and ++ asection.map_tail for use as link_orders in ldwrite. */ ++ ++void ++lang_clear_os_map (void) ++{ ++ lang_output_section_statement_type *os; ++ ++ if (map_head_is_link_order) ++ return; ++ ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ asection *output_section; ++ ++ if (os->constraint < 0) ++ continue; ++ ++ output_section = os->bfd_section; ++ if (output_section == NULL) ++ continue; ++ ++ /* TODO: Don't just junk map_head.s, turn them into link_orders. */ ++ output_section->map_head.link_order = NULL; ++ output_section->map_tail.link_order = NULL; ++ } ++ ++ /* Stop future calls to lang_add_section from messing with map_head ++ and map_tail link_order fields. */ ++ map_head_is_link_order = true; ++} ++ ++static void ++print_output_section_statement ++ (lang_output_section_statement_type *output_section_statement) ++{ ++ asection *section = output_section_statement->bfd_section; ++ int len; ++ ++ if (output_section_statement != abs_output_section) ++ { ++ minfo ("\n%s", output_section_statement->name); ++ ++ if (section != NULL) ++ { ++ print_dot = section->vma; ++ ++ len = strlen (output_section_statement->name); ++ if (len >= SECTION_NAME_MAP_LENGTH - 1) ++ { ++ print_nl (); ++ len = 0; ++ } ++ print_spaces (SECTION_NAME_MAP_LENGTH - len); ++ ++ minfo ("0x%V %W", section->vma, TO_ADDR (section->size)); ++ ++ if (section->vma != section->lma) ++ minfo (_(" load address 0x%V"), section->lma); ++ ++ if (output_section_statement->update_dot_tree != NULL) ++ exp_fold_tree (output_section_statement->update_dot_tree, ++ bfd_abs_section_ptr, &print_dot); ++ } ++ ++ print_nl (); ++ } ++ ++ print_statement_list (output_section_statement->children.head, ++ output_section_statement); ++} ++ ++static void ++print_assignment (lang_assignment_statement_type *assignment, ++ lang_output_section_statement_type *output_section) ++{ ++ bool is_dot; ++ etree_type *tree; ++ asection *osec; ++ ++ print_spaces (SECTION_NAME_MAP_LENGTH); ++ ++ if (assignment->exp->type.node_class == etree_assert) ++ { ++ is_dot = false; ++ tree = assignment->exp->assert_s.child; ++ } ++ else ++ { ++ const char *dst = assignment->exp->assign.dst; ++ ++ is_dot = (dst[0] == '.' && dst[1] == 0); ++ tree = assignment->exp; ++ } ++ ++ osec = output_section->bfd_section; ++ if (osec == NULL) ++ osec = bfd_abs_section_ptr; ++ ++ if (assignment->exp->type.node_class != etree_provide) ++ exp_fold_tree (tree, osec, &print_dot); ++ else ++ expld.result.valid_p = false; ++ ++ char buf[32]; ++ const char *str = buf; ++ if (expld.result.valid_p) ++ { ++ bfd_vma value; ++ ++ if (assignment->exp->type.node_class == etree_assert ++ || is_dot ++ || expld.assign_name != NULL) ++ { ++ value = expld.result.value; ++ ++ if (expld.result.section != NULL) ++ value += expld.result.section->vma; ++ ++ buf[0] = '0'; ++ buf[1] = 'x'; ++ bfd_sprintf_vma (link_info.output_bfd, buf + 2, value); ++ if (is_dot) ++ print_dot = value; ++ } ++ else ++ { ++ struct bfd_link_hash_entry *h; ++ ++ h = bfd_link_hash_lookup (link_info.hash, assignment->exp->assign.dst, ++ false, false, true); ++ if (h != NULL ++ && (h->type == bfd_link_hash_defined ++ || h->type == bfd_link_hash_defweak)) ++ { ++ value = h->u.def.value; ++ value += h->u.def.section->output_section->vma; ++ value += h->u.def.section->output_offset; ++ ++ buf[0] = '['; ++ buf[1] = '0'; ++ buf[2] = 'x'; ++ bfd_sprintf_vma (link_info.output_bfd, buf + 3, value); ++ strcat (buf, "]"); ++ } ++ else ++ str = "[unresolved]"; ++ } ++ } ++ else ++ { ++ if (assignment->exp->type.node_class == etree_provide) ++ str = "[!provide]"; ++ else ++ str = "*undef*"; ++ } ++ expld.assign_name = NULL; ++ ++ fprintf (config.map_file, "%-34s", str); ++ exp_print_tree (assignment->exp); ++ print_nl (); ++} ++ ++static void ++print_input_statement (lang_input_statement_type *statm) ++{ ++ if (statm->filename != NULL) ++ fprintf (config.map_file, "LOAD %s\n", statm->filename); ++} ++ ++/* Print all symbols defined in a particular section. This is called ++ via bfd_link_hash_traverse, or by print_all_symbols. */ ++ ++bool ++print_one_symbol (struct bfd_link_hash_entry *hash_entry, void *ptr) ++{ ++ asection *sec = (asection *) ptr; ++ ++ if ((hash_entry->type == bfd_link_hash_defined ++ || hash_entry->type == bfd_link_hash_defweak) ++ && sec == hash_entry->u.def.section) ++ { ++ print_spaces (SECTION_NAME_MAP_LENGTH); ++ minfo ("0x%V ", ++ (hash_entry->u.def.value ++ + hash_entry->u.def.section->output_offset ++ + hash_entry->u.def.section->output_section->vma)); ++ ++ minfo (" %pT\n", hash_entry->root.string); ++ } ++ ++ return true; ++} ++ ++static int ++hash_entry_addr_cmp (const void *a, const void *b) ++{ ++ const struct bfd_link_hash_entry *l = *(const struct bfd_link_hash_entry **)a; ++ const struct bfd_link_hash_entry *r = *(const struct bfd_link_hash_entry **)b; ++ ++ if (l->u.def.value < r->u.def.value) ++ return -1; ++ else if (l->u.def.value > r->u.def.value) ++ return 1; ++ else ++ return 0; ++} ++ ++static void ++print_all_symbols (asection *sec) ++{ ++ input_section_userdata_type *ud = bfd_section_userdata (sec); ++ struct map_symbol_def *def; ++ struct bfd_link_hash_entry **entries; ++ unsigned int i; ++ ++ if (!ud) ++ return; ++ ++ *ud->map_symbol_def_tail = 0; ++ ++ /* Sort the symbols by address. */ ++ entries = (struct bfd_link_hash_entry **) ++ obstack_alloc (&map_obstack, ++ ud->map_symbol_def_count * sizeof (*entries)); ++ ++ for (i = 0, def = ud->map_symbol_def_head; def; def = def->next, i++) ++ entries[i] = def->entry; ++ ++ qsort (entries, ud->map_symbol_def_count, sizeof (*entries), ++ hash_entry_addr_cmp); ++ ++ /* Print the symbols. */ ++ for (i = 0; i < ud->map_symbol_def_count; i++) ++ ldemul_print_symbol (entries[i], sec); ++ ++ obstack_free (&map_obstack, entries); ++} ++ ++/* Returns TRUE if SYM is a symbol suitable for printing ++ in a linker map as a local symbol. */ ++ ++static bool ++ld_is_local_symbol (asymbol * sym) ++{ ++ const char * name = bfd_asymbol_name (sym); ++ ++ if (name == NULL || *name == 0) ++ return false; ++ ++ if (strcmp (name, "(null)") == 0) ++ return false; ++ ++ /* Skip .Lxxx and such like. */ ++ if (bfd_is_local_label (link_info.output_bfd, sym)) ++ return false; ++ ++ /* FIXME: This is intended to skip ARM mapping symbols, ++ which for some reason are not excluded by bfd_is_local_label, ++ but maybe it is wrong for other architectures. ++ It would be better to fix bfd_is_local_label. */ ++ if (*name == '$') ++ return false; ++ ++ /* Some local symbols, eg _GLOBAL_OFFSET_TABLE_, are present ++ in the hash table, so do not print duplicates here. */ ++ struct bfd_link_hash_entry * h; ++ h = bfd_link_hash_lookup (link_info.hash, name, false /* create */, ++ false /* copy */, true /* follow */); ++ if (h == NULL) ++ return true; ++ ++ /* Symbols from the plugin owned BFD will not get their own ++ iteration of this function, but can be on the link_info ++ list. So include them here. */ ++ if (h->u.def.section->owner != NULL ++ && ((bfd_get_file_flags (h->u.def.section->owner) & (BFD_LINKER_CREATED | BFD_PLUGIN)) ++ == (BFD_LINKER_CREATED | BFD_PLUGIN))) ++ return true; ++ ++ return false; ++} ++ ++/* Print information about an input section to the map file. */ ++ ++static void ++print_input_section (asection *i, bool is_discarded) ++{ ++ bfd_size_type size = i->size; ++ int len; ++ bfd_vma addr; ++ ++ init_opb (i); ++ ++ minfo (" %s", i->name); ++ ++ len = 1 + strlen (i->name); ++ if (len >= SECTION_NAME_MAP_LENGTH - 1) ++ { ++ print_nl (); ++ len = 0; ++ } ++ print_spaces (SECTION_NAME_MAP_LENGTH - len); ++ ++ if (i->output_section != NULL ++ && i->output_section->owner == link_info.output_bfd) ++ addr = i->output_section->vma + i->output_offset; ++ else ++ { ++ addr = print_dot; ++ if (!is_discarded) ++ size = 0; ++ } ++ ++ char buf[32]; ++ bfd_sprintf_vma (link_info.output_bfd, buf, addr); ++ minfo ("0x%s %W %pB\n", buf, TO_ADDR (size), i->owner); ++ ++ if (size != i->rawsize && i->rawsize != 0) ++ { ++ len = SECTION_NAME_MAP_LENGTH + 3 + strlen (buf); ++ print_spaces (len); ++ minfo (_("%W (size before relaxing)\n"), TO_ADDR (i->rawsize)); ++ } ++ ++ if (i->output_section != NULL ++ && i->output_section->owner == link_info.output_bfd) ++ { ++ if (link_info.reduce_memory_overheads) ++ bfd_link_hash_traverse (link_info.hash, ldemul_print_symbol, i); ++ else ++ print_all_symbols (i); ++ ++ /* Update print_dot, but make sure that we do not move it ++ backwards - this could happen if we have overlays and a ++ later overlay is shorter than an earier one. */ ++ if (addr + TO_ADDR (size) > print_dot) ++ print_dot = addr + TO_ADDR (size); ++ ++ if (config.print_map_locals) ++ { ++ long storage_needed; ++ ++ /* FIXME: It would be better to cache this table, rather ++ than recreating it for each output section. */ ++ /* FIXME: This call is not working for non-ELF based targets. ++ Find out why. */ ++ storage_needed = bfd_get_symtab_upper_bound (link_info.output_bfd); ++ if (storage_needed > 0) ++ { ++ asymbol ** symbol_table; ++ long number_of_symbols; ++ long j; ++ ++ symbol_table = xmalloc (storage_needed); ++ number_of_symbols = bfd_canonicalize_symtab (link_info.output_bfd, symbol_table); ++ ++ for (j = 0; j < number_of_symbols; j++) ++ { ++ asymbol * sym = symbol_table[j]; ++ bfd_vma sym_addr = sym->value + i->output_section->vma; ++ ++ if (sym->section == i->output_section ++ && (sym->flags & BSF_LOCAL) != 0 ++ && sym_addr >= addr ++ && sym_addr < print_dot ++ && ld_is_local_symbol (sym)) ++ { ++ print_spaces (SECTION_NAME_MAP_LENGTH); ++ minfo ("0x%V (local) %s\n", sym_addr, bfd_asymbol_name (sym)); ++ } ++ } ++ ++ free (symbol_table); ++ } ++ } ++ } ++} ++ ++static void ++print_fill_statement (lang_fill_statement_type *fill) ++{ ++ size_t size; ++ unsigned char *p; ++ fputs (" FILL mask 0x", config.map_file); ++ for (p = fill->fill->data, size = fill->fill->size; size != 0; p++, size--) ++ fprintf (config.map_file, "%02x", *p); ++ fputs ("\n", config.map_file); ++} ++ ++static void ++print_data_statement (lang_data_statement_type *data) ++{ ++ bfd_vma addr; ++ bfd_size_type size; ++ const char *name; ++ ++ init_opb (data->output_section); ++ print_spaces (SECTION_NAME_MAP_LENGTH); ++ ++ addr = data->output_offset; ++ if (data->output_section != NULL) ++ addr += data->output_section->vma; ++ ++ switch (data->type) ++ { ++ default: ++ abort (); ++ case BYTE: ++ size = BYTE_SIZE; ++ name = "BYTE"; ++ break; ++ case SHORT: ++ size = SHORT_SIZE; ++ name = "SHORT"; ++ break; ++ case LONG: ++ size = LONG_SIZE; ++ name = "LONG"; ++ break; ++ case QUAD: ++ size = QUAD_SIZE; ++ name = "QUAD"; ++ break; ++ case SQUAD: ++ size = QUAD_SIZE; ++ name = "SQUAD"; ++ break; ++ } ++ ++ if (size < TO_SIZE ((unsigned) 1)) ++ size = TO_SIZE ((unsigned) 1); ++ minfo ("0x%V %W %s 0x%v", addr, TO_ADDR (size), name, data->value); ++ ++ if (data->exp->type.node_class != etree_value) ++ { ++ print_space (); ++ exp_print_tree (data->exp); ++ } ++ ++ print_nl (); ++ ++ print_dot = addr + TO_ADDR (size); ++} ++ ++/* Print an address statement. These are generated by options like ++ -Ttext. */ ++ ++static void ++print_address_statement (lang_address_statement_type *address) ++{ ++ minfo (_("Address of section %s set to "), address->section_name); ++ exp_print_tree (address->address); ++ print_nl (); ++} ++ ++/* Print a reloc statement. */ ++ ++static void ++print_reloc_statement (lang_reloc_statement_type *reloc) ++{ ++ bfd_vma addr; ++ bfd_size_type size; ++ ++ init_opb (reloc->output_section); ++ print_spaces (SECTION_NAME_MAP_LENGTH); ++ ++ addr = reloc->output_offset; ++ if (reloc->output_section != NULL) ++ addr += reloc->output_section->vma; ++ ++ size = bfd_get_reloc_size (reloc->howto); ++ ++ minfo ("0x%V %W RELOC %s ", addr, TO_ADDR (size), reloc->howto->name); ++ ++ if (reloc->name != NULL) ++ minfo ("%s+", reloc->name); ++ else ++ minfo ("%s+", reloc->section->name); ++ ++ exp_print_tree (reloc->addend_exp); ++ ++ print_nl (); ++ ++ print_dot = addr + TO_ADDR (size); ++} ++ ++static void ++print_padding_statement (lang_padding_statement_type *s) ++{ ++ int len; ++ bfd_vma addr; ++ ++ init_opb (s->output_section); ++ minfo (" *fill*"); ++ ++ len = sizeof " *fill*" - 1; ++ print_spaces (SECTION_NAME_MAP_LENGTH - len); ++ ++ addr = s->output_offset; ++ if (s->output_section != NULL) ++ addr += s->output_section->vma; ++ minfo ("0x%V %W ", addr, TO_ADDR (s->size)); ++ ++ if (s->fill->size != 0) ++ { ++ size_t size; ++ unsigned char *p; ++ for (p = s->fill->data, size = s->fill->size; size != 0; p++, size--) ++ fprintf (config.map_file, "%02x", *p); ++ } ++ ++ print_nl (); ++ ++ print_dot = addr + TO_ADDR (s->size); ++} ++ ++static void ++print_wild_statement (lang_wild_statement_type *w, ++ lang_output_section_statement_type *os) ++{ ++ struct wildcard_list *sec; ++ ++ print_space (); ++ ++ if (w->exclude_name_list) ++ { ++ name_list *tmp; ++ minfo ("EXCLUDE_FILE(%s", w->exclude_name_list->name); ++ for (tmp = w->exclude_name_list->next; tmp; tmp = tmp->next) ++ minfo (" %s", tmp->name); ++ minfo (") "); ++ } ++ ++ if (w->filenames_sorted) ++ minfo ("SORT_BY_NAME("); ++ if (w->filename != NULL) ++ minfo ("%s", w->filename); ++ else ++ minfo ("*"); ++ if (w->filenames_sorted) ++ minfo (")"); ++ ++ minfo ("("); ++ for (sec = w->section_list; sec; sec = sec->next) ++ { ++ int closing_paren = 0; ++ ++ switch (sec->spec.sorted) ++ { ++ case none: ++ break; ++ ++ case by_name: ++ minfo ("SORT_BY_NAME("); ++ closing_paren = 1; ++ break; ++ ++ case by_alignment: ++ minfo ("SORT_BY_ALIGNMENT("); ++ closing_paren = 1; ++ break; ++ ++ case by_name_alignment: ++ minfo ("SORT_BY_NAME(SORT_BY_ALIGNMENT("); ++ closing_paren = 2; ++ break; ++ ++ case by_alignment_name: ++ minfo ("SORT_BY_ALIGNMENT(SORT_BY_NAME("); ++ closing_paren = 2; ++ break; ++ ++ case by_none: ++ minfo ("SORT_NONE("); ++ closing_paren = 1; ++ break; ++ ++ case by_init_priority: ++ minfo ("SORT_BY_INIT_PRIORITY("); ++ closing_paren = 1; ++ break; ++ } ++ ++ if (sec->spec.exclude_name_list != NULL) ++ { ++ name_list *tmp; ++ minfo ("EXCLUDE_FILE(%s", sec->spec.exclude_name_list->name); ++ for (tmp = sec->spec.exclude_name_list->next; tmp; tmp = tmp->next) ++ minfo (" %s", tmp->name); ++ minfo (") "); ++ } ++ if (sec->spec.name != NULL) ++ minfo ("%s", sec->spec.name); ++ else ++ minfo ("*"); ++ for (;closing_paren > 0; closing_paren--) ++ minfo (")"); ++ if (sec->next) ++ minfo (" "); ++ } ++ minfo (")"); ++ ++ print_nl (); ++ ++ print_statement_list (w->children.head, os); ++} ++ ++/* Print a group statement. */ ++ ++static void ++print_group (lang_group_statement_type *s, ++ lang_output_section_statement_type *os) ++{ ++ fprintf (config.map_file, "START GROUP\n"); ++ print_statement_list (s->children.head, os); ++ fprintf (config.map_file, "END GROUP\n"); ++} ++ ++/* Print the list of statements in S. ++ This can be called for any statement type. */ ++ ++static void ++print_statement_list (lang_statement_union_type *s, ++ lang_output_section_statement_type *os) ++{ ++ while (s != NULL) ++ { ++ print_statement (s, os); ++ s = s->header.next; ++ } ++} ++ ++/* Print the first statement in statement list S. ++ This can be called for any statement type. */ ++ ++static void ++print_statement (lang_statement_union_type *s, ++ lang_output_section_statement_type *os) ++{ ++ switch (s->header.type) ++ { ++ default: ++ fprintf (config.map_file, _("Fail with %d\n"), s->header.type); ++ FAIL (); ++ break; ++ case lang_constructors_statement_enum: ++ if (constructor_list.head != NULL) ++ { ++ if (constructors_sorted) ++ minfo (" SORT (CONSTRUCTORS)\n"); ++ else ++ minfo (" CONSTRUCTORS\n"); ++ print_statement_list (constructor_list.head, os); ++ } ++ break; ++ case lang_wild_statement_enum: ++ print_wild_statement (&s->wild_statement, os); ++ break; ++ case lang_address_statement_enum: ++ print_address_statement (&s->address_statement); ++ break; ++ case lang_object_symbols_statement_enum: ++ minfo (" CREATE_OBJECT_SYMBOLS\n"); ++ break; ++ case lang_fill_statement_enum: ++ print_fill_statement (&s->fill_statement); ++ break; ++ case lang_data_statement_enum: ++ print_data_statement (&s->data_statement); ++ break; ++ case lang_reloc_statement_enum: ++ print_reloc_statement (&s->reloc_statement); ++ break; ++ case lang_input_section_enum: ++ print_input_section (s->input_section.section, false); ++ break; ++ case lang_padding_statement_enum: ++ print_padding_statement (&s->padding_statement); ++ break; ++ case lang_output_section_statement_enum: ++ print_output_section_statement (&s->output_section_statement); ++ break; ++ case lang_assignment_statement_enum: ++ print_assignment (&s->assignment_statement, os); ++ break; ++ case lang_target_statement_enum: ++ fprintf (config.map_file, "TARGET(%s)\n", s->target_statement.target); ++ break; ++ case lang_output_statement_enum: ++ minfo ("OUTPUT(%s", s->output_statement.name); ++ if (output_target != NULL) ++ minfo (" %s", output_target); ++ minfo (")\n"); ++ break; ++ case lang_input_statement_enum: ++ print_input_statement (&s->input_statement); ++ break; ++ case lang_group_statement_enum: ++ print_group (&s->group_statement, os); ++ break; ++ case lang_insert_statement_enum: ++ minfo ("INSERT %s %s\n", ++ s->insert_statement.is_before ? "BEFORE" : "AFTER", ++ s->insert_statement.where); ++ break; ++ } ++} ++ ++static void ++print_statements (void) ++{ ++ print_statement_list (statement_list.head, abs_output_section); ++} ++ ++/* Print the first N statements in statement list S to STDERR. ++ If N == 0, nothing is printed. ++ If N < 0, the entire list is printed. ++ Intended to be called from GDB. */ ++ ++void ++dprint_statement (lang_statement_union_type *s, int n) ++{ ++ FILE *map_save = config.map_file; ++ ++ config.map_file = stderr; ++ ++ if (n < 0) ++ print_statement_list (s, abs_output_section); ++ else ++ { ++ while (s && --n >= 0) ++ { ++ print_statement (s, abs_output_section); ++ s = s->header.next; ++ } ++ } ++ ++ config.map_file = map_save; ++} ++ ++static void ++insert_pad (lang_statement_union_type **ptr, ++ fill_type *fill, ++ bfd_size_type alignment_needed, ++ asection *output_section, ++ bfd_vma dot) ++{ ++ static fill_type zero_fill; ++ lang_statement_union_type *pad = NULL; ++ ++ if (ptr != &statement_list.head) ++ pad = ((lang_statement_union_type *) ++ ((char *) ptr - offsetof (lang_statement_union_type, header.next))); ++ if (pad != NULL ++ && pad->header.type == lang_padding_statement_enum ++ && pad->padding_statement.output_section == output_section) ++ { ++ /* Use the existing pad statement. */ ++ } ++ else if ((pad = *ptr) != NULL ++ && pad->header.type == lang_padding_statement_enum ++ && pad->padding_statement.output_section == output_section) ++ { ++ /* Use the existing pad statement. */ ++ } ++ else ++ { ++ /* Make a new padding statement, linked into existing chain. */ ++ pad = stat_alloc (sizeof (lang_padding_statement_type)); ++ pad->header.next = *ptr; ++ *ptr = pad; ++ pad->header.type = lang_padding_statement_enum; ++ pad->padding_statement.output_section = output_section; ++ if (fill == NULL) ++ fill = &zero_fill; ++ pad->padding_statement.fill = fill; ++ } ++ pad->padding_statement.output_offset = dot - output_section->vma; ++ pad->padding_statement.size = alignment_needed; ++ if (!(output_section->flags & SEC_FIXED_SIZE)) ++ output_section->size = TO_SIZE (dot + TO_ADDR (alignment_needed) ++ - output_section->vma); ++} ++ ++/* Work out how much this section will move the dot point. */ ++ ++static bfd_vma ++size_input_section ++ (lang_statement_union_type **this_ptr, ++ lang_output_section_statement_type *output_section_statement, ++ fill_type *fill, ++ bool *removed, ++ bfd_vma dot) ++{ ++ lang_input_section_type *is = &((*this_ptr)->input_section); ++ asection *i = is->section; ++ asection *o = output_section_statement->bfd_section; ++ *removed = 0; ++ ++ if (link_info.non_contiguous_regions) ++ { ++ /* If the input section I has already been successfully assigned ++ to an output section other than O, don't bother with it and ++ let the caller remove it from the list. Keep processing in ++ case we have already handled O, because the repeated passes ++ have reinitialized its size. */ ++ if (i->already_assigned && i->already_assigned != o) ++ { ++ *removed = 1; ++ return dot; ++ } ++ } ++ ++ if (i->sec_info_type == SEC_INFO_TYPE_JUST_SYMS) ++ i->output_offset = i->vma - o->vma; ++ else if (((i->flags & SEC_EXCLUDE) != 0) ++ || output_section_statement->ignored) ++ i->output_offset = dot - o->vma; ++ else ++ { ++ bfd_size_type alignment_needed; ++ ++ /* Align this section first to the input sections requirement, ++ then to the output section's requirement. If this alignment ++ is greater than any seen before, then record it too. Perform ++ the alignment by inserting a magic 'padding' statement. */ ++ ++ if (output_section_statement->subsection_alignment != NULL) ++ i->alignment_power ++ = exp_get_power (output_section_statement->subsection_alignment, ++ "subsection alignment"); ++ ++ if (o->alignment_power < i->alignment_power) ++ o->alignment_power = i->alignment_power; ++ ++ alignment_needed = align_power (dot, i->alignment_power) - dot; ++ ++ if (alignment_needed != 0) ++ { ++ insert_pad (this_ptr, fill, TO_SIZE (alignment_needed), o, dot); ++ dot += alignment_needed; ++ } ++ ++ if (link_info.non_contiguous_regions) ++ { ++ /* If I would overflow O, let the caller remove I from the ++ list. */ ++ if (output_section_statement->region) ++ { ++ bfd_vma end = output_section_statement->region->origin ++ + output_section_statement->region->length; ++ ++ if (dot + TO_ADDR (i->size) > end) ++ { ++ if (i->flags & SEC_LINKER_CREATED) ++ einfo (_("%F%P: Output section `%pA' not large enough for " ++ "the linker-created stubs section `%pA'.\n"), ++ i->output_section, i); ++ ++ if (i->rawsize && i->rawsize != i->size) ++ einfo (_("%F%P: Relaxation not supported with " ++ "--enable-non-contiguous-regions (section `%pA' " ++ "would overflow `%pA' after it changed size).\n"), ++ i, i->output_section); ++ ++ *removed = 1; ++ dot = end; ++ i->output_section = NULL; ++ return dot; ++ } ++ } ++ } ++ ++ /* Remember where in the output section this input section goes. */ ++ i->output_offset = dot - o->vma; ++ ++ /* Mark how big the output section must be to contain this now. */ ++ dot += TO_ADDR (i->size); ++ if (!(o->flags & SEC_FIXED_SIZE)) ++ o->size = TO_SIZE (dot - o->vma); ++ ++ if (link_info.non_contiguous_regions) ++ { ++ /* Record that I was successfully assigned to O, and update ++ its actual output section too. */ ++ i->already_assigned = o; ++ i->output_section = o; ++ } ++ } ++ ++ return dot; ++} ++ ++struct check_sec ++{ ++ asection *sec; ++ bool warned; ++}; ++ ++static int ++sort_sections_by_lma (const void *arg1, const void *arg2) ++{ ++ const asection *sec1 = ((const struct check_sec *) arg1)->sec; ++ const asection *sec2 = ((const struct check_sec *) arg2)->sec; ++ ++ if (sec1->lma < sec2->lma) ++ return -1; ++ else if (sec1->lma > sec2->lma) ++ return 1; ++ else if (sec1->id < sec2->id) ++ return -1; ++ else if (sec1->id > sec2->id) ++ return 1; ++ ++ return 0; ++} ++ ++static int ++sort_sections_by_vma (const void *arg1, const void *arg2) ++{ ++ const asection *sec1 = ((const struct check_sec *) arg1)->sec; ++ const asection *sec2 = ((const struct check_sec *) arg2)->sec; ++ ++ if (sec1->vma < sec2->vma) ++ return -1; ++ else if (sec1->vma > sec2->vma) ++ return 1; ++ else if (sec1->id < sec2->id) ++ return -1; ++ else if (sec1->id > sec2->id) ++ return 1; ++ ++ return 0; ++} ++ ++#define IS_TBSS(s) \ ++ ((s->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == SEC_THREAD_LOCAL) ++ ++#define IGNORE_SECTION(s) \ ++ ((s->flags & SEC_ALLOC) == 0 || IS_TBSS (s)) ++ ++/* Check to see if any allocated sections overlap with other allocated ++ sections. This can happen if a linker script specifies the output ++ section addresses of the two sections. Also check whether any memory ++ region has overflowed. */ ++ ++static void ++lang_check_section_addresses (void) ++{ ++ asection *s, *p; ++ struct check_sec *sections; ++ size_t i, count; ++ bfd_vma addr_mask; ++ bfd_vma s_start; ++ bfd_vma s_end; ++ bfd_vma p_start = 0; ++ bfd_vma p_end = 0; ++ lang_memory_region_type *m; ++ bool overlays; ++ ++ /* Detect address space overflow on allocated sections. */ ++ addr_mask = ((bfd_vma) 1 << ++ (bfd_arch_bits_per_address (link_info.output_bfd) - 1)) - 1; ++ addr_mask = (addr_mask << 1) + 1; ++ for (s = link_info.output_bfd->sections; s != NULL; s = s->next) ++ if ((s->flags & SEC_ALLOC) != 0) ++ { ++ s_end = (s->vma + s->size) & addr_mask; ++ if (s_end != 0 && s_end < (s->vma & addr_mask)) ++ einfo (_("%X%P: section %s VMA wraps around address space\n"), ++ s->name); ++ else ++ { ++ s_end = (s->lma + s->size) & addr_mask; ++ if (s_end != 0 && s_end < (s->lma & addr_mask)) ++ einfo (_("%X%P: section %s LMA wraps around address space\n"), ++ s->name); ++ } ++ } ++ ++ if (bfd_count_sections (link_info.output_bfd) <= 1) ++ return; ++ ++ count = bfd_count_sections (link_info.output_bfd); ++ sections = XNEWVEC (struct check_sec, count); ++ ++ /* Scan all sections in the output list. */ ++ count = 0; ++ for (s = link_info.output_bfd->sections; s != NULL; s = s->next) ++ { ++ if (IGNORE_SECTION (s) ++ || s->size == 0) ++ continue; ++ ++ sections[count].sec = s; ++ sections[count].warned = false; ++ count++; ++ } ++ ++ if (count <= 1) ++ { ++ free (sections); ++ return; ++ } ++ ++ qsort (sections, count, sizeof (*sections), sort_sections_by_lma); ++ ++ /* First check section LMAs. There should be no overlap of LMAs on ++ loadable sections, even with overlays. */ ++ for (p = NULL, i = 0; i < count; i++) ++ { ++ s = sections[i].sec; ++ init_opb (s); ++ if ((s->flags & SEC_LOAD) != 0) ++ { ++ s_start = s->lma; ++ s_end = s_start + TO_ADDR (s->size) - 1; ++ ++ /* Look for an overlap. We have sorted sections by lma, so ++ we know that s_start >= p_start. Besides the obvious ++ case of overlap when the current section starts before ++ the previous one ends, we also must have overlap if the ++ previous section wraps around the address space. */ ++ if (p != NULL ++ && (s_start <= p_end ++ || p_end < p_start)) ++ { ++ einfo (_("%X%P: section %s LMA [%V,%V]" ++ " overlaps section %s LMA [%V,%V]\n"), ++ s->name, s_start, s_end, p->name, p_start, p_end); ++ sections[i].warned = true; ++ } ++ p = s; ++ p_start = s_start; ++ p_end = s_end; ++ } ++ } ++ ++ /* If any non-zero size allocated section (excluding tbss) starts at ++ exactly the same VMA as another such section, then we have ++ overlays. Overlays generated by the OVERLAY keyword will have ++ this property. It is possible to intentionally generate overlays ++ that fail this test, but it would be unusual. */ ++ qsort (sections, count, sizeof (*sections), sort_sections_by_vma); ++ overlays = false; ++ p_start = sections[0].sec->vma; ++ for (i = 1; i < count; i++) ++ { ++ s_start = sections[i].sec->vma; ++ if (p_start == s_start) ++ { ++ overlays = true; ++ break; ++ } ++ p_start = s_start; ++ } ++ ++ /* Now check section VMAs if no overlays were detected. */ ++ if (!overlays) ++ { ++ for (p = NULL, i = 0; i < count; i++) ++ { ++ s = sections[i].sec; ++ init_opb (s); ++ s_start = s->vma; ++ s_end = s_start + TO_ADDR (s->size) - 1; ++ ++ if (p != NULL ++ && !sections[i].warned ++ && (s_start <= p_end ++ || p_end < p_start)) ++ einfo (_("%X%P: section %s VMA [%V,%V]" ++ " overlaps section %s VMA [%V,%V]\n"), ++ s->name, s_start, s_end, p->name, p_start, p_end); ++ p = s; ++ p_start = s_start; ++ p_end = s_end; ++ } ++ } ++ ++ free (sections); ++ ++ /* If any memory region has overflowed, report by how much. ++ We do not issue this diagnostic for regions that had sections ++ explicitly placed outside their bounds; os_region_check's ++ diagnostics are adequate for that case. ++ ++ FIXME: It is conceivable that m->current - (m->origin + m->length) ++ might overflow a 32-bit integer. There is, alas, no way to print ++ a bfd_vma quantity in decimal. */ ++ for (m = lang_memory_region_list; m; m = m->next) ++ if (m->had_full_message) ++ { ++ unsigned long over = m->current - (m->origin + m->length); ++ einfo (ngettext ("%X%P: region `%s' overflowed by %lu byte\n", ++ "%X%P: region `%s' overflowed by %lu bytes\n", ++ over), ++ m->name_list.name, over); ++ } ++} ++ ++/* Make sure the new address is within the region. We explicitly permit the ++ current address to be at the exact end of the region when the address is ++ non-zero, in case the region is at the end of addressable memory and the ++ calculation wraps around. */ ++ ++static void ++os_region_check (lang_output_section_statement_type *os, ++ lang_memory_region_type *region, ++ etree_type *tree, ++ bfd_vma rbase) ++{ ++ if ((region->current < region->origin ++ || (region->current - region->origin > region->length)) ++ && ((region->current != region->origin + region->length) ++ || rbase == 0)) ++ { ++ if (tree != NULL) ++ { ++ einfo (_("%X%P: address 0x%v of %pB section `%s'" ++ " is not within region `%s'\n"), ++ region->current, ++ os->bfd_section->owner, ++ os->bfd_section->name, ++ region->name_list.name); ++ } ++ else if (!region->had_full_message) ++ { ++ region->had_full_message = true; ++ ++ einfo (_("%X%P: %pB section `%s' will not fit in region `%s'\n"), ++ os->bfd_section->owner, ++ os->bfd_section->name, ++ region->name_list.name); ++ } ++ } ++} ++ ++static void ++ldlang_check_relro_region (lang_statement_union_type *s) ++{ ++ seg_align_type *seg = &expld.dataseg; ++ ++ if (seg->relro == exp_seg_relro_start) ++ { ++ if (!seg->relro_start_stat) ++ seg->relro_start_stat = s; ++ else ++ { ++ ASSERT (seg->relro_start_stat == s); ++ } ++ } ++ else if (seg->relro == exp_seg_relro_end) ++ { ++ if (!seg->relro_end_stat) ++ seg->relro_end_stat = s; ++ else ++ { ++ ASSERT (seg->relro_end_stat == s); ++ } ++ } ++} ++ ++/* Set the sizes for all the output sections. */ ++ ++static bfd_vma ++lang_size_sections_1 ++ (lang_statement_union_type **prev, ++ lang_output_section_statement_type *output_section_statement, ++ fill_type *fill, ++ bfd_vma dot, ++ bool *relax, ++ bool check_regions) ++{ ++ lang_statement_union_type *s; ++ lang_statement_union_type *prev_s = NULL; ++ bool removed_prev_s = false; ++ ++ /* Size up the sections from their constituent parts. */ ++ for (s = *prev; s != NULL; prev_s = s, s = s->header.next) ++ { ++ bool removed = false; ++ ++ switch (s->header.type) ++ { ++ case lang_output_section_statement_enum: ++ { ++ bfd_vma newdot, after, dotdelta; ++ lang_output_section_statement_type *os; ++ lang_memory_region_type *r; ++ int section_alignment = 0; ++ ++ os = &s->output_section_statement; ++ init_opb (os->bfd_section); ++ if (os->constraint == -1) ++ break; ++ ++ /* FIXME: We shouldn't need to zero section vmas for ld -r ++ here, in lang_insert_orphan, or in the default linker scripts. ++ This is covering for coff backend linker bugs. See PR6945. */ ++ if (os->addr_tree == NULL ++ && bfd_link_relocatable (&link_info) ++ && (bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_coff_flavour)) ++ os->addr_tree = exp_intop (0); ++ if (os->addr_tree != NULL) ++ { ++ exp_fold_tree (os->addr_tree, bfd_abs_section_ptr, &dot); ++ ++ if (expld.result.valid_p) ++ { ++ dot = expld.result.value; ++ if (expld.result.section != NULL) ++ dot += expld.result.section->vma; ++ } ++ else if (expld.phase != lang_mark_phase_enum) ++ einfo (_("%F%P:%pS: non constant or forward reference" ++ " address expression for section %s\n"), ++ os->addr_tree, os->name); ++ } ++ ++ if (os->bfd_section == NULL) ++ /* This section was removed or never actually created. */ ++ break; ++ ++ /* If this is a COFF shared library section, use the size and ++ address from the input section. FIXME: This is COFF ++ specific; it would be cleaner if there were some other way ++ to do this, but nothing simple comes to mind. */ ++ if (((bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_ecoff_flavour) ++ || (bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_coff_flavour)) ++ && (os->bfd_section->flags & SEC_COFF_SHARED_LIBRARY) != 0) ++ { ++ asection *input; ++ ++ if (os->children.head == NULL ++ || os->children.head->header.next != NULL ++ || (os->children.head->header.type ++ != lang_input_section_enum)) ++ einfo (_("%X%P: internal error on COFF shared library" ++ " section %s\n"), os->name); ++ ++ input = os->children.head->input_section.section; ++ bfd_set_section_vma (os->bfd_section, ++ bfd_section_vma (input)); ++ if (!(os->bfd_section->flags & SEC_FIXED_SIZE)) ++ os->bfd_section->size = input->size; ++ break; ++ } ++ ++ newdot = dot; ++ dotdelta = 0; ++ if (bfd_is_abs_section (os->bfd_section)) ++ { ++ /* No matter what happens, an abs section starts at zero. */ ++ ASSERT (os->bfd_section->vma == 0); ++ } ++ else ++ { ++ if (os->addr_tree == NULL) ++ { ++ /* No address specified for this section, get one ++ from the region specification. */ ++ if (os->region == NULL ++ || ((os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD)) ++ && os->region->name_list.name[0] == '*' ++ && strcmp (os->region->name_list.name, ++ DEFAULT_MEMORY_REGION) == 0)) ++ { ++ os->region = lang_memory_default (os->bfd_section); ++ } ++ ++ /* If a loadable section is using the default memory ++ region, and some non default memory regions were ++ defined, issue an error message. */ ++ if (!os->ignored ++ && !IGNORE_SECTION (os->bfd_section) ++ && !bfd_link_relocatable (&link_info) ++ && check_regions ++ && strcmp (os->region->name_list.name, ++ DEFAULT_MEMORY_REGION) == 0 ++ && lang_memory_region_list != NULL ++ && (strcmp (lang_memory_region_list->name_list.name, ++ DEFAULT_MEMORY_REGION) != 0 ++ || lang_memory_region_list->next != NULL) ++ && lang_sizing_iteration == 1) ++ { ++ /* By default this is an error rather than just a ++ warning because if we allocate the section to the ++ default memory region we can end up creating an ++ excessively large binary, or even seg faulting when ++ attempting to perform a negative seek. See ++ sources.redhat.com/ml/binutils/2003-04/msg00423.html ++ for an example of this. This behaviour can be ++ overridden by the using the --no-check-sections ++ switch. */ ++ if (command_line.check_section_addresses) ++ einfo (_("%F%P: error: no memory region specified" ++ " for loadable section `%s'\n"), ++ bfd_section_name (os->bfd_section)); ++ else ++ einfo (_("%P: warning: no memory region specified" ++ " for loadable section `%s'\n"), ++ bfd_section_name (os->bfd_section)); ++ } ++ ++ newdot = os->region->current; ++ section_alignment = os->bfd_section->alignment_power; ++ } ++ else ++ section_alignment = exp_get_power (os->section_alignment, ++ "section alignment"); ++ ++ /* Align to what the section needs. */ ++ if (section_alignment > 0) ++ { ++ bfd_vma savedot = newdot; ++ bfd_vma diff = 0; ++ ++ newdot = align_power (newdot, section_alignment); ++ dotdelta = newdot - savedot; ++ ++ if (lang_sizing_iteration == 1) ++ diff = dotdelta; ++ else if (lang_sizing_iteration > 1) ++ { ++ /* Only report adjustments that would change ++ alignment from what we have already reported. */ ++ diff = newdot - os->bfd_section->vma; ++ if (!(diff & (((bfd_vma) 1 << section_alignment) - 1))) ++ diff = 0; ++ } ++ if (diff != 0 ++ && (config.warn_section_align ++ || os->addr_tree != NULL)) ++ einfo (_("%P: warning: " ++ "start of section %s changed by %ld\n"), ++ os->name, (long) diff); ++ } ++ ++ bfd_set_section_vma (os->bfd_section, newdot); ++ ++ os->bfd_section->output_offset = 0; ++ } ++ ++ lang_size_sections_1 (&os->children.head, os, ++ os->fill, newdot, relax, check_regions); ++ ++ os->processed_vma = true; ++ ++ if (bfd_is_abs_section (os->bfd_section) || os->ignored) ++ /* Except for some special linker created sections, ++ no output section should change from zero size ++ after strip_excluded_output_sections. A non-zero ++ size on an ignored section indicates that some ++ input section was not sized early enough. */ ++ ASSERT (os->bfd_section->size == 0); ++ else ++ { ++ dot = os->bfd_section->vma; ++ ++ /* Put the section within the requested block size, or ++ align at the block boundary. */ ++ after = ((dot ++ + TO_ADDR (os->bfd_section->size) ++ + os->block_value - 1) ++ & - (bfd_vma) os->block_value); ++ ++ if (!(os->bfd_section->flags & SEC_FIXED_SIZE)) ++ os->bfd_section->size = TO_SIZE (after ++ - os->bfd_section->vma); ++ } ++ ++ /* Set section lma. */ ++ r = os->region; ++ if (r == NULL) ++ r = lang_memory_region_lookup (DEFAULT_MEMORY_REGION, false); ++ ++ if (os->load_base) ++ { ++ bfd_vma lma = exp_get_abs_int (os->load_base, 0, "load base"); ++ os->bfd_section->lma = lma; ++ } ++ else if (os->lma_region != NULL) ++ { ++ bfd_vma lma = os->lma_region->current; ++ ++ if (os->align_lma_with_input) ++ lma += dotdelta; ++ else ++ { ++ /* When LMA_REGION is the same as REGION, align the LMA ++ as we did for the VMA, possibly including alignment ++ from the bfd section. If a different region, then ++ only align according to the value in the output ++ statement. */ ++ if (os->lma_region != os->region) ++ section_alignment = exp_get_power (os->section_alignment, ++ "section alignment"); ++ if (section_alignment > 0) ++ lma = align_power (lma, section_alignment); ++ } ++ os->bfd_section->lma = lma; ++ } ++ else if (r->last_os != NULL ++ && (os->bfd_section->flags & SEC_ALLOC) != 0) ++ { ++ bfd_vma lma; ++ asection *last; ++ ++ last = r->last_os->output_section_statement.bfd_section; ++ ++ /* A backwards move of dot should be accompanied by ++ an explicit assignment to the section LMA (ie. ++ os->load_base set) because backwards moves can ++ create overlapping LMAs. */ ++ if (dot < last->vma ++ && os->bfd_section->size != 0 ++ && dot + TO_ADDR (os->bfd_section->size) <= last->vma) ++ { ++ /* If dot moved backwards then leave lma equal to ++ vma. This is the old default lma, which might ++ just happen to work when the backwards move is ++ sufficiently large. Nag if this changes anything, ++ so people can fix their linker scripts. */ ++ ++ if (last->vma != last->lma) ++ einfo (_("%P: warning: dot moved backwards " ++ "before `%s'\n"), os->name); ++ } ++ else ++ { ++ /* If this is an overlay, set the current lma to that ++ at the end of the previous section. */ ++ if (os->sectype == overlay_section) ++ lma = last->lma + TO_ADDR (last->size); ++ ++ /* Otherwise, keep the same lma to vma relationship ++ as the previous section. */ ++ else ++ lma = os->bfd_section->vma + last->lma - last->vma; ++ ++ if (section_alignment > 0) ++ lma = align_power (lma, section_alignment); ++ os->bfd_section->lma = lma; ++ } ++ } ++ os->processed_lma = true; ++ ++ /* Keep track of normal sections using the default ++ lma region. We use this to set the lma for ++ following sections. Overlays or other linker ++ script assignment to lma might mean that the ++ default lma == vma is incorrect. ++ To avoid warnings about dot moving backwards when using ++ -Ttext, don't start tracking sections until we find one ++ of non-zero size or with lma set differently to vma. ++ Do this tracking before we short-cut the loop so that we ++ track changes for the case where the section size is zero, ++ but the lma is set differently to the vma. This is ++ important, if an orphan section is placed after an ++ otherwise empty output section that has an explicit lma ++ set, we want that lma reflected in the orphans lma. */ ++ if (((!IGNORE_SECTION (os->bfd_section) ++ && (os->bfd_section->size != 0 ++ || (r->last_os == NULL ++ && os->bfd_section->vma != os->bfd_section->lma) ++ || (r->last_os != NULL ++ && dot >= (r->last_os->output_section_statement ++ .bfd_section->vma)))) ++ || os->sectype == first_overlay_section) ++ && os->lma_region == NULL ++ && !bfd_link_relocatable (&link_info)) ++ r->last_os = s; ++ ++ if (bfd_is_abs_section (os->bfd_section) || os->ignored) ++ break; ++ ++ /* .tbss sections effectively have zero size. */ ++ if (!IS_TBSS (os->bfd_section) ++ || bfd_link_relocatable (&link_info)) ++ dotdelta = TO_ADDR (os->bfd_section->size); ++ else ++ dotdelta = 0; ++ dot += dotdelta; ++ ++ if (os->update_dot_tree != 0) ++ exp_fold_tree (os->update_dot_tree, bfd_abs_section_ptr, &dot); ++ ++ /* Update dot in the region ? ++ We only do this if the section is going to be allocated, ++ since unallocated sections do not contribute to the region's ++ overall size in memory. */ ++ if (os->region != NULL ++ && (os->bfd_section->flags & (SEC_ALLOC | SEC_LOAD))) ++ { ++ os->region->current = dot; ++ ++ if (check_regions) ++ /* Make sure the new address is within the region. */ ++ os_region_check (os, os->region, os->addr_tree, ++ os->bfd_section->vma); ++ ++ if (os->lma_region != NULL && os->lma_region != os->region ++ && ((os->bfd_section->flags & SEC_LOAD) ++ || os->align_lma_with_input)) ++ { ++ os->lma_region->current = os->bfd_section->lma + dotdelta; ++ ++ if (check_regions) ++ os_region_check (os, os->lma_region, NULL, ++ os->bfd_section->lma); ++ } ++ } ++ } ++ break; ++ ++ case lang_constructors_statement_enum: ++ dot = lang_size_sections_1 (&constructor_list.head, ++ output_section_statement, ++ fill, dot, relax, check_regions); ++ break; ++ ++ case lang_data_statement_enum: ++ { ++ unsigned int size = 0; ++ ++ s->data_statement.output_offset = ++ dot - output_section_statement->bfd_section->vma; ++ s->data_statement.output_section = ++ output_section_statement->bfd_section; ++ ++ /* We might refer to provided symbols in the expression, and ++ need to mark them as needed. */ ++ exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); ++ ++ switch (s->data_statement.type) ++ { ++ default: ++ abort (); ++ case QUAD: ++ case SQUAD: ++ size = QUAD_SIZE; ++ break; ++ case LONG: ++ size = LONG_SIZE; ++ break; ++ case SHORT: ++ size = SHORT_SIZE; ++ break; ++ case BYTE: ++ size = BYTE_SIZE; ++ break; ++ } ++ if (size < TO_SIZE ((unsigned) 1)) ++ size = TO_SIZE ((unsigned) 1); ++ dot += TO_ADDR (size); ++ if (!(output_section_statement->bfd_section->flags ++ & SEC_FIXED_SIZE)) ++ output_section_statement->bfd_section->size ++ = TO_SIZE (dot - output_section_statement->bfd_section->vma); ++ ++ } ++ break; ++ ++ case lang_reloc_statement_enum: ++ { ++ int size; ++ ++ s->reloc_statement.output_offset = ++ dot - output_section_statement->bfd_section->vma; ++ s->reloc_statement.output_section = ++ output_section_statement->bfd_section; ++ size = bfd_get_reloc_size (s->reloc_statement.howto); ++ dot += TO_ADDR (size); ++ if (!(output_section_statement->bfd_section->flags ++ & SEC_FIXED_SIZE)) ++ output_section_statement->bfd_section->size ++ = TO_SIZE (dot - output_section_statement->bfd_section->vma); ++ } ++ break; ++ ++ case lang_wild_statement_enum: ++ dot = lang_size_sections_1 (&s->wild_statement.children.head, ++ output_section_statement, ++ fill, dot, relax, check_regions); ++ break; ++ ++ case lang_object_symbols_statement_enum: ++ link_info.create_object_symbols_section ++ = output_section_statement->bfd_section; ++ output_section_statement->bfd_section->flags |= SEC_KEEP; ++ break; ++ ++ case lang_output_statement_enum: ++ case lang_target_statement_enum: ++ break; ++ ++ case lang_input_section_enum: ++ { ++ asection *i; ++ ++ i = s->input_section.section; ++ if (relax) ++ { ++ bool again; ++ ++ if (!bfd_relax_section (i->owner, i, &link_info, &again)) ++ einfo (_("%F%P: can't relax section: %E\n")); ++ if (again) ++ *relax = true; ++ } ++ dot = size_input_section (prev, output_section_statement, ++ fill, &removed, dot); ++ } ++ break; ++ ++ case lang_input_statement_enum: ++ break; ++ ++ case lang_fill_statement_enum: ++ s->fill_statement.output_section = ++ output_section_statement->bfd_section; ++ ++ fill = s->fill_statement.fill; ++ break; ++ ++ case lang_assignment_statement_enum: ++ { ++ bfd_vma newdot = dot; ++ etree_type *tree = s->assignment_statement.exp; ++ ++ expld.dataseg.relro = exp_seg_relro_none; ++ ++ exp_fold_tree (tree, ++ output_section_statement->bfd_section, ++ &newdot); ++ ++ ldlang_check_relro_region (s); ++ ++ expld.dataseg.relro = exp_seg_relro_none; ++ ++ /* This symbol may be relative to this section. */ ++ if ((tree->type.node_class == etree_provided ++ || tree->type.node_class == etree_assign) ++ && (tree->assign.dst [0] != '.' ++ || tree->assign.dst [1] != '\0')) ++ output_section_statement->update_dot = 1; ++ ++ if (!output_section_statement->ignored) ++ { ++ if (output_section_statement == abs_output_section) ++ { ++ /* If we don't have an output section, then just adjust ++ the default memory address. */ ++ lang_memory_region_lookup (DEFAULT_MEMORY_REGION, ++ false)->current = newdot; ++ } ++ else if (newdot != dot) ++ { ++ /* Insert a pad after this statement. We can't ++ put the pad before when relaxing, in case the ++ assignment references dot. */ ++ insert_pad (&s->header.next, fill, TO_SIZE (newdot - dot), ++ output_section_statement->bfd_section, dot); ++ ++ /* Don't neuter the pad below when relaxing. */ ++ s = s->header.next; ++ ++ /* If dot is advanced, this implies that the section ++ should have space allocated to it, unless the ++ user has explicitly stated that the section ++ should not be allocated. */ ++ if (output_section_statement->sectype != noalloc_section ++ && (output_section_statement->sectype != noload_section ++ || (bfd_get_flavour (link_info.output_bfd) ++ == bfd_target_elf_flavour))) ++ output_section_statement->bfd_section->flags |= SEC_ALLOC; ++ } ++ dot = newdot; ++ } ++ } ++ break; ++ ++ case lang_padding_statement_enum: ++ /* If this is the first time lang_size_sections is called, ++ we won't have any padding statements. If this is the ++ second or later passes when relaxing, we should allow ++ padding to shrink. If padding is needed on this pass, it ++ will be added back in. */ ++ s->padding_statement.size = 0; ++ ++ /* Make sure output_offset is valid. If relaxation shrinks ++ the section and this pad isn't needed, it's possible to ++ have output_offset larger than the final size of the ++ section. bfd_set_section_contents will complain even for ++ a pad size of zero. */ ++ s->padding_statement.output_offset ++ = dot - output_section_statement->bfd_section->vma; ++ break; ++ ++ case lang_group_statement_enum: ++ dot = lang_size_sections_1 (&s->group_statement.children.head, ++ output_section_statement, ++ fill, dot, relax, check_regions); ++ break; ++ ++ case lang_insert_statement_enum: ++ break; ++ ++ /* We can only get here when relaxing is turned on. */ ++ case lang_address_statement_enum: ++ break; ++ ++ default: ++ FAIL (); ++ break; ++ } ++ ++ /* If an input section doesn't fit in the current output ++ section, remove it from the list. Handle the case where we ++ have to remove an input_section statement here: there is a ++ special case to remove the first element of the list. */ ++ if (link_info.non_contiguous_regions && removed) ++ { ++ /* If we removed the first element during the previous ++ iteration, override the loop assignment of prev_s. */ ++ if (removed_prev_s) ++ prev_s = NULL; ++ ++ if (prev_s) ++ { ++ /* If there was a real previous input section, just skip ++ the current one. */ ++ prev_s->header.next=s->header.next; ++ s = prev_s; ++ removed_prev_s = false; ++ } ++ else ++ { ++ /* Remove the first input section of the list. */ ++ *prev = s->header.next; ++ removed_prev_s = true; ++ } ++ ++ /* Move to next element, unless we removed the head of the ++ list. */ ++ if (!removed_prev_s) ++ prev = &s->header.next; ++ } ++ else ++ { ++ prev = &s->header.next; ++ removed_prev_s = false; ++ } ++ } ++ return dot; ++} ++ ++/* Callback routine that is used in _bfd_elf_map_sections_to_segments. ++ The BFD library has set NEW_SEGMENT to TRUE iff it thinks that ++ CURRENT_SECTION and PREVIOUS_SECTION ought to be placed into different ++ segments. We are allowed an opportunity to override this decision. */ ++ ++bool ++ldlang_override_segment_assignment (struct bfd_link_info *info ATTRIBUTE_UNUSED, ++ bfd *abfd ATTRIBUTE_UNUSED, ++ asection *current_section, ++ asection *previous_section, ++ bool new_segment) ++{ ++ lang_output_section_statement_type *cur; ++ lang_output_section_statement_type *prev; ++ ++ /* The checks below are only necessary when the BFD library has decided ++ that the two sections ought to be placed into the same segment. */ ++ if (new_segment) ++ return true; ++ ++ /* Paranoia checks. */ ++ if (current_section == NULL || previous_section == NULL) ++ return new_segment; ++ ++ /* If this flag is set, the target never wants code and non-code ++ sections comingled in the same segment. */ ++ if (config.separate_code ++ && ((current_section->flags ^ previous_section->flags) & SEC_CODE)) ++ return true; ++ ++ /* Find the memory regions associated with the two sections. ++ We call lang_output_section_find() here rather than scanning the list ++ of output sections looking for a matching section pointer because if ++ we have a large number of sections then a hash lookup is faster. */ ++ cur = lang_output_section_find (current_section->name); ++ prev = lang_output_section_find (previous_section->name); ++ ++ /* More paranoia. */ ++ if (cur == NULL || prev == NULL) ++ return new_segment; ++ ++ /* If the regions are different then force the sections to live in ++ different segments. See the email thread starting at the following ++ URL for the reasons why this is necessary: ++ http://sourceware.org/ml/binutils/2007-02/msg00216.html */ ++ return cur->region != prev->region; ++} ++ ++void ++one_lang_size_sections_pass (bool *relax, bool check_regions) ++{ ++ lang_statement_iteration++; ++ if (expld.phase != lang_mark_phase_enum) ++ lang_sizing_iteration++; ++ lang_size_sections_1 (&statement_list.head, abs_output_section, ++ 0, 0, relax, check_regions); ++} ++ ++static bool ++lang_size_segment (void) ++{ ++ /* If XXX_SEGMENT_ALIGN XXX_SEGMENT_END pair was seen, check whether ++ a page could be saved in the data segment. */ ++ seg_align_type *seg = &expld.dataseg; ++ bfd_vma first, last; ++ ++ first = -seg->base & (seg->commonpagesize - 1); ++ last = seg->end & (seg->commonpagesize - 1); ++ if (first && last ++ && ((seg->base & ~(seg->commonpagesize - 1)) ++ != (seg->end & ~(seg->commonpagesize - 1))) ++ && first + last <= seg->commonpagesize) ++ { ++ seg->phase = exp_seg_adjust; ++ return true; ++ } ++ ++ seg->phase = exp_seg_done; ++ return false; ++} ++ ++static bfd_vma ++lang_size_relro_segment_1 (void) ++{ ++ seg_align_type *seg = &expld.dataseg; ++ bfd_vma relro_end, desired_end; ++ asection *sec; ++ ++ /* Compute the expected PT_GNU_RELRO/PT_LOAD segment end. */ ++ relro_end = (seg->relro_end + seg->relropagesize - 1) & -seg->relropagesize; ++ ++ /* Adjust by the offset arg of XXX_SEGMENT_RELRO_END. */ ++ desired_end = relro_end - seg->relro_offset; ++ ++ /* For sections in the relro segment.. */ ++ for (sec = link_info.output_bfd->section_last; sec; sec = sec->prev) ++ if ((sec->flags & SEC_ALLOC) != 0 ++ && sec->vma >= seg->base ++ && sec->vma < seg->relro_end - seg->relro_offset) ++ { ++ /* Where do we want to put this section so that it ends as ++ desired? */ ++ bfd_vma start, end, bump; ++ ++ end = start = sec->vma; ++ if (!IS_TBSS (sec)) ++ end += TO_ADDR (sec->size); ++ bump = desired_end - end; ++ /* We'd like to increase START by BUMP, but we must heed ++ alignment so the increase might be less than optimum. */ ++ start += bump; ++ start &= ~(((bfd_vma) 1 << sec->alignment_power) - 1); ++ /* This is now the desired end for the previous section. */ ++ desired_end = start; ++ } ++ ++ seg->phase = exp_seg_relro_adjust; ++ ASSERT (desired_end >= seg->base); ++ seg->base = desired_end; ++ return relro_end; ++} ++ ++static bool ++lang_size_relro_segment (bool *relax, bool check_regions) ++{ ++ bool do_reset = false; ++ ++ if (link_info.relro && expld.dataseg.relro_end) ++ { ++ bfd_vma data_initial_base = expld.dataseg.base; ++ bfd_vma data_relro_end = lang_size_relro_segment_1 (); ++ ++ lang_reset_memory_regions (); ++ one_lang_size_sections_pass (relax, check_regions); ++ ++ /* Assignments to dot, or to output section address in a user ++ script have increased padding over the original. Revert. */ ++ if (expld.dataseg.relro_end > data_relro_end) ++ { ++ expld.dataseg.base = data_initial_base; ++ do_reset = true; ++ } ++ } ++ else if (lang_size_segment ()) ++ do_reset = true; ++ ++ return do_reset; ++} ++ ++void ++lang_size_sections (bool *relax, bool check_regions) ++{ ++ expld.phase = lang_allocating_phase_enum; ++ expld.dataseg.phase = exp_seg_none; ++ ++ one_lang_size_sections_pass (relax, check_regions); ++ ++ if (expld.dataseg.phase != exp_seg_end_seen) ++ expld.dataseg.phase = exp_seg_done; ++ ++ if (expld.dataseg.phase == exp_seg_end_seen) ++ { ++ bool do_reset ++ = lang_size_relro_segment (relax, check_regions); ++ ++ if (do_reset) ++ { ++ lang_reset_memory_regions (); ++ one_lang_size_sections_pass (relax, check_regions); ++ } ++ ++ if (link_info.relro && expld.dataseg.relro_end) ++ { ++ link_info.relro_start = expld.dataseg.base; ++ link_info.relro_end = expld.dataseg.relro_end; ++ } ++ } ++} ++ ++static lang_output_section_statement_type *current_section; ++static lang_assignment_statement_type *current_assign; ++static bool prefer_next_section; ++ ++/* Worker function for lang_do_assignments. Recursiveness goes here. */ ++ ++static bfd_vma ++lang_do_assignments_1 (lang_statement_union_type *s, ++ lang_output_section_statement_type *current_os, ++ fill_type *fill, ++ bfd_vma dot, ++ bool *found_end) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ switch (s->header.type) ++ { ++ case lang_constructors_statement_enum: ++ dot = lang_do_assignments_1 (constructor_list.head, ++ current_os, fill, dot, found_end); ++ break; ++ ++ case lang_output_section_statement_enum: ++ { ++ lang_output_section_statement_type *os; ++ bfd_vma newdot; ++ ++ os = &(s->output_section_statement); ++ os->after_end = *found_end; ++ init_opb (os->bfd_section); ++ newdot = dot; ++ if (os->bfd_section != NULL) ++ { ++ if (!os->ignored && (os->bfd_section->flags & SEC_ALLOC) != 0) ++ { ++ current_section = os; ++ prefer_next_section = false; ++ } ++ newdot = os->bfd_section->vma; ++ } ++ newdot = lang_do_assignments_1 (os->children.head, ++ os, os->fill, newdot, found_end); ++ if (!os->ignored) ++ { ++ if (os->bfd_section != NULL) ++ { ++ newdot = os->bfd_section->vma; ++ ++ /* .tbss sections effectively have zero size. */ ++ if (!IS_TBSS (os->bfd_section) ++ || bfd_link_relocatable (&link_info)) ++ newdot += TO_ADDR (os->bfd_section->size); ++ ++ if (os->update_dot_tree != NULL) ++ exp_fold_tree (os->update_dot_tree, ++ bfd_abs_section_ptr, &newdot); ++ } ++ dot = newdot; ++ } ++ } ++ break; ++ ++ case lang_wild_statement_enum: ++ ++ dot = lang_do_assignments_1 (s->wild_statement.children.head, ++ current_os, fill, dot, found_end); ++ break; ++ ++ case lang_object_symbols_statement_enum: ++ case lang_output_statement_enum: ++ case lang_target_statement_enum: ++ break; ++ ++ case lang_data_statement_enum: ++ exp_fold_tree (s->data_statement.exp, bfd_abs_section_ptr, &dot); ++ if (expld.result.valid_p) ++ { ++ s->data_statement.value = expld.result.value; ++ if (expld.result.section != NULL) ++ s->data_statement.value += expld.result.section->vma; ++ } ++ else if (expld.phase == lang_final_phase_enum) ++ einfo (_("%F%P: invalid data statement\n")); ++ { ++ unsigned int size; ++ switch (s->data_statement.type) ++ { ++ default: ++ abort (); ++ case QUAD: ++ case SQUAD: ++ size = QUAD_SIZE; ++ break; ++ case LONG: ++ size = LONG_SIZE; ++ break; ++ case SHORT: ++ size = SHORT_SIZE; ++ break; ++ case BYTE: ++ size = BYTE_SIZE; ++ break; ++ } ++ if (size < TO_SIZE ((unsigned) 1)) ++ size = TO_SIZE ((unsigned) 1); ++ dot += TO_ADDR (size); ++ } ++ break; ++ ++ case lang_reloc_statement_enum: ++ exp_fold_tree (s->reloc_statement.addend_exp, ++ bfd_abs_section_ptr, &dot); ++ if (expld.result.valid_p) ++ s->reloc_statement.addend_value = expld.result.value; ++ else if (expld.phase == lang_final_phase_enum) ++ einfo (_("%F%P: invalid reloc statement\n")); ++ dot += TO_ADDR (bfd_get_reloc_size (s->reloc_statement.howto)); ++ break; ++ ++ case lang_input_section_enum: ++ { ++ asection *in = s->input_section.section; ++ ++ if ((in->flags & SEC_EXCLUDE) == 0) ++ dot += TO_ADDR (in->size); ++ } ++ break; ++ ++ case lang_input_statement_enum: ++ break; ++ ++ case lang_fill_statement_enum: ++ fill = s->fill_statement.fill; ++ break; ++ ++ case lang_assignment_statement_enum: ++ current_assign = &s->assignment_statement; ++ if (current_assign->exp->type.node_class != etree_assert) ++ { ++ const char *p = current_assign->exp->assign.dst; ++ ++ if (current_os == abs_output_section && p[0] == '.' && p[1] == 0) ++ prefer_next_section = true; ++ ++ while (*p == '_') ++ ++p; ++ if (strcmp (p, "end") == 0) ++ *found_end = true; ++ } ++ exp_fold_tree (s->assignment_statement.exp, ++ (current_os->bfd_section != NULL ++ ? current_os->bfd_section : bfd_und_section_ptr), ++ &dot); ++ break; ++ ++ case lang_padding_statement_enum: ++ dot += TO_ADDR (s->padding_statement.size); ++ break; ++ ++ case lang_group_statement_enum: ++ dot = lang_do_assignments_1 (s->group_statement.children.head, ++ current_os, fill, dot, found_end); ++ break; ++ ++ case lang_insert_statement_enum: ++ break; ++ ++ case lang_address_statement_enum: ++ break; ++ ++ default: ++ FAIL (); ++ break; ++ } ++ } ++ return dot; ++} ++ ++void ++lang_do_assignments (lang_phase_type phase) ++{ ++ bool found_end = false; ++ ++ current_section = NULL; ++ prefer_next_section = false; ++ expld.phase = phase; ++ lang_statement_iteration++; ++ lang_do_assignments_1 (statement_list.head, ++ abs_output_section, NULL, 0, &found_end); ++} ++ ++/* For an assignment statement outside of an output section statement, ++ choose the best of neighbouring output sections to use for values ++ of "dot". */ ++ ++asection * ++section_for_dot (void) ++{ ++ asection *s; ++ ++ /* Assignments belong to the previous output section, unless there ++ has been an assignment to "dot", in which case following ++ assignments belong to the next output section. (The assumption ++ is that an assignment to "dot" is setting up the address for the ++ next output section.) Except that past the assignment to "_end" ++ we always associate with the previous section. This exception is ++ for targets like SH that define an alloc .stack or other ++ weirdness after non-alloc sections. */ ++ if (current_section == NULL || prefer_next_section) ++ { ++ lang_statement_union_type *stmt; ++ lang_output_section_statement_type *os; ++ ++ for (stmt = (lang_statement_union_type *) current_assign; ++ stmt != NULL; ++ stmt = stmt->header.next) ++ if (stmt->header.type == lang_output_section_statement_enum) ++ break; ++ ++ os = stmt ? &stmt->output_section_statement : NULL; ++ while (os != NULL ++ && !os->after_end ++ && (os->bfd_section == NULL ++ || (os->bfd_section->flags & SEC_EXCLUDE) != 0 ++ || bfd_section_removed_from_list (link_info.output_bfd, ++ os->bfd_section))) ++ os = os->next; ++ ++ if (current_section == NULL || os == NULL || !os->after_end) ++ { ++ if (os != NULL) ++ s = os->bfd_section; ++ else ++ s = link_info.output_bfd->section_last; ++ while (s != NULL ++ && ((s->flags & SEC_ALLOC) == 0 ++ || (s->flags & SEC_THREAD_LOCAL) != 0)) ++ s = s->prev; ++ if (s != NULL) ++ return s; ++ ++ return bfd_abs_section_ptr; ++ } ++ } ++ ++ s = current_section->bfd_section; ++ ++ /* The section may have been stripped. */ ++ while (s != NULL ++ && ((s->flags & SEC_EXCLUDE) != 0 ++ || (s->flags & SEC_ALLOC) == 0 ++ || (s->flags & SEC_THREAD_LOCAL) != 0 ++ || bfd_section_removed_from_list (link_info.output_bfd, s))) ++ s = s->prev; ++ if (s == NULL) ++ s = link_info.output_bfd->sections; ++ while (s != NULL ++ && ((s->flags & SEC_ALLOC) == 0 ++ || (s->flags & SEC_THREAD_LOCAL) != 0)) ++ s = s->next; ++ if (s != NULL) ++ return s; ++ ++ return bfd_abs_section_ptr; ++} ++ ++/* Array of __start/__stop/.startof./.sizeof/ symbols. */ ++ ++static struct bfd_link_hash_entry **start_stop_syms; ++static size_t start_stop_count = 0; ++static size_t start_stop_alloc = 0; ++ ++/* Give start/stop SYMBOL for SEC a preliminary definition, and add it ++ to start_stop_syms. */ ++ ++static void ++lang_define_start_stop (const char *symbol, asection *sec) ++{ ++ struct bfd_link_hash_entry *h; ++ ++ h = bfd_define_start_stop (link_info.output_bfd, &link_info, symbol, sec); ++ if (h != NULL) ++ { ++ if (start_stop_count == start_stop_alloc) ++ { ++ start_stop_alloc = 2 * start_stop_alloc + 10; ++ start_stop_syms ++ = xrealloc (start_stop_syms, ++ start_stop_alloc * sizeof (*start_stop_syms)); ++ } ++ start_stop_syms[start_stop_count++] = h; ++ } ++} ++ ++/* Check for input sections whose names match references to ++ __start_SECNAME or __stop_SECNAME symbols. Give the symbols ++ preliminary definitions. */ ++ ++static void ++lang_init_start_stop (void) ++{ ++ bfd *abfd; ++ asection *s; ++ char leading_char = bfd_get_symbol_leading_char (link_info.output_bfd); ++ ++ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next) ++ for (s = abfd->sections; s != NULL; s = s->next) ++ { ++ const char *ps; ++ const char *secname = s->name; ++ ++ for (ps = secname; *ps != '\0'; ps++) ++ if (!ISALNUM ((unsigned char) *ps) && *ps != '_') ++ break; ++ if (*ps == '\0') ++ { ++ char *symbol = (char *) xmalloc (10 + strlen (secname)); ++ ++ symbol[0] = leading_char; ++ sprintf (symbol + (leading_char != 0), "__start_%s", secname); ++ lang_define_start_stop (symbol, s); ++ ++ symbol[1] = leading_char; ++ memcpy (symbol + 1 + (leading_char != 0), "__stop", 6); ++ lang_define_start_stop (symbol + 1, s); ++ ++ free (symbol); ++ } ++ } ++} ++ ++/* Iterate over start_stop_syms. */ ++ ++static void ++foreach_start_stop (void (*func) (struct bfd_link_hash_entry *)) ++{ ++ size_t i; ++ ++ for (i = 0; i < start_stop_count; ++i) ++ func (start_stop_syms[i]); ++} ++ ++/* __start and __stop symbols are only supposed to be defined by the ++ linker for orphan sections, but we now extend that to sections that ++ map to an output section of the same name. The symbols were ++ defined early for --gc-sections, before we mapped input to output ++ sections, so undo those that don't satisfy this rule. */ ++ ++static void ++undef_start_stop (struct bfd_link_hash_entry *h) ++{ ++ if (h->ldscript_def) ++ return; ++ ++ if (h->u.def.section->output_section == NULL ++ || h->u.def.section->output_section->owner != link_info.output_bfd ++ || strcmp (h->u.def.section->name, ++ h->u.def.section->output_section->name) != 0) ++ { ++ asection *sec = bfd_get_section_by_name (link_info.output_bfd, ++ h->u.def.section->name); ++ if (sec != NULL) ++ { ++ /* When there are more than one input sections with the same ++ section name, SECNAME, linker picks the first one to define ++ __start_SECNAME and __stop_SECNAME symbols. When the first ++ input section is removed by comdat group, we need to check ++ if there is still an output section with section name ++ SECNAME. */ ++ asection *i; ++ for (i = sec->map_head.s; i != NULL; i = i->map_head.s) ++ if (strcmp (h->u.def.section->name, i->name) == 0) ++ { ++ h->u.def.section = i; ++ return; ++ } ++ } ++ h->type = bfd_link_hash_undefined; ++ h->u.undef.abfd = NULL; ++ if (is_elf_hash_table (link_info.hash)) ++ { ++ const struct elf_backend_data *bed; ++ struct elf_link_hash_entry *eh = (struct elf_link_hash_entry *) h; ++ unsigned int was_forced = eh->forced_local; ++ ++ bed = get_elf_backend_data (link_info.output_bfd); ++ (*bed->elf_backend_hide_symbol) (&link_info, eh, true); ++ if (!eh->ref_regular_nonweak) ++ h->type = bfd_link_hash_undefweak; ++ eh->def_regular = 0; ++ eh->forced_local = was_forced; ++ } ++ } ++} ++ ++static void ++lang_undef_start_stop (void) ++{ ++ foreach_start_stop (undef_start_stop); ++} ++ ++/* Check for output sections whose names match references to ++ .startof.SECNAME or .sizeof.SECNAME symbols. Give the symbols ++ preliminary definitions. */ ++ ++static void ++lang_init_startof_sizeof (void) ++{ ++ asection *s; ++ ++ for (s = link_info.output_bfd->sections; s != NULL; s = s->next) ++ { ++ const char *secname = s->name; ++ char *symbol = (char *) xmalloc (10 + strlen (secname)); ++ ++ sprintf (symbol, ".startof.%s", secname); ++ lang_define_start_stop (symbol, s); ++ ++ memcpy (symbol + 1, ".size", 5); ++ lang_define_start_stop (symbol + 1, s); ++ free (symbol); ++ } ++} ++ ++/* Set .startof., .sizeof., __start and __stop symbols final values. */ ++ ++static void ++set_start_stop (struct bfd_link_hash_entry *h) ++{ ++ if (h->ldscript_def ++ || h->type != bfd_link_hash_defined) ++ return; ++ ++ if (h->root.string[0] == '.') ++ { ++ /* .startof. or .sizeof. symbol. ++ .startof. already has final value. */ ++ if (h->root.string[2] == 'i') ++ { ++ /* .sizeof. */ ++ h->u.def.value = TO_ADDR (h->u.def.section->size); ++ h->u.def.section = bfd_abs_section_ptr; ++ } ++ } ++ else ++ { ++ /* __start or __stop symbol. */ ++ int has_lead = bfd_get_symbol_leading_char (link_info.output_bfd) != 0; ++ ++ h->u.def.section = h->u.def.section->output_section; ++ if (h->root.string[4 + has_lead] == 'o') ++ { ++ /* __stop_ */ ++ h->u.def.value = TO_ADDR (h->u.def.section->size); ++ } ++ } ++} ++ ++static void ++lang_finalize_start_stop (void) ++{ ++ foreach_start_stop (set_start_stop); ++} ++ ++static void ++lang_symbol_tweaks (void) ++{ ++ /* Give initial values for __start and __stop symbols, so that ELF ++ gc_sections will keep sections referenced by these symbols. Must ++ be done before lang_do_assignments. */ ++ if (config.build_constructors) ++ lang_init_start_stop (); ++ ++ /* Make __ehdr_start hidden, and set def_regular even though it is ++ likely undefined at this stage. For lang_check_relocs. */ ++ if (is_elf_hash_table (link_info.hash) ++ && !bfd_link_relocatable (&link_info)) ++ { ++ struct elf_link_hash_entry *h = (struct elf_link_hash_entry *) ++ bfd_link_hash_lookup (link_info.hash, "__ehdr_start", ++ false, false, true); ++ ++ /* Only adjust the export class if the symbol was referenced ++ and not defined, otherwise leave it alone. */ ++ if (h != NULL ++ && (h->root.type == bfd_link_hash_new ++ || h->root.type == bfd_link_hash_undefined ++ || h->root.type == bfd_link_hash_undefweak ++ || h->root.type == bfd_link_hash_common)) ++ { ++ const struct elf_backend_data *bed; ++ bed = get_elf_backend_data (link_info.output_bfd); ++ (*bed->elf_backend_hide_symbol) (&link_info, h, true); ++ if (ELF_ST_VISIBILITY (h->other) != STV_INTERNAL) ++ h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; ++ h->def_regular = 1; ++ h->root.linker_def = 1; ++ h->root.rel_from_abs = 1; ++ } ++ } ++} ++ ++static void ++lang_end (void) ++{ ++ struct bfd_link_hash_entry *h; ++ bool warn; ++ ++ if ((bfd_link_relocatable (&link_info) && !link_info.gc_sections) ++ || bfd_link_dll (&link_info)) ++ warn = entry_from_cmdline; ++ else ++ warn = true; ++ ++ /* Force the user to specify a root when generating a relocatable with ++ --gc-sections, unless --gc-keep-exported was also given. */ ++ if (bfd_link_relocatable (&link_info) ++ && link_info.gc_sections ++ && !link_info.gc_keep_exported) ++ { ++ struct bfd_sym_chain *sym; ++ ++ for (sym = link_info.gc_sym_list; sym != NULL; sym = sym->next) ++ { ++ h = bfd_link_hash_lookup (link_info.hash, sym->name, ++ false, false, false); ++ if (h != NULL ++ && (h->type == bfd_link_hash_defined ++ || h->type == bfd_link_hash_defweak) ++ && !bfd_is_const_section (h->u.def.section)) ++ break; ++ } ++ if (!sym) ++ einfo (_("%F%P: --gc-sections requires a defined symbol root " ++ "specified by -e or -u\n")); ++ } ++ ++ if (entry_symbol.name == NULL) ++ { ++ /* No entry has been specified. Look for the default entry, but ++ don't warn if we don't find it. */ ++ entry_symbol.name = entry_symbol_default; ++ warn = false; ++ } ++ ++ h = bfd_link_hash_lookup (link_info.hash, entry_symbol.name, ++ false, false, true); ++ if (h != NULL ++ && (h->type == bfd_link_hash_defined ++ || h->type == bfd_link_hash_defweak) ++ && h->u.def.section->output_section != NULL) ++ { ++ bfd_vma val; ++ ++ val = (h->u.def.value ++ + bfd_section_vma (h->u.def.section->output_section) ++ + h->u.def.section->output_offset); ++ if (!bfd_set_start_address (link_info.output_bfd, val)) ++ einfo (_("%F%P: %s: can't set start address\n"), entry_symbol.name); ++ } ++ else ++ { ++ bfd_vma val; ++ const char *send; ++ ++ /* We couldn't find the entry symbol. Try parsing it as a ++ number. */ ++ val = bfd_scan_vma (entry_symbol.name, &send, 0); ++ if (*send == '\0') ++ { ++ if (!bfd_set_start_address (link_info.output_bfd, val)) ++ einfo (_("%F%P: can't set start address\n")); ++ } ++ /* BZ 2004952: Only use the start of the entry section for executables. */ ++ else if bfd_link_executable (&link_info) ++ { ++ asection *ts; ++ ++ /* Can't find the entry symbol, and it's not a number. Use ++ the first address in the text section. */ ++ ts = bfd_get_section_by_name (link_info.output_bfd, entry_section); ++ if (ts != NULL) ++ { ++ if (warn) ++ einfo (_("%P: warning: cannot find entry symbol %s;" ++ " defaulting to %V\n"), ++ entry_symbol.name, ++ bfd_section_vma (ts)); ++ if (!bfd_set_start_address (link_info.output_bfd, ++ bfd_section_vma (ts))) ++ einfo (_("%F%P: can't set start address\n")); ++ } ++ else ++ { ++ if (warn) ++ einfo (_("%P: warning: cannot find entry symbol %s;" ++ " not setting start address\n"), ++ entry_symbol.name); ++ } ++ } ++ else ++ { ++ if (warn) ++ einfo (_("%P: warning: cannot find entry symbol %s;" ++ " not setting start address\n"), ++ entry_symbol.name); ++ } ++ } ++} ++ ++/* This is a small function used when we want to ignore errors from ++ BFD. */ ++ ++static void ++ignore_bfd_errors (const char *fmt ATTRIBUTE_UNUSED, ++ va_list ap ATTRIBUTE_UNUSED) ++{ ++ /* Don't do anything. */ ++} ++ ++/* Check that the architecture of all the input files is compatible ++ with the output file. Also call the backend to let it do any ++ other checking that is needed. */ ++ ++static void ++lang_check (void) ++{ ++ lang_input_statement_type *file; ++ bfd *input_bfd; ++ const bfd_arch_info_type *compatible; ++ ++ for (file = (void *) file_chain.head; ++ file != NULL; ++ file = file->next) ++ { ++#if BFD_SUPPORTS_PLUGINS ++ /* Don't check format of files claimed by plugin. */ ++ if (file->flags.claimed) ++ continue; ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ input_bfd = file->the_bfd; ++ compatible ++ = bfd_arch_get_compatible (input_bfd, link_info.output_bfd, ++ command_line.accept_unknown_input_arch); ++ ++ /* In general it is not possible to perform a relocatable ++ link between differing object formats when the input ++ file has relocations, because the relocations in the ++ input format may not have equivalent representations in ++ the output format (and besides BFD does not translate ++ relocs for other link purposes than a final link). */ ++ if (!file->flags.just_syms ++ && (bfd_link_relocatable (&link_info) ++ || link_info.emitrelocations) ++ && (compatible == NULL ++ || (bfd_get_flavour (input_bfd) ++ != bfd_get_flavour (link_info.output_bfd))) ++ && (bfd_get_file_flags (input_bfd) & HAS_RELOC) != 0) ++ { ++ einfo (_("%F%P: relocatable linking with relocations from" ++ " format %s (%pB) to format %s (%pB) is not supported\n"), ++ bfd_get_target (input_bfd), input_bfd, ++ bfd_get_target (link_info.output_bfd), link_info.output_bfd); ++ /* einfo with %F exits. */ ++ } ++ ++ if (compatible == NULL) ++ { ++ if (command_line.warn_mismatch) ++ einfo (_("%X%P: %s architecture of input file `%pB'" ++ " is incompatible with %s output\n"), ++ bfd_printable_name (input_bfd), input_bfd, ++ bfd_printable_name (link_info.output_bfd)); ++ } ++ ++ /* If the input bfd has no contents, it shouldn't set the ++ private data of the output bfd. */ ++ else if (!file->flags.just_syms ++ && ((input_bfd->flags & DYNAMIC) != 0 ++ || bfd_count_sections (input_bfd) != 0)) ++ { ++ bfd_error_handler_type pfn = NULL; ++ ++ /* If we aren't supposed to warn about mismatched input ++ files, temporarily set the BFD error handler to a ++ function which will do nothing. We still want to call ++ bfd_merge_private_bfd_data, since it may set up ++ information which is needed in the output file. */ ++ if (!command_line.warn_mismatch) ++ pfn = bfd_set_error_handler (ignore_bfd_errors); ++ if (!bfd_merge_private_bfd_data (input_bfd, &link_info)) ++ { ++ if (command_line.warn_mismatch) ++ einfo (_("%X%P: failed to merge target specific data" ++ " of file %pB\n"), input_bfd); ++ } ++ if (!command_line.warn_mismatch) ++ bfd_set_error_handler (pfn); ++ } ++ } ++} ++ ++/* Look through all the global common symbols and attach them to the ++ correct section. The -sort-common command line switch may be used ++ to roughly sort the entries by alignment. */ ++ ++static void ++lang_common (void) ++{ ++ if (link_info.inhibit_common_definition) ++ return; ++ if (bfd_link_relocatable (&link_info) ++ && !command_line.force_common_definition) ++ return; ++ ++ if (!config.sort_common) ++ bfd_link_hash_traverse (link_info.hash, lang_one_common, NULL); ++ else ++ { ++ unsigned int power; ++ ++ if (config.sort_common == sort_descending) ++ { ++ for (power = 4; power > 0; power--) ++ bfd_link_hash_traverse (link_info.hash, lang_one_common, &power); ++ ++ power = 0; ++ bfd_link_hash_traverse (link_info.hash, lang_one_common, &power); ++ } ++ else ++ { ++ for (power = 0; power <= 4; power++) ++ bfd_link_hash_traverse (link_info.hash, lang_one_common, &power); ++ ++ power = (unsigned int) -1; ++ bfd_link_hash_traverse (link_info.hash, lang_one_common, &power); ++ } ++ } ++} ++ ++/* Place one common symbol in the correct section. */ ++ ++static bool ++lang_one_common (struct bfd_link_hash_entry *h, void *info) ++{ ++ unsigned int power_of_two; ++ bfd_vma size; ++ asection *section; ++ ++ if (h->type != bfd_link_hash_common) ++ return true; ++ ++ size = h->u.c.size; ++ power_of_two = h->u.c.p->alignment_power; ++ ++ if (config.sort_common == sort_descending ++ && power_of_two < *(unsigned int *) info) ++ return true; ++ else if (config.sort_common == sort_ascending ++ && power_of_two > *(unsigned int *) info) ++ return true; ++ ++ section = h->u.c.p->section; ++ if (!bfd_define_common_symbol (link_info.output_bfd, &link_info, h)) ++ einfo (_("%F%P: could not define common symbol `%pT': %E\n"), ++ h->root.string); ++ ++ if (config.map_file != NULL) ++ { ++ static bool header_printed; ++ int len; ++ char *name; ++ char buf[32]; ++ ++ if (!header_printed) ++ { ++ minfo (_("\nAllocating common symbols\n")); ++ minfo (_("Common symbol size file\n\n")); ++ header_printed = true; ++ } ++ ++ name = bfd_demangle (link_info.output_bfd, h->root.string, ++ DMGL_ANSI | DMGL_PARAMS); ++ if (name == NULL) ++ { ++ minfo ("%s", h->root.string); ++ len = strlen (h->root.string); ++ } ++ else ++ { ++ minfo ("%s", name); ++ len = strlen (name); ++ free (name); ++ } ++ ++ if (len >= 19) ++ { ++ print_nl (); ++ len = 0; ++ } ++ ++ sprintf (buf, "%" PRIx64, (uint64_t) size); ++ fprintf (config.map_file, "%*s0x%-16s", 20 - len, "", buf); ++ ++ minfo ("%pB\n", section->owner); ++ } ++ ++ return true; ++} ++ ++/* Handle a single orphan section S, placing the orphan into an appropriate ++ output section. The effects of the --orphan-handling command line ++ option are handled here. */ ++ ++static void ++ldlang_place_orphan (asection *s) ++{ ++ if (config.orphan_handling == orphan_handling_discard) ++ { ++ lang_output_section_statement_type *os; ++ os = lang_output_section_statement_lookup (DISCARD_SECTION_NAME, 0, 1); ++ if (os->addr_tree == NULL ++ && (bfd_link_relocatable (&link_info) ++ || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) ++ os->addr_tree = exp_intop (0); ++ lang_add_section (&os->children, s, NULL, NULL, os); ++ } ++ else ++ { ++ lang_output_section_statement_type *os; ++ const char *name = s->name; ++ int constraint = 0; ++ ++ if (config.orphan_handling == orphan_handling_error) ++ einfo (_("%X%P: error: unplaced orphan section `%pA' from `%pB'\n"), ++ s, s->owner); ++ ++ if (config.unique_orphan_sections || unique_section_p (s, NULL)) ++ constraint = SPECIAL; ++ ++ os = ldemul_place_orphan (s, name, constraint); ++ if (os == NULL) ++ { ++ os = lang_output_section_statement_lookup (name, constraint, 1); ++ if (os->addr_tree == NULL ++ && (bfd_link_relocatable (&link_info) ++ || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)) ++ os->addr_tree = exp_intop (0); ++ lang_add_section (&os->children, s, NULL, NULL, os); ++ } ++ ++ if (config.orphan_handling == orphan_handling_warn) ++ einfo (_("%P: warning: orphan section `%pA' from `%pB' being " ++ "placed in section `%s'\n"), ++ s, s->owner, os->name); ++ } ++} ++ ++/* Run through the input files and ensure that every input section has ++ somewhere to go. If one is found without a destination then create ++ an input request and place it into the statement tree. */ ++ ++static void ++lang_place_orphans (void) ++{ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ asection *s; ++ ++ for (s = file->the_bfd->sections; s != NULL; s = s->next) ++ { ++ if (s->output_section == NULL) ++ { ++ /* This section of the file is not attached, root ++ around for a sensible place for it to go. */ ++ ++ if (file->flags.just_syms) ++ bfd_link_just_syms (file->the_bfd, s, &link_info); ++ else if (lang_discard_section_p (s)) ++ s->output_section = bfd_abs_section_ptr; ++ else if (strcmp (s->name, "COMMON") == 0) ++ { ++ /* This is a lonely common section which must have ++ come from an archive. We attach to the section ++ with the wildcard. */ ++ if (!bfd_link_relocatable (&link_info) ++ || command_line.force_common_definition) ++ { ++ if (default_common_section == NULL) ++ default_common_section ++ = lang_output_section_statement_lookup (".bss", 0, 1); ++ lang_add_section (&default_common_section->children, s, ++ NULL, NULL, default_common_section); ++ } ++ } ++ else ++ ldlang_place_orphan (s); ++ } ++ } ++ } ++} ++ ++void ++lang_set_flags (lang_memory_region_type *ptr, const char *flags, int invert) ++{ ++ flagword *ptr_flags; ++ ++ ptr_flags = invert ? &ptr->not_flags : &ptr->flags; ++ ++ while (*flags) ++ { ++ switch (*flags) ++ { ++ /* PR 17900: An exclamation mark in the attributes reverses ++ the sense of any of the attributes that follow. */ ++ case '!': ++ invert = !invert; ++ ptr_flags = invert ? &ptr->not_flags : &ptr->flags; ++ break; ++ ++ case 'A': case 'a': ++ *ptr_flags |= SEC_ALLOC; ++ break; ++ ++ case 'R': case 'r': ++ *ptr_flags |= SEC_READONLY; ++ break; ++ ++ case 'W': case 'w': ++ *ptr_flags |= SEC_DATA; ++ break; ++ ++ case 'X': case 'x': ++ *ptr_flags |= SEC_CODE; ++ break; ++ ++ case 'L': case 'l': ++ case 'I': case 'i': ++ *ptr_flags |= SEC_LOAD; ++ break; ++ ++ default: ++ einfo (_("%F%P: invalid character %c (%d) in flags\n"), ++ *flags, *flags); ++ break; ++ } ++ flags++; ++ } ++} ++ ++/* Call a function on each real input file. This function will be ++ called on an archive, but not on the elements. */ ++ ++void ++lang_for_each_input_file (void (*func) (lang_input_statement_type *)) ++{ ++ lang_input_statement_type *f; ++ ++ for (f = (void *) input_file_chain.head; ++ f != NULL; ++ f = f->next_real_file) ++ if (f->flags.real) ++ func (f); ++} ++ ++/* Call a function on each real file. The function will be called on ++ all the elements of an archive which are included in the link, but ++ will not be called on the archive file itself. */ ++ ++void ++lang_for_each_file (void (*func) (lang_input_statement_type *)) ++{ ++ LANG_FOR_EACH_INPUT_STATEMENT (f) ++ { ++ if (f->flags.real) ++ func (f); ++ } ++} ++ ++void ++ldlang_add_file (lang_input_statement_type *entry) ++{ ++ lang_statement_append (&file_chain, entry, &entry->next); ++ ++ /* The BFD linker needs to have a list of all input BFDs involved in ++ a link. */ ++ ASSERT (link_info.input_bfds_tail != &entry->the_bfd->link.next ++ && entry->the_bfd->link.next == NULL); ++ ASSERT (entry->the_bfd != link_info.output_bfd); ++ ++ *link_info.input_bfds_tail = entry->the_bfd; ++ link_info.input_bfds_tail = &entry->the_bfd->link.next; ++ bfd_set_usrdata (entry->the_bfd, entry); ++ bfd_set_gp_size (entry->the_bfd, g_switch_value); ++ ++ /* Look through the sections and check for any which should not be ++ included in the link. We need to do this now, so that we can ++ notice when the backend linker tries to report multiple ++ definition errors for symbols which are in sections we aren't ++ going to link. FIXME: It might be better to entirely ignore ++ symbols which are defined in sections which are going to be ++ discarded. This would require modifying the backend linker for ++ each backend which might set the SEC_LINK_ONCE flag. If we do ++ this, we should probably handle SEC_EXCLUDE in the same way. */ ++ ++ bfd_map_over_sections (entry->the_bfd, section_already_linked, entry); ++} ++ ++void ++lang_add_output (const char *name, int from_script) ++{ ++ /* Make -o on command line override OUTPUT in script. */ ++ if (!had_output_filename || !from_script) ++ { ++ output_filename = name; ++ had_output_filename = true; ++ } ++} ++ ++lang_output_section_statement_type * ++lang_enter_output_section_statement (const char *output_section_statement_name, ++ etree_type *address_exp, ++ enum section_type sectype, ++ etree_type *sectype_value, ++ etree_type *align, ++ etree_type *subalign, ++ etree_type *ebase, ++ int constraint, ++ int align_with_input) ++{ ++ lang_output_section_statement_type *os; ++ ++ os = lang_output_section_statement_lookup (output_section_statement_name, ++ constraint, 2); ++ current_section = os; ++ ++ if (os->addr_tree == NULL) ++ { ++ os->addr_tree = address_exp; ++ } ++ os->sectype = sectype; ++ if (sectype == type_section || sectype == typed_readonly_section) ++ os->sectype_value = sectype_value; ++ else if (sectype == noload_section) ++ os->flags = SEC_NEVER_LOAD; ++ else ++ os->flags = SEC_NO_FLAGS; ++ os->block_value = 1; ++ ++ /* Make next things chain into subchain of this. */ ++ push_stat_ptr (&os->children); ++ ++ os->align_lma_with_input = align_with_input == ALIGN_WITH_INPUT; ++ if (os->align_lma_with_input && align != NULL) ++ einfo (_("%F%P:%pS: error: align with input and explicit align specified\n"), ++ NULL); ++ ++ os->subsection_alignment = subalign; ++ os->section_alignment = align; ++ ++ os->load_base = ebase; ++ return os; ++} ++ ++void ++lang_final (void) ++{ ++ lang_output_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_output_statement, stat_ptr); ++ new_stmt->name = output_filename; ++} ++ ++/* Reset the current counters in the regions. */ ++ ++void ++lang_reset_memory_regions (void) ++{ ++ lang_memory_region_type *p = lang_memory_region_list; ++ asection *o; ++ lang_output_section_statement_type *os; ++ ++ for (p = lang_memory_region_list; p != NULL; p = p->next) ++ { ++ p->current = p->origin; ++ p->last_os = NULL; ++ } ++ ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ os->processed_vma = false; ++ os->processed_lma = false; ++ } ++ ++ for (o = link_info.output_bfd->sections; o != NULL; o = o->next) ++ { ++ /* Save the last size for possible use by bfd_relax_section. */ ++ o->rawsize = o->size; ++ if (!(o->flags & SEC_FIXED_SIZE)) ++ o->size = 0; ++ } ++} ++ ++/* Worker for lang_gc_sections_1. */ ++ ++static void ++gc_section_callback (lang_wild_statement_type *ptr, ++ struct wildcard_list *sec ATTRIBUTE_UNUSED, ++ asection *section, ++ lang_input_statement_type *file ATTRIBUTE_UNUSED, ++ void *data ATTRIBUTE_UNUSED) ++{ ++ /* If the wild pattern was marked KEEP, the member sections ++ should be as well. */ ++ if (ptr->keep_sections) ++ section->flags |= SEC_KEEP; ++} ++ ++/* Iterate over sections marking them against GC. */ ++ ++static void ++lang_gc_sections_1 (lang_statement_union_type *s) ++{ ++ for (; s != NULL; s = s->header.next) ++ { ++ switch (s->header.type) ++ { ++ case lang_wild_statement_enum: ++ walk_wild (&s->wild_statement, gc_section_callback, NULL); ++ break; ++ case lang_constructors_statement_enum: ++ lang_gc_sections_1 (constructor_list.head); ++ break; ++ case lang_output_section_statement_enum: ++ lang_gc_sections_1 (s->output_section_statement.children.head); ++ break; ++ case lang_group_statement_enum: ++ lang_gc_sections_1 (s->group_statement.children.head); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void ++lang_gc_sections (void) ++{ ++ /* Keep all sections so marked in the link script. */ ++ lang_gc_sections_1 (statement_list.head); ++ ++ /* SEC_EXCLUDE is ignored when doing a relocatable link, except in ++ the special case of .stabstr debug info. (See bfd/stabs.c) ++ Twiddle the flag here, to simplify later linker code. */ ++ if (bfd_link_relocatable (&link_info)) ++ { ++ LANG_FOR_EACH_INPUT_STATEMENT (f) ++ { ++ asection *sec; ++#if BFD_SUPPORTS_PLUGINS ++ if (f->flags.claimed) ++ continue; ++#endif ++ for (sec = f->the_bfd->sections; sec != NULL; sec = sec->next) ++ if ((sec->flags & SEC_DEBUGGING) == 0 ++ || strcmp (sec->name, ".stabstr") != 0) ++ sec->flags &= ~SEC_EXCLUDE; ++ } ++ } ++ ++ if (link_info.gc_sections) ++ bfd_gc_sections (link_info.output_bfd, &link_info); ++} ++ ++/* Worker for lang_find_relro_sections_1. */ ++ ++static void ++find_relro_section_callback (lang_wild_statement_type *ptr ATTRIBUTE_UNUSED, ++ struct wildcard_list *sec ATTRIBUTE_UNUSED, ++ asection *section, ++ lang_input_statement_type *file ATTRIBUTE_UNUSED, ++ void *data) ++{ ++ /* Discarded, excluded and ignored sections effectively have zero ++ size. */ ++ if (section->output_section != NULL ++ && section->output_section->owner == link_info.output_bfd ++ && (section->output_section->flags & SEC_EXCLUDE) == 0 ++ && !IGNORE_SECTION (section) ++ && section->size != 0) ++ { ++ bool *has_relro_section = (bool *) data; ++ *has_relro_section = true; ++ } ++} ++ ++/* Iterate over sections for relro sections. */ ++ ++static void ++lang_find_relro_sections_1 (lang_statement_union_type *s, ++ bool *has_relro_section) ++{ ++ if (*has_relro_section) ++ return; ++ ++ for (; s != NULL; s = s->header.next) ++ { ++ if (s == expld.dataseg.relro_end_stat) ++ break; ++ ++ switch (s->header.type) ++ { ++ case lang_wild_statement_enum: ++ walk_wild (&s->wild_statement, ++ find_relro_section_callback, ++ has_relro_section); ++ break; ++ case lang_constructors_statement_enum: ++ lang_find_relro_sections_1 (constructor_list.head, ++ has_relro_section); ++ break; ++ case lang_output_section_statement_enum: ++ lang_find_relro_sections_1 (s->output_section_statement.children.head, ++ has_relro_section); ++ break; ++ case lang_group_statement_enum: ++ lang_find_relro_sections_1 (s->group_statement.children.head, ++ has_relro_section); ++ break; ++ default: ++ break; ++ } ++ } ++} ++ ++static void ++lang_find_relro_sections (void) ++{ ++ bool has_relro_section = false; ++ ++ /* Check all sections in the link script. */ ++ ++ lang_find_relro_sections_1 (expld.dataseg.relro_start_stat, ++ &has_relro_section); ++ ++ if (!has_relro_section) ++ link_info.relro = false; ++} ++ ++/* Relax all sections until bfd_relax_section gives up. */ ++ ++void ++lang_relax_sections (bool need_layout) ++{ ++ /* NB: Also enable relaxation to layout sections for DT_RELR. */ ++ if (RELAXATION_ENABLED || link_info.enable_dt_relr) ++ { ++ /* We may need more than one relaxation pass. */ ++ int i = link_info.relax_pass; ++ ++ /* The backend can use it to determine the current pass. */ ++ link_info.relax_pass = 0; ++ ++ while (i--) ++ { ++ /* Keep relaxing until bfd_relax_section gives up. */ ++ bool relax_again; ++ ++ link_info.relax_trip = -1; ++ do ++ { ++ link_info.relax_trip++; ++ ++ /* Note: pe-dll.c does something like this also. If you find ++ you need to change this code, you probably need to change ++ pe-dll.c also. DJ */ ++ ++ /* Do all the assignments with our current guesses as to ++ section sizes. */ ++ lang_do_assignments (lang_assigning_phase_enum); ++ ++ /* We must do this after lang_do_assignments, because it uses ++ size. */ ++ lang_reset_memory_regions (); ++ ++ /* Perform another relax pass - this time we know where the ++ globals are, so can make a better guess. */ ++ relax_again = false; ++ lang_size_sections (&relax_again, false); ++ } ++ while (relax_again); ++ ++ link_info.relax_pass++; ++ } ++ need_layout = true; ++ } ++ ++ if (need_layout) ++ { ++ /* Final extra sizing to report errors. */ ++ lang_do_assignments (lang_assigning_phase_enum); ++ lang_reset_memory_regions (); ++ lang_size_sections (NULL, true); ++ } ++} ++ ++#if BFD_SUPPORTS_PLUGINS ++/* Find the insert point for the plugin's replacement files. We ++ place them after the first claimed real object file, or if the ++ first claimed object is an archive member, after the last real ++ object file immediately preceding the archive. In the event ++ no objects have been claimed at all, we return the first dummy ++ object file on the list as the insert point; that works, but ++ the callee must be careful when relinking the file_chain as it ++ is not actually on that chain, only the statement_list and the ++ input_file list; in that case, the replacement files must be ++ inserted at the head of the file_chain. */ ++ ++static lang_input_statement_type * ++find_replacements_insert_point (bool *before) ++{ ++ lang_input_statement_type *claim1, *lastobject; ++ lastobject = (void *) input_file_chain.head; ++ for (claim1 = (void *) file_chain.head; ++ claim1 != NULL; ++ claim1 = claim1->next) ++ { ++ if (claim1->flags.claimed) ++ { ++ *before = claim1->flags.claim_archive; ++ return claim1->flags.claim_archive ? lastobject : claim1; ++ } ++ /* Update lastobject if this is a real object file. */ ++ if (claim1->the_bfd != NULL && claim1->the_bfd->my_archive == NULL) ++ lastobject = claim1; ++ } ++ /* No files were claimed by the plugin. Choose the last object ++ file found on the list (maybe the first, dummy entry) as the ++ insert point. */ ++ *before = false; ++ return lastobject; ++} ++ ++/* Find where to insert ADD, an archive element or shared library ++ added during a rescan. */ ++ ++static lang_input_statement_type ** ++find_rescan_insertion (lang_input_statement_type *add) ++{ ++ bfd *add_bfd = add->the_bfd; ++ lang_input_statement_type *f; ++ lang_input_statement_type *last_loaded = NULL; ++ lang_input_statement_type *before = NULL; ++ lang_input_statement_type **iter = NULL; ++ ++ if (add_bfd->my_archive != NULL) ++ add_bfd = add_bfd->my_archive; ++ ++ /* First look through the input file chain, to find an object file ++ before the one we've rescanned. Normal object files always ++ appear on both the input file chain and the file chain, so this ++ lets us get quickly to somewhere near the correct place on the ++ file chain if it is full of archive elements. Archives don't ++ appear on the file chain, but if an element has been extracted ++ then their input_statement->next points at it. */ ++ for (f = (void *) input_file_chain.head; ++ f != NULL; ++ f = f->next_real_file) ++ { ++ if (f->the_bfd == add_bfd) ++ { ++ before = last_loaded; ++ if (f->next != NULL) ++ return &f->next->next; ++ } ++ if (f->the_bfd != NULL && f->next != NULL) ++ last_loaded = f; ++ } ++ ++ for (iter = before ? &before->next : &file_chain.head->input_statement.next; ++ *iter != NULL; ++ iter = &(*iter)->next) ++ if (!(*iter)->flags.claim_archive ++ && (*iter)->the_bfd->my_archive == NULL) ++ break; ++ ++ return iter; ++} ++ ++/* Insert SRCLIST into DESTLIST after given element by chaining ++ on FIELD as the next-pointer. (Counterintuitively does not need ++ a pointer to the actual after-node itself, just its chain field.) */ ++ ++static void ++lang_list_insert_after (lang_statement_list_type *destlist, ++ lang_statement_list_type *srclist, ++ lang_statement_union_type **field) ++{ ++ *(srclist->tail) = *field; ++ *field = srclist->head; ++ if (destlist->tail == field) ++ destlist->tail = srclist->tail; ++} ++ ++/* Detach new nodes added to DESTLIST since the time ORIGLIST ++ was taken as a copy of it and leave them in ORIGLIST. */ ++ ++static void ++lang_list_remove_tail (lang_statement_list_type *destlist, ++ lang_statement_list_type *origlist) ++{ ++ union lang_statement_union **savetail; ++ /* Check that ORIGLIST really is an earlier state of DESTLIST. */ ++ ASSERT (origlist->head == destlist->head); ++ savetail = origlist->tail; ++ origlist->head = *(savetail); ++ origlist->tail = destlist->tail; ++ destlist->tail = savetail; ++ *savetail = NULL; ++} ++ ++static lang_statement_union_type ** ++find_next_input_statement (lang_statement_union_type **s) ++{ ++ for ( ; *s; s = &(*s)->header.next) ++ { ++ lang_statement_union_type **t; ++ switch ((*s)->header.type) ++ { ++ case lang_input_statement_enum: ++ return s; ++ case lang_wild_statement_enum: ++ t = &(*s)->wild_statement.children.head; ++ break; ++ case lang_group_statement_enum: ++ t = &(*s)->group_statement.children.head; ++ break; ++ case lang_output_section_statement_enum: ++ t = &(*s)->output_section_statement.children.head; ++ break; ++ default: ++ continue; ++ } ++ t = find_next_input_statement (t); ++ if (*t) ++ return t; ++ } ++ return s; ++} ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ ++/* Add NAME to the list of garbage collection entry points. */ ++ ++void ++lang_add_gc_name (const char *name) ++{ ++ struct bfd_sym_chain *sym; ++ ++ if (name == NULL) ++ return; ++ ++ sym = stat_alloc (sizeof (*sym)); ++ ++ sym->next = link_info.gc_sym_list; ++ sym->name = name; ++ link_info.gc_sym_list = sym; ++} ++ ++/* Check relocations. */ ++ ++static void ++lang_check_relocs (void) ++{ ++ if (link_info.check_relocs_after_open_input) ++ { ++ bfd *abfd; ++ ++ for (abfd = link_info.input_bfds; ++ abfd != (bfd *) NULL; abfd = abfd->link.next) ++ if (!bfd_link_check_relocs (abfd, &link_info)) ++ { ++ /* No object output, fail return. */ ++ config.make_executable = false; ++ /* Note: we do not abort the loop, but rather ++ continue the scan in case there are other ++ bad relocations to report. */ ++ } ++ } ++} ++ ++/* Look through all output sections looking for places where we can ++ propagate forward the lma region. */ ++ ++static void ++lang_propagate_lma_regions (void) ++{ ++ lang_output_section_statement_type *os; ++ ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ if (os->prev != NULL ++ && os->lma_region == NULL ++ && os->load_base == NULL ++ && os->addr_tree == NULL ++ && os->region == os->prev->region) ++ os->lma_region = os->prev->lma_region; ++ } ++} ++ ++static void ++warn_non_contiguous_discards (void) ++{ ++ LANG_FOR_EACH_INPUT_STATEMENT (file) ++ { ++ if ((file->the_bfd->flags & (BFD_LINKER_CREATED | DYNAMIC)) != 0 ++ || file->flags.just_syms) ++ continue; ++ ++ for (asection *s = file->the_bfd->sections; s != NULL; s = s->next) ++ if (s->output_section == NULL ++ && (s->flags & SEC_LINKER_CREATED) == 0) ++ einfo (_("%P: warning: --enable-non-contiguous-regions " ++ "discards section `%pA' from `%pB'\n"), ++ s, file->the_bfd); ++ } ++} ++ ++static void ++reset_one_wild (lang_statement_union_type *statement) ++{ ++ if (statement->header.type == lang_wild_statement_enum) ++ { ++ lang_wild_statement_type *stmt = &statement->wild_statement; ++ lang_list_init (&stmt->matching_sections); ++ } ++} ++ ++static void ++reset_resolved_wilds (void) ++{ ++ lang_for_each_statement (reset_one_wild); ++} ++ ++void ++lang_process (void) ++{ ++ /* Finalize dynamic list. */ ++ if (link_info.dynamic_list) ++ lang_finalize_version_expr_head (&link_info.dynamic_list->head); ++ ++ current_target = default_target; ++ ++ /* Open the output file. */ ++ lang_for_each_statement (ldlang_open_output); ++ init_opb (NULL); ++ ++ ldemul_create_output_section_statements (); ++ ++ /* Add to the hash table all undefineds on the command line. */ ++ lang_place_undefineds (); ++ ++ if (!bfd_section_already_linked_table_init ()) ++ einfo (_("%F%P: can not create hash table: %E\n")); ++ ++ /* A first pass through the memory regions ensures that if any region ++ references a symbol for its origin or length then this symbol will be ++ added to the symbol table. Having these symbols in the symbol table ++ means that when we call open_input_bfds PROVIDE statements will ++ trigger to provide any needed symbols. The regions origins and ++ lengths are not assigned as a result of this call. */ ++ lang_do_memory_regions (false); ++ ++ /* Create a bfd for each input file. */ ++ current_target = default_target; ++ lang_statement_iteration++; ++ open_input_bfds (statement_list.head, OPEN_BFD_NORMAL); ++ ++ /* Now that open_input_bfds has processed assignments and provide ++ statements we can give values to symbolic origin/length now. */ ++ lang_do_memory_regions (true); ++ ++ ldemul_before_plugin_all_symbols_read (); ++ ++#if BFD_SUPPORTS_PLUGINS ++ if (link_info.lto_plugin_active) ++ { ++ lang_statement_list_type added; ++ lang_statement_list_type files, inputfiles; ++ ++ /* Now all files are read, let the plugin(s) decide if there ++ are any more to be added to the link before we call the ++ emulation's after_open hook. We create a private list of ++ input statements for this purpose, which we will eventually ++ insert into the global statement list after the first claimed ++ file. */ ++ added = *stat_ptr; ++ /* We need to manipulate all three chains in synchrony. */ ++ files = file_chain; ++ inputfiles = input_file_chain; ++ if (plugin_call_all_symbols_read ()) ++ einfo (_("%F%P: %s: plugin reported error after all symbols read\n"), ++ plugin_error_plugin ()); ++ link_info.lto_all_symbols_read = true; ++ /* Open any newly added files, updating the file chains. */ ++ plugin_undefs = link_info.hash->undefs_tail; ++ open_input_bfds (*added.tail, OPEN_BFD_NORMAL); ++ if (plugin_undefs == link_info.hash->undefs_tail) ++ plugin_undefs = NULL; ++ /* Restore the global list pointer now they have all been added. */ ++ lang_list_remove_tail (stat_ptr, &added); ++ /* And detach the fresh ends of the file lists. */ ++ lang_list_remove_tail (&file_chain, &files); ++ lang_list_remove_tail (&input_file_chain, &inputfiles); ++ /* Were any new files added? */ ++ if (added.head != NULL) ++ { ++ /* If so, we will insert them into the statement list immediately ++ after the first input file that was claimed by the plugin, ++ unless that file was an archive in which case it is inserted ++ immediately before. */ ++ bool before; ++ lang_statement_union_type **prev; ++ plugin_insert = find_replacements_insert_point (&before); ++ /* If a plugin adds input files without having claimed any, we ++ don't really have a good idea where to place them. Just putting ++ them at the start or end of the list is liable to leave them ++ outside the crtbegin...crtend range. */ ++ ASSERT (plugin_insert != NULL); ++ /* Splice the new statement list into the old one. */ ++ prev = &plugin_insert->header.next; ++ if (before) ++ { ++ prev = find_next_input_statement (prev); ++ if (*prev != (void *) plugin_insert->next_real_file) ++ { ++ /* We didn't find the expected input statement. ++ Fall back to adding after plugin_insert. */ ++ prev = &plugin_insert->header.next; ++ } ++ } ++ lang_list_insert_after (stat_ptr, &added, prev); ++ /* Likewise for the file chains. */ ++ lang_list_insert_after (&input_file_chain, &inputfiles, ++ (void *) &plugin_insert->next_real_file); ++ /* We must be careful when relinking file_chain; we may need to ++ insert the new files at the head of the list if the insert ++ point chosen is the dummy first input file. */ ++ if (plugin_insert->filename) ++ lang_list_insert_after (&file_chain, &files, ++ (void *) &plugin_insert->next); ++ else ++ lang_list_insert_after (&file_chain, &files, &file_chain.head); ++ ++ /* Rescan archives in case new undefined symbols have appeared. */ ++ files = file_chain; ++ lang_statement_iteration++; ++ open_input_bfds (statement_list.head, OPEN_BFD_RESCAN); ++ lang_list_remove_tail (&file_chain, &files); ++ while (files.head != NULL) ++ { ++ lang_input_statement_type **insert; ++ lang_input_statement_type **iter, *temp; ++ bfd *my_arch; ++ ++ insert = find_rescan_insertion (&files.head->input_statement); ++ /* All elements from an archive can be added at once. */ ++ iter = &files.head->input_statement.next; ++ my_arch = files.head->input_statement.the_bfd->my_archive; ++ if (my_arch != NULL) ++ for (; *iter != NULL; iter = &(*iter)->next) ++ if ((*iter)->the_bfd->my_archive != my_arch) ++ break; ++ temp = *insert; ++ *insert = &files.head->input_statement; ++ files.head = (lang_statement_union_type *) *iter; ++ *iter = temp; ++ if (file_chain.tail == (lang_statement_union_type **) insert) ++ file_chain.tail = (lang_statement_union_type **) iter; ++ if (my_arch != NULL) ++ { ++ lang_input_statement_type *parent = bfd_usrdata (my_arch); ++ if (parent != NULL) ++ parent->next = (lang_input_statement_type *) ++ ((char *) iter ++ - offsetof (lang_input_statement_type, next)); ++ } ++ } ++ } ++ } ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ ++ struct bfd_sym_chain **sym = &link_info.gc_sym_list; ++ while (*sym) ++ sym = &(*sym)->next; ++ ++ *sym = &entry_symbol; ++ ++ if (entry_symbol.name == NULL) ++ { ++ *sym = ldlang_undef_chain_list_head; ++ ++ /* entry_symbol is normally initialised by an ENTRY definition in the ++ linker script or the -e command line option. But if neither of ++ these have been used, the target specific backend may still have ++ provided an entry symbol via a call to lang_default_entry(). ++ Unfortunately this value will not be processed until lang_end() ++ is called, long after this function has finished. So detect this ++ case here and add the target's entry symbol to the list of starting ++ points for garbage collection resolution. */ ++ lang_add_gc_name (entry_symbol_default); ++ } ++ ++ lang_add_gc_name (link_info.init_function); ++ lang_add_gc_name (link_info.fini_function); ++ ++ ldemul_after_open (); ++ if (config.map_file != NULL) ++ lang_print_asneeded (); ++ ++ ldlang_open_ctf (); ++ ++ bfd_section_already_linked_table_free (); ++ ++ /* Make sure that we're not mixing architectures. We call this ++ after all the input files have been opened, but before we do any ++ other processing, so that any operations merge_private_bfd_data ++ does on the output file will be known during the rest of the ++ link. */ ++ lang_check (); ++ ++ /* Handle .exports instead of a version script if we're told to do so. */ ++ if (command_line.version_exports_section) ++ lang_do_version_exports_section (); ++ ++ /* Build all sets based on the information gathered from the input ++ files. */ ++ ldctor_build_sets (); ++ ++ lang_symbol_tweaks (); ++ ++ /* PR 13683: We must rerun the assignments prior to running garbage ++ collection in order to make sure that all symbol aliases are resolved. */ ++ lang_do_assignments (lang_mark_phase_enum); ++ expld.phase = lang_first_phase_enum; ++ ++ /* Size up the common data. */ ++ lang_common (); ++ ++ if (0) ++ debug_prefix_tree (); ++ ++ resolve_wilds (); ++ ++ /* Remove unreferenced sections if asked to. */ ++ lang_gc_sections (); ++ ++ lang_mark_undefineds (); ++ ++ /* Check relocations. */ ++ lang_check_relocs (); ++ ++ ldemul_after_check_relocs (); ++ ++ /* There might have been new sections created (e.g. as result of ++ checking relocs to need a .got, or suchlike), so to properly order ++ them into our lists of matching sections reset them here. */ ++ reset_resolved_wilds (); ++ resolve_wilds (); ++ ++ /* Update wild statements in case the user gave --sort-section. ++ Note how the option might have come after the linker script and ++ so couldn't have been set when the wild statements were created. */ ++ update_wild_statements (statement_list.head); ++ ++ /* Run through the contours of the script and attach input sections ++ to the correct output sections. */ ++ lang_statement_iteration++; ++ map_input_to_output_sections (statement_list.head, NULL, NULL); ++ ++ /* Start at the statement immediately after the special abs_section ++ output statement, so that it isn't reordered. */ ++ process_insert_statements (&lang_os_list.head->header.next); ++ ++ ldemul_before_place_orphans (); ++ ++ /* Find any sections not attached explicitly and handle them. */ ++ lang_place_orphans (); ++ ++ if (!bfd_link_relocatable (&link_info)) ++ { ++ asection *found; ++ ++ /* Merge SEC_MERGE sections. This has to be done after GC of ++ sections, so that GCed sections are not merged, but before ++ assigning dynamic symbols, since removing whole input sections ++ is hard then. */ ++ bfd_merge_sections (link_info.output_bfd, &link_info); ++ ++ /* Look for a text section and set the readonly attribute in it. */ ++ found = bfd_get_section_by_name (link_info.output_bfd, ".text"); ++ ++ if (found != NULL) ++ { ++ if (config.text_read_only) ++ found->flags |= SEC_READONLY; ++ else ++ found->flags &= ~SEC_READONLY; ++ } ++ } ++ ++ /* Merge together CTF sections. After this, only the symtab-dependent ++ function and data object sections need adjustment. */ ++ lang_merge_ctf (); ++ ++ /* Emit the CTF, iff the emulation doesn't need to do late emission after ++ examining things laid out late, like the strtab. */ ++ lang_write_ctf (0); ++ ++ /* Copy forward lma regions for output sections in same lma region. */ ++ lang_propagate_lma_regions (); ++ ++ /* Defining __start/__stop symbols early for --gc-sections to work ++ around a glibc build problem can result in these symbols being ++ defined when they should not be. Fix them now. */ ++ if (config.build_constructors) ++ lang_undef_start_stop (); ++ ++ /* Define .startof./.sizeof. symbols with preliminary values before ++ dynamic symbols are created. */ ++ if (!bfd_link_relocatable (&link_info)) ++ lang_init_startof_sizeof (); ++ ++ /* Do anything special before sizing sections. This is where ELF ++ and other back-ends size dynamic sections. */ ++ ldemul_before_allocation (); ++ ++ /* We must record the program headers before we try to fix the ++ section positions, since they will affect SIZEOF_HEADERS. */ ++ lang_record_phdrs (); ++ ++ /* Check relro sections. */ ++ if (link_info.relro && !bfd_link_relocatable (&link_info)) ++ lang_find_relro_sections (); ++ ++ /* Size up the sections. */ ++ lang_size_sections (NULL, !RELAXATION_ENABLED); ++ ++ /* See if anything special should be done now we know how big ++ everything is. This is where relaxation is done. */ ++ ldemul_after_allocation (); ++ ++ /* Fix any __start, __stop, .startof. or .sizeof. symbols. */ ++ lang_finalize_start_stop (); ++ ++ /* Do all the assignments again, to report errors. Assignment ++ statements are processed multiple times, updating symbols; In ++ open_input_bfds, lang_do_assignments, and lang_size_sections. ++ Since lang_relax_sections calls lang_do_assignments, symbols are ++ also updated in ldemul_after_allocation. */ ++ lang_do_assignments (lang_final_phase_enum); ++ ++ ldemul_finish (); ++ ++ /* Convert absolute symbols to section relative. */ ++ ldexp_finalize_syms (); ++ ++ /* Make sure that the section addresses make sense. */ ++ if (command_line.check_section_addresses) ++ lang_check_section_addresses (); ++ ++ if (link_info.non_contiguous_regions ++ && link_info.non_contiguous_regions_warnings) ++ warn_non_contiguous_discards (); ++ ++ /* Check any required symbols are known. */ ++ ldlang_check_require_defined_symbols (); ++ ++ lang_end (); ++} ++ ++void ++lang_add_version_string (void) ++{ ++ if (! enable_linker_version) ++ return; ++ ++ const char * str = "GNU ld "; ++ int len = strlen (str); ++ int i; ++ ++ for (i = 0 ; i < len ; i++) ++ lang_add_data (BYTE, exp_intop (str[i])); ++ ++ str = BFD_VERSION_STRING; ++ len = strlen (str); ++ ++ for (i = 0 ; i < len ; i++) ++ lang_add_data (BYTE, exp_intop (str[i])); ++ ++ lang_add_data (BYTE, exp_intop ('\0')); ++} ++ ++/* EXPORTED TO YACC */ ++ ++void ++lang_add_wild (struct wildcard_spec *filespec, ++ struct wildcard_list *section_list, ++ bool keep_sections) ++{ ++ struct wildcard_list *curr, *next; ++ lang_wild_statement_type *new_stmt; ++ bool any_specs_sorted = false; ++ ++ /* Reverse the list as the parser puts it back to front. */ ++ for (curr = section_list, section_list = NULL; ++ curr != NULL; ++ section_list = curr, curr = next) ++ { ++ if (curr->spec.sorted != none && curr->spec.sorted != by_none) ++ any_specs_sorted = true; ++ next = curr->next; ++ curr->next = section_list; ++ } ++ ++ if (filespec != NULL && filespec->name != NULL) ++ { ++ if (strcmp (filespec->name, "*") == 0) ++ filespec->name = NULL; ++ else if (!wildcardp (filespec->name)) ++ lang_has_input_file = true; ++ } ++ ++ new_stmt = new_stat (lang_wild_statement, stat_ptr); ++ new_stmt->filename = NULL; ++ new_stmt->filenames_sorted = false; ++ new_stmt->any_specs_sorted = any_specs_sorted; ++ new_stmt->section_flag_list = NULL; ++ new_stmt->exclude_name_list = NULL; ++ if (filespec != NULL) ++ { ++ new_stmt->filename = filespec->name; ++ new_stmt->filenames_sorted = filespec->sorted == by_name; ++ new_stmt->section_flag_list = filespec->section_flag_list; ++ new_stmt->exclude_name_list = filespec->exclude_name_list; ++ } ++ new_stmt->section_list = section_list; ++ new_stmt->keep_sections = keep_sections; ++ lang_list_init (&new_stmt->children); ++ lang_list_init (&new_stmt->matching_sections); ++ analyze_walk_wild_section_handler (new_stmt); ++ if (0) ++ { ++ printf ("wild %s(", new_stmt->filename ? new_stmt->filename : "*"); ++ for (curr = new_stmt->section_list; curr; curr = curr->next) ++ printf ("%s ", curr->spec.name ? curr->spec.name : "*"); ++ printf (")\n"); ++ } ++} ++ ++void ++lang_section_start (const char *name, etree_type *address, ++ const segment_type *segment) ++{ ++ lang_address_statement_type *ad; ++ ++ ad = new_stat (lang_address_statement, stat_ptr); ++ ad->section_name = name; ++ ad->address = address; ++ ad->segment = segment; ++} ++ ++/* Set the start symbol to NAME. CMDLINE is nonzero if this is called ++ because of a -e argument on the command line, or zero if this is ++ called by ENTRY in a linker script. Command line arguments take ++ precedence. */ ++ ++void ++lang_add_entry (const char *name, bool cmdline) ++{ ++ if (entry_symbol.name == NULL ++ || cmdline ++ || !entry_from_cmdline) ++ { ++ entry_symbol.name = name; ++ entry_from_cmdline = cmdline; ++ } ++} ++ ++/* Set the default start symbol to NAME. .em files should use this, ++ not lang_add_entry, to override the use of "start" if neither the ++ linker script nor the command line specifies an entry point. NAME ++ must be permanently allocated. */ ++void ++lang_default_entry (const char *name) ++{ ++ entry_symbol_default = name; ++} ++ ++void ++lang_add_target (const char *name) ++{ ++ lang_target_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_target_statement, stat_ptr); ++ new_stmt->target = name; ++} ++ ++void ++lang_add_map (const char *name) ++{ ++ while (*name) ++ { ++ switch (*name) ++ { ++ case 'F': ++ map_option_f = true; ++ break; ++ } ++ name++; ++ } ++} ++ ++void ++lang_add_fill (fill_type *fill) ++{ ++ lang_fill_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_fill_statement, stat_ptr); ++ new_stmt->fill = fill; ++} ++ ++void ++lang_add_data (int type, union etree_union *exp) ++{ ++ lang_data_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_data_statement, stat_ptr); ++ new_stmt->exp = exp; ++ new_stmt->type = type; ++} ++ ++void ++lang_add_string (const char *s) ++{ ++ bfd_vma len = strlen (s); ++ bfd_vma i; ++ bool escape = false; ++ ++ /* Add byte expressions until end of string. */ ++ for (i = 0 ; i < len; i++) ++ { ++ char c = *s++; ++ ++ if (escape) ++ { ++ switch (c) ++ { ++ default: ++ /* Ignore the escape. */ ++ break; ++ ++ case 'n': c = '\n'; break; ++ case 'r': c = '\r'; break; ++ case 't': c = '\t'; break; ++ ++ case '0': ++ case '1': ++ case '2': ++ case '3': ++ case '4': ++ case '5': ++ case '6': ++ case '7': ++ /* We have an octal number. */ ++ { ++ unsigned int value = c - '0'; ++ ++ c = *s; ++ if ((c >= '0') && (c <= '7')) ++ { ++ value <<= 3; ++ value += (c - '0'); ++ i++; ++ s++; ++ ++ c = *s; ++ if ((c >= '0') && (c <= '7')) ++ { ++ value <<= 3; ++ value += (c - '0'); ++ i++; ++ s++; ++ } ++ } ++ ++ if (value > 0xff) ++ { ++ /* octal: \777 is treated as '\077' + '7' */ ++ value >>= 3; ++ i--; ++ s--; ++ } ++ ++ c = value; ++ } ++ break; ++ } ++ ++ lang_add_data (BYTE, exp_intop (c)); ++ escape = false; ++ } ++ else ++ { ++ if (c == '\\') ++ escape = true; ++ else ++ lang_add_data (BYTE, exp_intop (c)); ++ } ++ } ++ ++ /* Remeber to terminate the string. */ ++ lang_add_data (BYTE, exp_intop (0)); ++} ++ ++/* Create a new reloc statement. RELOC is the BFD relocation type to ++ generate. HOWTO is the corresponding howto structure (we could ++ look this up, but the caller has already done so). SECTION is the ++ section to generate a reloc against, or NAME is the name of the ++ symbol to generate a reloc against. Exactly one of SECTION and ++ NAME must be NULL. ADDEND is an expression for the addend. */ ++ ++void ++lang_add_reloc (bfd_reloc_code_real_type reloc, ++ reloc_howto_type *howto, ++ asection *section, ++ const char *name, ++ union etree_union *addend) ++{ ++ lang_reloc_statement_type *p = new_stat (lang_reloc_statement, stat_ptr); ++ ++ p->reloc = reloc; ++ p->howto = howto; ++ p->section = section; ++ p->name = name; ++ p->addend_exp = addend; ++ ++ p->addend_value = 0; ++ p->output_section = NULL; ++ p->output_offset = 0; ++} ++ ++lang_assignment_statement_type * ++lang_add_assignment (etree_type *exp) ++{ ++ lang_assignment_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_assignment_statement, stat_ptr); ++ new_stmt->exp = exp; ++ return new_stmt; ++} ++ ++void ++lang_add_attribute (enum statement_enum attribute) ++{ ++ new_statement (attribute, sizeof (lang_statement_header_type), stat_ptr); ++} ++ ++void ++lang_startup (const char *name) ++{ ++ if (first_file->filename != NULL) ++ { ++ einfo (_("%F%P: multiple STARTUP files\n")); ++ } ++ first_file->filename = name; ++ first_file->local_sym_name = name; ++ first_file->flags.real = true; ++} ++ ++void ++lang_float (bool maybe) ++{ ++ lang_float_flag = maybe; ++} ++ ++ ++/* Work out the load- and run-time regions from a script statement, and ++ store them in *LMA_REGION and *REGION respectively. ++ ++ MEMSPEC is the name of the run-time region, or the value of ++ DEFAULT_MEMORY_REGION if the statement didn't specify one. ++ LMA_MEMSPEC is the name of the load-time region, or null if the ++ statement didn't specify one.HAVE_LMA_P is TRUE if the statement ++ had an explicit load address. ++ ++ It is an error to specify both a load region and a load address. */ ++ ++static void ++lang_get_regions (lang_memory_region_type **region, ++ lang_memory_region_type **lma_region, ++ const char *memspec, ++ const char *lma_memspec, ++ bool have_lma, ++ bool have_vma) ++{ ++ *lma_region = lang_memory_region_lookup (lma_memspec, false); ++ ++ /* If no runtime region or VMA has been specified, but the load region ++ has been specified, then use the load region for the runtime region ++ as well. */ ++ if (lma_memspec != NULL ++ && !have_vma ++ && strcmp (memspec, DEFAULT_MEMORY_REGION) == 0) ++ *region = *lma_region; ++ else ++ *region = lang_memory_region_lookup (memspec, false); ++ ++ if (have_lma && lma_memspec != 0) ++ einfo (_("%X%P:%pS: section has both a load address and a load region\n"), ++ NULL); ++} ++ ++void ++lang_leave_output_section_statement (fill_type *fill, const char *memspec, ++ lang_output_section_phdr_list *phdrs, ++ const char *lma_memspec) ++{ ++ lang_get_regions (¤t_section->region, ++ ¤t_section->lma_region, ++ memspec, lma_memspec, ++ current_section->load_base != NULL, ++ current_section->addr_tree != NULL); ++ ++ current_section->fill = fill; ++ current_section->phdrs = phdrs; ++ pop_stat_ptr (); ++} ++ ++/* Set the output format type. -oformat overrides scripts. */ ++ ++void ++lang_add_output_format (const char *format, ++ const char *big, ++ const char *little, ++ int from_script) ++{ ++ if (output_target == NULL || !from_script) ++ { ++ if (command_line.endian == ENDIAN_BIG ++ && big != NULL) ++ format = big; ++ else if (command_line.endian == ENDIAN_LITTLE ++ && little != NULL) ++ format = little; ++ ++ output_target = format; ++ } ++} ++ ++void ++lang_add_insert (const char *where, int is_before) ++{ ++ lang_insert_statement_type *new_stmt; ++ ++ new_stmt = new_stat (lang_insert_statement, stat_ptr); ++ new_stmt->where = where; ++ new_stmt->is_before = is_before; ++ saved_script_handle = previous_script_handle; ++} ++ ++/* Enter a group. This creates a new lang_group_statement, and sets ++ stat_ptr to build new statements within the group. */ ++ ++void ++lang_enter_group (void) ++{ ++ lang_group_statement_type *g; ++ ++ g = new_stat (lang_group_statement, stat_ptr); ++ lang_list_init (&g->children); ++ push_stat_ptr (&g->children); ++} ++ ++/* Leave a group. This just resets stat_ptr to start writing to the ++ regular list of statements again. Note that this will not work if ++ groups can occur inside anything else which can adjust stat_ptr, ++ but currently they can't. */ ++ ++void ++lang_leave_group (void) ++{ ++ pop_stat_ptr (); ++} ++ ++/* Add a new program header. This is called for each entry in a PHDRS ++ command in a linker script. */ ++ ++void ++lang_new_phdr (const char *name, ++ etree_type *type, ++ bool filehdr, ++ bool phdrs, ++ etree_type *at, ++ etree_type *flags) ++{ ++ struct lang_phdr *n, **pp; ++ bool hdrs; ++ ++ n = stat_alloc (sizeof (struct lang_phdr)); ++ n->next = NULL; ++ n->name = name; ++ n->type = exp_get_vma (type, 0, "program header type"); ++ n->filehdr = filehdr; ++ n->phdrs = phdrs; ++ n->at = at; ++ n->flags = flags; ++ ++ hdrs = n->type == 1 && (phdrs || filehdr); ++ ++ for (pp = &lang_phdr_list; *pp != NULL; pp = &(*pp)->next) ++ if (hdrs ++ && (*pp)->type == 1 ++ && !((*pp)->filehdr || (*pp)->phdrs)) ++ { ++ einfo (_("%X%P:%pS: PHDRS and FILEHDR are not supported" ++ " when prior PT_LOAD headers lack them\n"), NULL); ++ hdrs = false; ++ } ++ ++ *pp = n; ++} ++ ++/* Record the program header information in the output BFD. FIXME: We ++ should not be calling an ELF specific function here. */ ++ ++static void ++lang_record_phdrs (void) ++{ ++ unsigned int alc; ++ asection **secs; ++ lang_output_section_phdr_list *last; ++ struct lang_phdr *l; ++ lang_output_section_statement_type *os; ++ ++ alc = 10; ++ secs = (asection **) xmalloc (alc * sizeof (asection *)); ++ last = NULL; ++ ++ for (l = lang_phdr_list; l != NULL; l = l->next) ++ { ++ unsigned int c; ++ flagword flags; ++ bfd_vma at; ++ ++ c = 0; ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ lang_output_section_phdr_list *pl; ++ ++ if (os->constraint < 0) ++ continue; ++ ++ pl = os->phdrs; ++ if (pl != NULL) ++ last = pl; ++ else ++ { ++ if (os->sectype == noload_section ++ || os->bfd_section == NULL ++ || (os->bfd_section->flags & SEC_ALLOC) == 0) ++ continue; ++ ++ /* Don't add orphans to PT_INTERP header. */ ++ if (l->type == 3) ++ continue; ++ ++ if (last == NULL) ++ { ++ lang_output_section_statement_type *tmp_os; ++ ++ /* If we have not run across a section with a program ++ header assigned to it yet, then scan forwards to find ++ one. This prevents inconsistencies in the linker's ++ behaviour when a script has specified just a single ++ header and there are sections in that script which are ++ not assigned to it, and which occur before the first ++ use of that header. See here for more details: ++ http://sourceware.org/ml/binutils/2007-02/msg00291.html */ ++ for (tmp_os = os; tmp_os; tmp_os = tmp_os->next) ++ if (tmp_os->phdrs) ++ { ++ last = tmp_os->phdrs; ++ break; ++ } ++ if (last == NULL) ++ einfo (_("%F%P: no sections assigned to phdrs\n")); ++ } ++ pl = last; ++ } ++ ++ if (os->bfd_section == NULL) ++ continue; ++ ++ for (; pl != NULL; pl = pl->next) ++ { ++ if (strcmp (pl->name, l->name) == 0) ++ { ++ if (c >= alc) ++ { ++ alc *= 2; ++ secs = (asection **) xrealloc (secs, ++ alc * sizeof (asection *)); ++ } ++ secs[c] = os->bfd_section; ++ ++c; ++ pl->used = true; ++ } ++ } ++ } ++ ++ if (l->flags == NULL) ++ flags = 0; ++ else ++ flags = exp_get_vma (l->flags, 0, "phdr flags"); ++ ++ if (l->at == NULL) ++ at = 0; ++ else ++ at = exp_get_vma (l->at, 0, "phdr load address"); ++ ++ if (!bfd_record_phdr (link_info.output_bfd, l->type, ++ l->flags != NULL, flags, l->at != NULL, ++ at, l->filehdr, l->phdrs, c, secs)) ++ einfo (_("%F%P: bfd_record_phdr failed: %E\n")); ++ } ++ ++ free (secs); ++ ++ /* Make sure all the phdr assignments succeeded. */ ++ for (os = (void *) lang_os_list.head; ++ os != NULL; ++ os = os->next) ++ { ++ lang_output_section_phdr_list *pl; ++ ++ if (os->constraint < 0 ++ || os->bfd_section == NULL) ++ continue; ++ ++ for (pl = os->phdrs; ++ pl != NULL; ++ pl = pl->next) ++ if (!pl->used && strcmp (pl->name, "NONE") != 0) ++ einfo (_("%X%P: section `%s' assigned to non-existent phdr `%s'\n"), ++ os->name, pl->name); ++ } ++} ++ ++/* Record a list of sections which may not be cross referenced. */ ++ ++void ++lang_add_nocrossref (lang_nocrossref_type *l) ++{ ++ struct lang_nocrossrefs *n; ++ ++ n = (struct lang_nocrossrefs *) xmalloc (sizeof *n); ++ n->next = nocrossref_list; ++ n->list = l; ++ n->onlyfirst = false; ++ nocrossref_list = n; ++ ++ /* Set notice_all so that we get informed about all symbols. */ ++ link_info.notice_all = true; ++} ++ ++/* Record a section that cannot be referenced from a list of sections. */ ++ ++void ++lang_add_nocrossref_to (lang_nocrossref_type *l) ++{ ++ lang_add_nocrossref (l); ++ nocrossref_list->onlyfirst = true; ++} ++ ++/* Overlay handling. We handle overlays with some static variables. */ ++ ++/* The overlay virtual address. */ ++static etree_type *overlay_vma; ++/* And subsection alignment. */ ++static etree_type *overlay_subalign; ++ ++/* An expression for the maximum section size seen so far. */ ++static etree_type *overlay_max; ++ ++/* A list of all the sections in this overlay. */ ++ ++struct overlay_list { ++ struct overlay_list *next; ++ lang_output_section_statement_type *os; ++}; ++ ++static struct overlay_list *overlay_list; ++ ++/* Start handling an overlay. */ ++ ++void ++lang_enter_overlay (etree_type *vma_expr, etree_type *subalign) ++{ ++ /* The grammar should prevent nested overlays from occurring. */ ++ ASSERT (overlay_vma == NULL ++ && overlay_subalign == NULL ++ && overlay_max == NULL); ++ ++ overlay_vma = vma_expr; ++ overlay_subalign = subalign; ++} ++ ++/* Start a section in an overlay. We handle this by calling ++ lang_enter_output_section_statement with the correct VMA. ++ lang_leave_overlay sets up the LMA and memory regions. */ ++ ++void ++lang_enter_overlay_section (const char *name) ++{ ++ struct overlay_list *n; ++ etree_type *size; ++ ++ lang_enter_output_section_statement (name, overlay_vma, overlay_section, ++ 0, 0, overlay_subalign, 0, 0, 0); ++ ++ /* If this is the first section, then base the VMA of future ++ sections on this one. This will work correctly even if `.' is ++ used in the addresses. */ ++ if (overlay_list == NULL) ++ overlay_vma = exp_nameop (ADDR, name); ++ ++ /* Remember the section. */ ++ n = (struct overlay_list *) xmalloc (sizeof *n); ++ n->os = current_section; ++ n->next = overlay_list; ++ overlay_list = n; ++ ++ size = exp_nameop (SIZEOF, name); ++ ++ /* Arrange to work out the maximum section end address. */ ++ if (overlay_max == NULL) ++ overlay_max = size; ++ else ++ overlay_max = exp_binop (MAX_K, overlay_max, size); ++} ++ ++/* Finish a section in an overlay. There isn't any special to do ++ here. */ ++ ++void ++lang_leave_overlay_section (fill_type *fill, ++ lang_output_section_phdr_list *phdrs) ++{ ++ const char *name; ++ char *clean, *s2; ++ const char *s1; ++ char *buf; ++ ++ name = current_section->name; ++ ++ /* For now, assume that DEFAULT_MEMORY_REGION is the run-time memory ++ region and that no load-time region has been specified. It doesn't ++ really matter what we say here, since lang_leave_overlay will ++ override it. */ ++ lang_leave_output_section_statement (fill, DEFAULT_MEMORY_REGION, phdrs, 0); ++ ++ /* Define the magic symbols. */ ++ ++ clean = (char *) xmalloc (strlen (name) + 1); ++ s2 = clean; ++ for (s1 = name; *s1 != '\0'; s1++) ++ if (ISALNUM (*s1) || *s1 == '_') ++ *s2++ = *s1; ++ *s2 = '\0'; ++ ++ buf = (char *) xmalloc (strlen (clean) + sizeof "__load_start_"); ++ sprintf (buf, "__load_start_%s", clean); ++ lang_add_assignment (exp_provide (buf, ++ exp_nameop (LOADADDR, name), ++ false)); ++ ++ buf = (char *) xmalloc (strlen (clean) + sizeof "__load_stop_"); ++ sprintf (buf, "__load_stop_%s", clean); ++ lang_add_assignment (exp_provide (buf, ++ exp_binop ('+', ++ exp_nameop (LOADADDR, name), ++ exp_nameop (SIZEOF, name)), ++ false)); ++ ++ free (clean); ++} ++ ++/* Finish an overlay. If there are any overlay wide settings, this ++ looks through all the sections in the overlay and sets them. */ ++ ++void ++lang_leave_overlay (etree_type *lma_expr, ++ int nocrossrefs, ++ fill_type *fill, ++ const char *memspec, ++ lang_output_section_phdr_list *phdrs, ++ const char *lma_memspec) ++{ ++ lang_memory_region_type *region; ++ lang_memory_region_type *lma_region; ++ struct overlay_list *l; ++ lang_nocrossref_type *nocrossref; ++ ++ lang_get_regions (®ion, &lma_region, ++ memspec, lma_memspec, ++ lma_expr != NULL, false); ++ ++ nocrossref = NULL; ++ ++ /* After setting the size of the last section, set '.' to end of the ++ overlay region. */ ++ if (overlay_list != NULL) ++ { ++ overlay_list->os->update_dot = 1; ++ overlay_list->os->update_dot_tree ++ = exp_assign (".", exp_binop ('+', overlay_vma, overlay_max), false); ++ } ++ ++ l = overlay_list; ++ while (l != NULL) ++ { ++ struct overlay_list *next; ++ ++ if (fill != NULL && l->os->fill == NULL) ++ l->os->fill = fill; ++ ++ l->os->region = region; ++ l->os->lma_region = lma_region; ++ ++ /* The first section has the load address specified in the ++ OVERLAY statement. The rest are worked out from that. ++ The base address is not needed (and should be null) if ++ an LMA region was specified. */ ++ if (l->next == 0) ++ { ++ l->os->load_base = lma_expr; ++ l->os->sectype = first_overlay_section; ++ } ++ if (phdrs != NULL && l->os->phdrs == NULL) ++ l->os->phdrs = phdrs; ++ ++ if (nocrossrefs) ++ { ++ lang_nocrossref_type *nc; ++ ++ nc = (lang_nocrossref_type *) xmalloc (sizeof *nc); ++ nc->name = l->os->name; ++ nc->next = nocrossref; ++ nocrossref = nc; ++ } ++ ++ next = l->next; ++ free (l); ++ l = next; ++ } ++ ++ if (nocrossref != NULL) ++ lang_add_nocrossref (nocrossref); ++ ++ overlay_vma = NULL; ++ overlay_list = NULL; ++ overlay_max = NULL; ++ overlay_subalign = NULL; ++} ++ ++/* Version handling. This is only useful for ELF. */ ++ ++/* If PREV is NULL, return first version pattern matching particular symbol. ++ If PREV is non-NULL, return first version pattern matching particular ++ symbol after PREV (previously returned by lang_vers_match). */ ++ ++static struct bfd_elf_version_expr * ++lang_vers_match (struct bfd_elf_version_expr_head *head, ++ struct bfd_elf_version_expr *prev, ++ const char *sym) ++{ ++ const char *c_sym; ++ const char *cxx_sym = sym; ++ const char *java_sym = sym; ++ struct bfd_elf_version_expr *expr = NULL; ++ enum demangling_styles curr_style; ++ ++ curr_style = CURRENT_DEMANGLING_STYLE; ++ cplus_demangle_set_style (no_demangling); ++ c_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_NO_OPTS); ++ if (!c_sym) ++ c_sym = sym; ++ cplus_demangle_set_style (curr_style); ++ ++ if (head->mask & BFD_ELF_VERSION_CXX_TYPE) ++ { ++ cxx_sym = bfd_demangle (link_info.output_bfd, sym, ++ DMGL_PARAMS | DMGL_ANSI); ++ if (!cxx_sym) ++ cxx_sym = sym; ++ } ++ if (head->mask & BFD_ELF_VERSION_JAVA_TYPE) ++ { ++ java_sym = bfd_demangle (link_info.output_bfd, sym, DMGL_JAVA); ++ if (!java_sym) ++ java_sym = sym; ++ } ++ ++ if (head->htab && (prev == NULL || prev->literal)) ++ { ++ struct bfd_elf_version_expr e; ++ ++ switch (prev ? prev->mask : 0) ++ { ++ case 0: ++ if (head->mask & BFD_ELF_VERSION_C_TYPE) ++ { ++ e.pattern = c_sym; ++ expr = (struct bfd_elf_version_expr *) ++ htab_find ((htab_t) head->htab, &e); ++ while (expr && strcmp (expr->pattern, c_sym) == 0) ++ if (expr->mask == BFD_ELF_VERSION_C_TYPE) ++ goto out_ret; ++ else ++ expr = expr->next; ++ } ++ /* Fallthrough */ ++ case BFD_ELF_VERSION_C_TYPE: ++ if (head->mask & BFD_ELF_VERSION_CXX_TYPE) ++ { ++ e.pattern = cxx_sym; ++ expr = (struct bfd_elf_version_expr *) ++ htab_find ((htab_t) head->htab, &e); ++ while (expr && strcmp (expr->pattern, cxx_sym) == 0) ++ if (expr->mask == BFD_ELF_VERSION_CXX_TYPE) ++ goto out_ret; ++ else ++ expr = expr->next; ++ } ++ /* Fallthrough */ ++ case BFD_ELF_VERSION_CXX_TYPE: ++ if (head->mask & BFD_ELF_VERSION_JAVA_TYPE) ++ { ++ e.pattern = java_sym; ++ expr = (struct bfd_elf_version_expr *) ++ htab_find ((htab_t) head->htab, &e); ++ while (expr && strcmp (expr->pattern, java_sym) == 0) ++ if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE) ++ goto out_ret; ++ else ++ expr = expr->next; ++ } ++ /* Fallthrough */ ++ default: ++ break; ++ } ++ } ++ ++ /* Finally, try the wildcards. */ ++ if (prev == NULL || prev->literal) ++ expr = head->remaining; ++ else ++ expr = prev->next; ++ for (; expr; expr = expr->next) ++ { ++ const char *s; ++ ++ if (!expr->pattern) ++ continue; ++ ++ if (expr->pattern[0] == '*' && expr->pattern[1] == '\0') ++ break; ++ ++ if (expr->mask == BFD_ELF_VERSION_JAVA_TYPE) ++ s = java_sym; ++ else if (expr->mask == BFD_ELF_VERSION_CXX_TYPE) ++ s = cxx_sym; ++ else ++ s = c_sym; ++ if (fnmatch (expr->pattern, s, 0) == 0) ++ break; ++ } ++ ++ out_ret: ++ if (c_sym != sym) ++ free ((char *) c_sym); ++ if (cxx_sym != sym) ++ free ((char *) cxx_sym); ++ if (java_sym != sym) ++ free ((char *) java_sym); ++ return expr; ++} ++ ++/* Return NULL if the PATTERN argument is a glob pattern, otherwise, ++ return a pointer to the symbol name with any backslash quotes removed. */ ++ ++static const char * ++realsymbol (const char *pattern) ++{ ++ const char *p; ++ bool changed = false, backslash = false; ++ char *s, *symbol = (char *) xmalloc (strlen (pattern) + 1); ++ ++ for (p = pattern, s = symbol; *p != '\0'; ++p) ++ { ++ /* It is a glob pattern only if there is no preceding ++ backslash. */ ++ if (backslash) ++ { ++ /* Remove the preceding backslash. */ ++ *(s - 1) = *p; ++ backslash = false; ++ changed = true; ++ } ++ else ++ { ++ if (*p == '?' || *p == '*' || *p == '[') ++ { ++ free (symbol); ++ return NULL; ++ } ++ ++ *s++ = *p; ++ backslash = *p == '\\'; ++ } ++ } ++ ++ if (changed) ++ { ++ *s = '\0'; ++ return symbol; ++ } ++ else ++ { ++ free (symbol); ++ return pattern; ++ } ++} ++ ++/* This is called for each variable name or match expression. NEW_NAME is ++ the name of the symbol to match, or, if LITERAL_P is FALSE, a glob ++ pattern to be matched against symbol names. */ ++ ++struct bfd_elf_version_expr * ++lang_new_vers_pattern (struct bfd_elf_version_expr *orig, ++ const char *new_name, ++ const char *lang, ++ bool literal_p) ++{ ++ struct bfd_elf_version_expr *ret; ++ ++ ret = (struct bfd_elf_version_expr *) xmalloc (sizeof *ret); ++ ret->next = orig; ++ ret->symver = 0; ++ ret->script = 0; ++ ret->literal = true; ++ ret->pattern = literal_p ? new_name : realsymbol (new_name); ++ if (ret->pattern == NULL) ++ { ++ ret->pattern = new_name; ++ ret->literal = false; ++ } ++ ++ if (lang == NULL || strcasecmp (lang, "C") == 0) ++ ret->mask = BFD_ELF_VERSION_C_TYPE; ++ else if (strcasecmp (lang, "C++") == 0) ++ ret->mask = BFD_ELF_VERSION_CXX_TYPE; ++ else if (strcasecmp (lang, "Java") == 0) ++ ret->mask = BFD_ELF_VERSION_JAVA_TYPE; ++ else ++ { ++ einfo (_("%X%P: unknown language `%s' in version information\n"), ++ lang); ++ ret->mask = BFD_ELF_VERSION_C_TYPE; ++ } ++ ++ return ldemul_new_vers_pattern (ret); ++} ++ ++/* This is called for each set of variable names and match ++ expressions. */ ++ ++struct bfd_elf_version_tree * ++lang_new_vers_node (struct bfd_elf_version_expr *globals, ++ struct bfd_elf_version_expr *locals) ++{ ++ struct bfd_elf_version_tree *ret; ++ ++ ret = (struct bfd_elf_version_tree *) xcalloc (1, sizeof *ret); ++ ret->globals.list = globals; ++ ret->locals.list = locals; ++ ret->match = lang_vers_match; ++ ret->name_indx = (unsigned int) -1; ++ return ret; ++} ++ ++/* This static variable keeps track of version indices. */ ++ ++static int version_index; ++ ++static hashval_t ++version_expr_head_hash (const void *p) ++{ ++ const struct bfd_elf_version_expr *e = ++ (const struct bfd_elf_version_expr *) p; ++ ++ return htab_hash_string (e->pattern); ++} ++ ++static int ++version_expr_head_eq (const void *p1, const void *p2) ++{ ++ const struct bfd_elf_version_expr *e1 = ++ (const struct bfd_elf_version_expr *) p1; ++ const struct bfd_elf_version_expr *e2 = ++ (const struct bfd_elf_version_expr *) p2; ++ ++ return strcmp (e1->pattern, e2->pattern) == 0; ++} ++ ++static void ++lang_finalize_version_expr_head (struct bfd_elf_version_expr_head *head) ++{ ++ size_t count = 0; ++ struct bfd_elf_version_expr *e, *next; ++ struct bfd_elf_version_expr **list_loc, **remaining_loc; ++ ++ for (e = head->list; e; e = e->next) ++ { ++ if (e->literal) ++ count++; ++ head->mask |= e->mask; ++ } ++ ++ if (count) ++ { ++ head->htab = htab_create (count * 2, version_expr_head_hash, ++ version_expr_head_eq, NULL); ++ list_loc = &head->list; ++ remaining_loc = &head->remaining; ++ for (e = head->list; e; e = next) ++ { ++ next = e->next; ++ if (!e->literal) ++ { ++ *remaining_loc = e; ++ remaining_loc = &e->next; ++ } ++ else ++ { ++ void **loc = htab_find_slot ((htab_t) head->htab, e, INSERT); ++ ++ if (*loc) ++ { ++ struct bfd_elf_version_expr *e1, *last; ++ ++ e1 = (struct bfd_elf_version_expr *) *loc; ++ last = NULL; ++ do ++ { ++ if (e1->mask == e->mask) ++ { ++ last = NULL; ++ break; ++ } ++ last = e1; ++ e1 = e1->next; ++ } ++ while (e1 && strcmp (e1->pattern, e->pattern) == 0); ++ ++ if (last == NULL) ++ { ++ /* This is a duplicate. */ ++ /* FIXME: Memory leak. Sometimes pattern is not ++ xmalloced alone, but in larger chunk of memory. */ ++ /* free (e->pattern); */ ++ free (e); ++ } ++ else ++ { ++ e->next = last->next; ++ last->next = e; ++ } ++ } ++ else ++ { ++ *loc = e; ++ *list_loc = e; ++ list_loc = &e->next; ++ } ++ } ++ } ++ *remaining_loc = NULL; ++ *list_loc = head->remaining; ++ } ++ else ++ head->remaining = head->list; ++} ++ ++/* This is called when we know the name and dependencies of the ++ version. */ ++ ++void ++lang_register_vers_node (const char *name, ++ struct bfd_elf_version_tree *version, ++ struct bfd_elf_version_deps *deps) ++{ ++ struct bfd_elf_version_tree *t, **pp; ++ struct bfd_elf_version_expr *e1; ++ ++ if (name == NULL) ++ name = ""; ++ ++ if (link_info.version_info != NULL ++ && (name[0] == '\0' || link_info.version_info->name[0] == '\0')) ++ { ++ einfo (_("%X%P: anonymous version tag cannot be combined" ++ " with other version tags\n")); ++ free (version); ++ return; ++ } ++ ++ /* Make sure this node has a unique name. */ ++ for (t = link_info.version_info; t != NULL; t = t->next) ++ if (strcmp (t->name, name) == 0) ++ einfo (_("%X%P: duplicate version tag `%s'\n"), name); ++ ++ lang_finalize_version_expr_head (&version->globals); ++ lang_finalize_version_expr_head (&version->locals); ++ ++ /* Check the global and local match names, and make sure there ++ aren't any duplicates. */ ++ ++ for (e1 = version->globals.list; e1 != NULL; e1 = e1->next) ++ { ++ for (t = link_info.version_info; t != NULL; t = t->next) ++ { ++ struct bfd_elf_version_expr *e2; ++ ++ if (t->locals.htab && e1->literal) ++ { ++ e2 = (struct bfd_elf_version_expr *) ++ htab_find ((htab_t) t->locals.htab, e1); ++ while (e2 && strcmp (e1->pattern, e2->pattern) == 0) ++ { ++ if (e1->mask == e2->mask) ++ einfo (_("%X%P: duplicate expression `%s'" ++ " in version information\n"), e1->pattern); ++ e2 = e2->next; ++ } ++ } ++ else if (!e1->literal) ++ for (e2 = t->locals.remaining; e2 != NULL; e2 = e2->next) ++ if (strcmp (e1->pattern, e2->pattern) == 0 ++ && e1->mask == e2->mask) ++ einfo (_("%X%P: duplicate expression `%s'" ++ " in version information\n"), e1->pattern); ++ } ++ } ++ ++ for (e1 = version->locals.list; e1 != NULL; e1 = e1->next) ++ { ++ for (t = link_info.version_info; t != NULL; t = t->next) ++ { ++ struct bfd_elf_version_expr *e2; ++ ++ if (t->globals.htab && e1->literal) ++ { ++ e2 = (struct bfd_elf_version_expr *) ++ htab_find ((htab_t) t->globals.htab, e1); ++ while (e2 && strcmp (e1->pattern, e2->pattern) == 0) ++ { ++ if (e1->mask == e2->mask) ++ einfo (_("%X%P: duplicate expression `%s'" ++ " in version information\n"), ++ e1->pattern); ++ e2 = e2->next; ++ } ++ } ++ else if (!e1->literal) ++ for (e2 = t->globals.remaining; e2 != NULL; e2 = e2->next) ++ if (strcmp (e1->pattern, e2->pattern) == 0 ++ && e1->mask == e2->mask) ++ einfo (_("%X%P: duplicate expression `%s'" ++ " in version information\n"), e1->pattern); ++ } ++ } ++ ++ version->deps = deps; ++ version->name = name; ++ if (name[0] != '\0') ++ { ++ ++version_index; ++ version->vernum = version_index; ++ } ++ else ++ version->vernum = 0; ++ ++ for (pp = &link_info.version_info; *pp != NULL; pp = &(*pp)->next) ++ ; ++ *pp = version; ++} ++ ++/* This is called when we see a version dependency. */ ++ ++struct bfd_elf_version_deps * ++lang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name) ++{ ++ struct bfd_elf_version_deps *ret; ++ struct bfd_elf_version_tree *t; ++ ++ ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret); ++ ret->next = list; ++ ++ for (t = link_info.version_info; t != NULL; t = t->next) ++ { ++ if (strcmp (t->name, name) == 0) ++ { ++ ret->version_needed = t; ++ return ret; ++ } ++ } ++ ++ einfo (_("%X%P: unable to find version dependency `%s'\n"), name); ++ ++ ret->version_needed = NULL; ++ return ret; ++} ++ ++static void ++lang_do_version_exports_section (void) ++{ ++ struct bfd_elf_version_expr *greg = NULL, *lreg; ++ ++ LANG_FOR_EACH_INPUT_STATEMENT (is) ++ { ++ asection *sec = bfd_get_section_by_name (is->the_bfd, ".exports"); ++ char *contents, *p; ++ bfd_size_type len; ++ ++ if (sec == NULL) ++ continue; ++ ++ len = sec->size; ++ contents = (char *) xmalloc (len); ++ if (!bfd_get_section_contents (is->the_bfd, sec, contents, 0, len)) ++ einfo (_("%X%P: unable to read .exports section contents\n"), sec); ++ ++ p = contents; ++ while (p < contents + len) ++ { ++ greg = lang_new_vers_pattern (greg, p, NULL, false); ++ p = strchr (p, '\0') + 1; ++ } ++ ++ /* Do not free the contents, as we used them creating the regex. */ ++ ++ /* Do not include this section in the link. */ ++ sec->flags |= SEC_EXCLUDE | SEC_KEEP; ++ } ++ ++ lreg = lang_new_vers_pattern (NULL, "*", NULL, false); ++ lang_register_vers_node (command_line.version_exports_section, ++ lang_new_vers_node (greg, lreg), NULL); ++} ++ ++/* Evaluate LENGTH and ORIGIN parts of MEMORY spec. This is initially ++ called with UPDATE_REGIONS_P set to FALSE, in this case no errors are ++ thrown, however, references to symbols in the origin and length fields ++ will be pushed into the symbol table, this allows PROVIDE statements to ++ then provide these symbols. This function is called a second time with ++ UPDATE_REGIONS_P set to TRUE, this time the we update the actual region ++ data structures, and throw errors if missing symbols are encountered. */ ++ ++static void ++lang_do_memory_regions (bool update_regions_p) ++{ ++ lang_memory_region_type *r = lang_memory_region_list; ++ ++ for (; r != NULL; r = r->next) ++ { ++ if (r->origin_exp) ++ { ++ exp_fold_tree_no_dot (r->origin_exp); ++ if (update_regions_p) ++ { ++ if (expld.result.valid_p) ++ { ++ r->origin = expld.result.value; ++ r->current = r->origin; ++ } ++ else ++ einfo (_("%P: invalid origin for memory region %s\n"), ++ r->name_list.name); ++ } ++ } ++ if (r->length_exp) ++ { ++ exp_fold_tree_no_dot (r->length_exp); ++ if (update_regions_p) ++ { ++ if (expld.result.valid_p) ++ r->length = expld.result.value; ++ else ++ einfo (_("%P: invalid length for memory region %s\n"), ++ r->name_list.name); ++ } ++ } ++ } ++} ++ ++void ++lang_add_unique (const char *name) ++{ ++ struct unique_sections *ent; ++ ++ for (ent = unique_section_list; ent; ent = ent->next) ++ if (strcmp (ent->name, name) == 0) ++ return; ++ ++ ent = (struct unique_sections *) xmalloc (sizeof *ent); ++ ent->name = xstrdup (name); ++ ent->next = unique_section_list; ++ unique_section_list = ent; ++} ++ ++/* Append the list of dynamic symbols to the existing one. */ ++ ++void ++lang_append_dynamic_list (struct bfd_elf_dynamic_list **list_p, ++ struct bfd_elf_version_expr *dynamic) ++{ ++ if (*list_p) ++ { ++ struct bfd_elf_version_expr *tail; ++ for (tail = dynamic; tail->next != NULL; tail = tail->next) ++ ; ++ tail->next = (*list_p)->head.list; ++ (*list_p)->head.list = dynamic; ++ } ++ else ++ { ++ struct bfd_elf_dynamic_list *d; ++ ++ d = (struct bfd_elf_dynamic_list *) xcalloc (1, sizeof *d); ++ d->head.list = dynamic; ++ d->match = lang_vers_match; ++ *list_p = d; ++ } ++} ++ ++/* Append the list of C++ typeinfo dynamic symbols to the existing ++ one. */ ++ ++void ++lang_append_dynamic_list_cpp_typeinfo (void) ++{ ++ const char *symbols[] = ++ { ++ "typeinfo name for*", ++ "typeinfo for*" ++ }; ++ struct bfd_elf_version_expr *dynamic = NULL; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE (symbols); i++) ++ dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++", ++ false); ++ ++ lang_append_dynamic_list (&link_info.dynamic_list, dynamic); ++} ++ ++/* Append the list of C++ operator new and delete dynamic symbols to the ++ existing one. */ ++ ++void ++lang_append_dynamic_list_cpp_new (void) ++{ ++ const char *symbols[] = ++ { ++ "operator new*", ++ "operator delete*" ++ }; ++ struct bfd_elf_version_expr *dynamic = NULL; ++ unsigned int i; ++ ++ for (i = 0; i < ARRAY_SIZE (symbols); i++) ++ dynamic = lang_new_vers_pattern (dynamic, symbols [i], "C++", ++ false); ++ ++ lang_append_dynamic_list (&link_info.dynamic_list, dynamic); ++} ++ ++/* Scan a space and/or comma separated string of features. */ ++ ++void ++lang_ld_feature (char *str) ++{ ++ char *p, *q; ++ ++ p = str; ++ while (*p) ++ { ++ char sep; ++ while (*p == ',' || ISSPACE (*p)) ++ ++p; ++ if (!*p) ++ break; ++ q = p + 1; ++ while (*q && *q != ',' && !ISSPACE (*q)) ++ ++q; ++ sep = *q; ++ *q = 0; ++ if (strcasecmp (p, "SANE_EXPR") == 0) ++ config.sane_expr = true; ++ else ++ einfo (_("%X%P: unknown feature `%s'\n"), p); ++ *q = sep; ++ p = q; ++ } ++} ++ ++/* Pretty print memory amount. */ ++ ++static void ++lang_print_memory_size (uint64_t sz) ++{ ++ if ((sz & 0x3fffffff) == 0) ++ printf ("%10" PRIu64 " GB", sz >> 30); ++ else if ((sz & 0xfffff) == 0) ++ printf ("%10" PRIu64 " MB", sz >> 20); ++ else if ((sz & 0x3ff) == 0) ++ printf ("%10" PRIu64 " KB", sz >> 10); ++ else ++ printf (" %10" PRIu64 " B", sz); ++} ++ ++/* Implement --print-memory-usage: disply per region memory usage. */ ++ ++void ++lang_print_memory_usage (void) ++{ ++ lang_memory_region_type *r; ++ ++ printf ("Memory region Used Size Region Size %%age Used\n"); ++ for (r = lang_memory_region_list; r->next != NULL; r = r->next) ++ { ++ bfd_vma used_length = r->current - r->origin; ++ ++ printf ("%16s: ",r->name_list.name); ++ lang_print_memory_size (used_length); ++ lang_print_memory_size (r->length); ++ ++ if (r->length != 0) ++ { ++ double percent = used_length * 100.0 / r->length; ++ printf (" %6.2f%%", percent); ++ } ++ printf ("\n"); ++ } ++} +diff -rupN binutils.orig/ld/ldlang.h binutils-2.41/ld/ldlang.h +--- binutils.orig/ld/ldlang.h 2024-05-13 13:03:47.804601777 +0100 ++++ binutils-2.41/ld/ldlang.h 2024-05-13 13:04:08.599633306 +0100 +@@ -141,7 +141,12 @@ typedef struct lang_output_section_phdr_ + typedef struct lang_output_section_statement_struct + { + lang_statement_header_type header; ++ /* Input sections to be mapped to this output section. */ + lang_statement_list_type children; ++ /* Input sections to be mapped to the start of this output section. ++ These sections are provided by the --section-ordering file, if used. */ ++ lang_statement_list_type sort_children; ++ + struct lang_output_section_statement_struct *next; + struct lang_output_section_statement_struct *prev; + const char *name; +diff -rupN binutils.orig/ld/ldlex.h binutils-2.41/ld/ldlex.h +--- binutils.orig/ld/ldlex.h 2024-05-13 13:03:48.141602288 +0100 ++++ binutils-2.41/ld/ldlex.h 2024-05-13 13:04:08.599633306 +0100 +@@ -62,6 +62,7 @@ enum option_values + OPTION_SONAME, + OPTION_SORT_COMMON, + OPTION_SORT_SECTION, ++ OPTION_SECTION_ORDERING_FILE, + OPTION_STATS, + OPTION_SYMBOLIC, + OPTION_SYMBOLIC_FUNCTIONS, +@@ -190,6 +191,7 @@ typedef enum input_enum + input_script, + input_mri_script, + input_version_script, ++ input_section_ordering_script, + input_dynamic_list, + input_defsym + } input_type; +diff -rupN binutils.orig/ld/ldlex.h.orig binutils-2.41/ld/ldlex.h.orig +--- binutils.orig/ld/ldlex.h.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/ldlex.h.orig 2024-05-13 13:03:25.176567468 +0100 +@@ -0,0 +1,222 @@ ++/* ldlex.h - ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#ifndef LDLEX_H ++#define LDLEX_H ++ ++#include ++ ++/* Codes used for the long options with no short synonyms. 150 isn't ++ special; it's just an arbitrary non-ASCII char value. */ ++enum option_values ++{ ++ OPTION_ASSERT = 150, ++ OPTION_CALL_SHARED, ++ OPTION_CREF, ++ OPTION_DEFSYM, ++ OPTION_DEMANGLE, ++ OPTION_DYNAMIC_LINKER, ++ OPTION_NO_DYNAMIC_LINKER, ++ OPTION_SYSROOT, ++ OPTION_OUT_IMPLIB, ++ OPTION_EB, ++ OPTION_EL, ++ OPTION_EMBEDDED_RELOCS, ++ OPTION_EXPORT_DYNAMIC, ++ OPTION_NO_EXPORT_DYNAMIC, ++ OPTION_HELP, ++ OPTION_IGNORE, ++ OPTION_MAP, ++ OPTION_NO_DEMANGLE, ++ OPTION_NO_KEEP_MEMORY, ++ OPTION_NO_WARN_MISMATCH, ++ OPTION_NO_WARN_SEARCH_MISMATCH, ++ OPTION_NOINHIBIT_EXEC, ++ OPTION_NON_SHARED, ++ OPTION_NO_WHOLE_ARCHIVE, ++ OPTION_OFORMAT, ++ OPTION_RELAX, ++ OPTION_NO_RELAX, ++ OPTION_NO_SYMBOLIC, ++ OPTION_RETAIN_SYMBOLS_FILE, ++ OPTION_RPATH, ++ OPTION_RPATH_LINK, ++ OPTION_SHARED, ++ OPTION_SONAME, ++ OPTION_SORT_COMMON, ++ OPTION_SORT_SECTION, ++ OPTION_STATS, ++ OPTION_SYMBOLIC, ++ OPTION_SYMBOLIC_FUNCTIONS, ++ OPTION_TASK_LINK, ++ OPTION_TBSS, ++ OPTION_TDATA, ++ OPTION_TTEXT, ++ OPTION_TTEXT_SEGMENT, ++ OPTION_TRODATA_SEGMENT, ++ OPTION_TLDATA_SEGMENT, ++ OPTION_TRADITIONAL_FORMAT, ++ OPTION_UR, ++ OPTION_VERBOSE, ++ OPTION_VERSION, ++ OPTION_VERSION_SCRIPT, ++ OPTION_VERSION_EXPORTS_SECTION, ++ OPTION_DYNAMIC_LIST, ++ OPTION_DYNAMIC_LIST_CPP_NEW, ++ OPTION_DYNAMIC_LIST_CPP_TYPEINFO, ++ OPTION_DYNAMIC_LIST_DATA, ++ OPTION_EXPORT_DYNAMIC_SYMBOL, ++ OPTION_EXPORT_DYNAMIC_SYMBOL_LIST, ++ OPTION_WARN_COMMON, ++ OPTION_WARN_CONSTRUCTORS, ++ OPTION_WARN_FATAL, ++ OPTION_NO_WARN_FATAL, ++ OPTION_NO_WARNINGS, ++ OPTION_WARN_MULTIPLE_GP, ++ OPTION_WARN_ONCE, ++ OPTION_WARN_SECTION_ALIGN, ++ OPTION_SPLIT_BY_RELOC, ++ OPTION_SPLIT_BY_FILE , ++ OPTION_WHOLE_ARCHIVE, ++ OPTION_ADD_DT_NEEDED_FOR_DYNAMIC, ++ OPTION_NO_ADD_DT_NEEDED_FOR_DYNAMIC, ++ OPTION_ADD_DT_NEEDED_FOR_REGULAR, ++ OPTION_NO_ADD_DT_NEEDED_FOR_REGULAR, ++ OPTION_WRAP, ++ OPTION_FORCE_EXE_SUFFIX, ++ OPTION_GC_SECTIONS, ++ OPTION_NO_GC_SECTIONS, ++ OPTION_PRINT_GC_SECTIONS, ++ OPTION_NO_PRINT_GC_SECTIONS, ++ OPTION_GC_KEEP_EXPORTED, ++ OPTION_HASH_SIZE, ++ OPTION_CHECK_SECTIONS, ++ OPTION_NO_CHECK_SECTIONS, ++ OPTION_NO_UNDEFINED, ++ OPTION_INIT, ++ OPTION_FINI, ++ OPTION_SECTION_START, ++ OPTION_UNIQUE, ++ OPTION_TARGET_HELP, ++ OPTION_ALLOW_SHLIB_UNDEFINED, ++ OPTION_NO_ALLOW_SHLIB_UNDEFINED, ++ OPTION_ALLOW_MULTIPLE_DEFINITION, ++#if SUPPORT_ERROR_HANDLING_SCRIPT ++ OPTION_ERROR_HANDLING_SCRIPT, ++#endif ++ OPTION_UNDEFINED_VERSION, ++ OPTION_NO_UNDEFINED_VERSION, ++ OPTION_DEFAULT_SYMVER, ++ OPTION_DEFAULT_IMPORTED_SYMVER, ++ OPTION_DISCARD_NONE, ++ OPTION_SPARE_DYNAMIC_TAGS, ++ OPTION_NO_DEFINE_COMMON, ++ OPTION_NOSTDLIB, ++ OPTION_NO_OMAGIC, ++ OPTION_STRIP_DISCARDED, ++ OPTION_NO_STRIP_DISCARDED, ++ OPTION_ACCEPT_UNKNOWN_INPUT_ARCH, ++ OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH, ++ OPTION_PIE, ++ OPTION_NO_PIE, ++ OPTION_UNRESOLVED_SYMBOLS, ++ OPTION_WARN_UNRESOLVED_SYMBOLS, ++ OPTION_ERROR_UNRESOLVED_SYMBOLS, ++ OPTION_WARN_TEXTREL, ++ OPTION_WARN_ALTERNATE_EM, ++ OPTION_REDUCE_MEMORY_OVERHEADS, ++ OPTION_MAX_CACHE_SIZE, ++#if BFD_SUPPORTS_PLUGINS ++ OPTION_PLUGIN, ++ OPTION_PLUGIN_OPT, ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ OPTION_DEFAULT_SCRIPT, ++ OPTION_PRINT_OUTPUT_FORMAT, ++ OPTION_PRINT_SYSROOT, ++ OPTION_IGNORE_UNRESOLVED_SYMBOL, ++ OPTION_PUSH_STATE, ++ OPTION_POP_STATE, ++ OPTION_DISABLE_MULTIPLE_DEFS_ABS, ++ OPTION_PRINT_MEMORY_USAGE, ++ OPTION_REQUIRE_DEFINED_SYMBOL, ++ OPTION_ORPHAN_HANDLING, ++ OPTION_FORCE_GROUP_ALLOCATION, ++ OPTION_PRINT_MAP_DISCARDED, ++ OPTION_NO_PRINT_MAP_DISCARDED, ++ OPTION_PRINT_MAP_LOCALS, ++ OPTION_NO_PRINT_MAP_LOCALS, ++ OPTION_NON_CONTIGUOUS_REGIONS, ++ OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS, ++ OPTION_DEPENDENCY_FILE, ++ OPTION_CTF_VARIABLES, ++ OPTION_NO_CTF_VARIABLES, ++ OPTION_CTF_SHARE_TYPES, ++ OPTION_ERROR_EXECSTACK, ++ OPTION_NO_ERROR_EXECSTACK, ++ OPTION_WARN_EXECSTACK_OBJECTS, ++ OPTION_WARN_EXECSTACK, ++ OPTION_NO_WARN_EXECSTACK, ++ OPTION_WARN_RWX_SEGMENTS, ++ OPTION_NO_WARN_RWX_SEGMENTS, ++ OPTION_ERROR_RWX_SEGMENTS, ++ OPTION_NO_ERROR_RWX_SEGMENTS, ++ OPTION_ENABLE_LINKER_VERSION, ++ OPTION_DISABLE_LINKER_VERSION, ++ OPTION_REMAP_INPUTS, ++ OPTION_REMAP_INPUTS_FILE, ++}; ++ ++/* The initial parser states. */ ++typedef enum input_enum ++{ ++ input_selected, /* We've set the initial state. */ ++ input_script, ++ input_mri_script, ++ input_version_script, ++ input_dynamic_list, ++ input_defsym ++} input_type; ++ ++extern input_type parser_input; ++ ++extern unsigned int lineno; ++extern const char *lex_string; ++ ++/* In ldlex.l. */ ++extern int yylex (void); ++extern void lex_push_file (FILE *, const char *, unsigned int); ++extern void lex_redirect (const char *, const char *, unsigned int); ++extern void ldlex_script (void); ++extern void ldlex_inputlist (void); ++extern void ldlex_mri_script (void); ++extern void ldlex_version_script (void); ++extern void ldlex_version_file (void); ++extern void ldlex_expression (void); ++extern void ldlex_wild (void); ++extern void ldlex_popstate (void); ++extern void ldlex_backup (void); ++extern const char* ldlex_filename (void); ++ ++/* In lexsup.c. */ ++extern int lex_input (void); ++extern void lex_unput (int); ++extern void parse_args (unsigned, char **); ++ ++#endif +diff -rupN binutils.orig/ld/ldlex.l binutils-2.41/ld/ldlex.l +--- binutils.orig/ld/ldlex.l 2024-05-13 13:03:47.805601779 +0100 ++++ binutils-2.41/ld/ldlex.l 2024-05-13 13:04:08.599633306 +0100 +@@ -120,11 +120,12 @@ V_IDENTIFIER [*?.$_a-zA-Z\[\]\-\!\^\\]([ + parser_input = input_selected; + switch (t) + { +- case input_script: return INPUT_SCRIPT; break; +- case input_mri_script: return INPUT_MRI_SCRIPT; break; +- case input_version_script: return INPUT_VERSION_SCRIPT; break; +- case input_dynamic_list: return INPUT_DYNAMIC_LIST; break; +- case input_defsym: return INPUT_DEFSYM; break; ++ case input_script: return INPUT_SCRIPT; ++ case input_mri_script: return INPUT_MRI_SCRIPT; ++ case input_version_script: return INPUT_VERSION_SCRIPT; ++ case input_section_ordering_script: return INPUT_SECTION_ORDERING_SCRIPT; ++ case input_dynamic_list: return INPUT_DYNAMIC_LIST; ++ case input_defsym: return INPUT_DEFSYM; + default: abort (); + } + } +diff -rupN binutils.orig/ld/ldmain.c binutils-2.41/ld/ldmain.c +--- binutils.orig/ld/ldmain.c 2024-05-13 13:03:47.805601779 +0100 ++++ binutils-2.41/ld/ldmain.c 2024-05-13 13:04:08.599633306 +0100 +@@ -90,6 +90,8 @@ bool version_printed; + /* TRUE if we should demangle symbol names. */ + bool demangling; + ++bool in_section_ordering; ++ + args_type command_line; + + ld_config_type config; +@@ -246,6 +248,26 @@ ld_bfd_error_handler (const char *fmt, v + (*default_bfd_error_handler) (fmt, ap); + } + ++static void ++display_external_script (void) ++{ ++ if (saved_script_handle == NULL) ++ return; ++ ++ static const int ld_bufsz = 8193; ++ size_t n; ++ char *buf = (char *) xmalloc (ld_bufsz); ++ ++ rewind (saved_script_handle); ++ while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) ++ { ++ buf[n] = 0; ++ info_msg ("%s", buf); ++ } ++ rewind (saved_script_handle); ++ free (buf); ++} ++ + int + main (int argc, char **argv) + { +@@ -416,26 +438,13 @@ main (int argc, char **argv) + if (verbose) + { + if (saved_script_handle) +- info_msg (_("using external linker script:")); ++ info_msg (_("using external linker script: %s"), processed_scripts->name); + else + info_msg (_("using internal linker script:")); + info_msg ("\n==================================================\n"); + + if (saved_script_handle) +- { +- static const int ld_bufsz = 8193; +- size_t n; +- char *buf = (char *) xmalloc (ld_bufsz); +- +- rewind (saved_script_handle); +- while ((n = fread (buf, 1, ld_bufsz - 1, saved_script_handle)) > 0) +- { +- buf[n] = 0; +- info_msg ("%s", buf); +- } +- rewind (saved_script_handle); +- free (buf); +- } ++ display_external_script (); + else + { + int isfile; +@@ -446,6 +455,22 @@ main (int argc, char **argv) + info_msg ("\n==================================================\n"); + } + ++ if (command_line.section_ordering_file) ++ { ++ FILE *hold_script_handle; ++ ++ hold_script_handle = saved_script_handle; ++ ldfile_open_command_file (command_line.section_ordering_file); ++ if (verbose) ++ display_external_script (); ++ saved_script_handle = hold_script_handle; ++ in_section_ordering = true; ++ parser_input = input_section_ordering_script; ++ yyparse (); ++ in_section_ordering = false; ++ ++ } ++ + if (command_line.force_group_allocation + || !bfd_link_relocatable (&link_info)) + link_info.resolve_section_groups = true; +diff -rupN binutils.orig/ld/lexsup.c binutils-2.41/ld/lexsup.c +--- binutils.orig/ld/lexsup.c 2024-05-13 13:03:48.141602288 +0100 ++++ binutils-2.41/ld/lexsup.c 2024-05-13 13:04:08.599633306 +0100 +@@ -484,6 +484,9 @@ static const struct ld_option ld_options + { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION}, + '\0', N_("name|alignment"), + N_("Sort sections by name or maximum alignment"), TWO_DASHES }, ++ { {"section-ordering-file", required_argument, NULL, OPTION_SECTION_ORDERING_FILE}, ++ '\0', N_("FILE"), ++ N_("Sort sections by statements in FILE"), TWO_DASHES }, + { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS}, + '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), + TWO_DASHES }, +@@ -1394,6 +1397,12 @@ parse_args (unsigned argc, char **argv) + einfo (_("%F%P: invalid section sorting option: %s\n"), + optarg); + break; ++ case OPTION_SECTION_ORDERING_FILE: ++ if (command_line.section_ordering_file != NULL ++ && strcmp (optarg, command_line.section_ordering_file) != 0) ++ einfo (_("%P: warning: section ordering file changed. Ignoring earlier definition\n")); ++ command_line.section_ordering_file = optarg; ++ break; + case OPTION_STATS: + config.stats = true; + break; +diff -rupN binutils.orig/ld/lexsup.c.orig binutils-2.41/ld/lexsup.c.orig +--- binutils.orig/ld/lexsup.c.orig 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/lexsup.c.orig 2024-05-13 13:03:25.177567469 +0100 +@@ -0,0 +1,2476 @@ ++/* Parse options for the GNU linker. ++ Copyright (C) 1991-2023 Free Software Foundation, Inc. ++ ++ This file is part of the GNU Binutils. ++ ++ This program is free software; you can redistribute it and/or modify ++ it under the terms of the GNU General Public License as published by ++ the Free Software Foundation; either version 3 of the License, or ++ (at your option) any later version. ++ ++ This program is distributed in the hope that it will be useful, ++ but WITHOUT ANY WARRANTY; without even the implied warranty of ++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ GNU General Public License for more details. ++ ++ You should have received a copy of the GNU General Public License ++ along with this program; if not, write to the Free Software ++ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++ MA 02110-1301, USA. */ ++ ++#include "sysdep.h" ++#include "bfd.h" ++#include "bfdver.h" ++#include "libiberty.h" ++#include "filenames.h" ++#include ++#include ++#include ++#include "safe-ctype.h" ++#include "getopt.h" ++#include "bfdlink.h" ++#include "ctf-api.h" ++#include "ld.h" ++#include "ldmain.h" ++#include "ldmisc.h" ++#include "ldexp.h" ++#include "ldlang.h" ++#include ++#include "ldlex.h" ++#include "ldfile.h" ++#include "ldver.h" ++#include "ldemul.h" ++#include "demangle.h" ++#if BFD_SUPPORTS_PLUGINS ++#include "plugin.h" ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ ++#ifndef PATH_SEPARATOR ++#if defined (__MSDOS__) || (defined (_WIN32) && ! defined (__CYGWIN32__)) ++#define PATH_SEPARATOR ';' ++#else ++#define PATH_SEPARATOR ':' ++#endif ++#endif ++ ++/* Somewhere above, sys/stat.h got included . . . . */ ++#if !defined(S_ISDIR) && defined(S_IFDIR) ++#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) ++#endif ++ ++static void set_default_dirlist (char *); ++static void set_section_start (char *, char *); ++static void set_segment_start (const char *, char *); ++static void help (void); ++ ++/* The long options. This structure is used for both the option ++ parsing and the help text. */ ++ ++enum control_enum { ++ /* Use one dash before long option name. */ ++ ONE_DASH = 1, ++ /* Use two dashes before long option name. */ ++ TWO_DASHES = 2, ++ /* Only accept two dashes before the long option name. ++ This is an overloading of the use of this enum, since originally it ++ was only intended to tell the --help display function how to display ++ the long option name. This feature was added in order to resolve ++ the confusion about the -omagic command line switch. Is it setting ++ the output file name to "magic" or is it setting the NMAGIC flag on ++ the output ? It has been decided that it is setting the output file ++ name, and that if you want to set the NMAGIC flag you should use -N ++ or --omagic. */ ++ EXACTLY_TWO_DASHES, ++ /* Don't mention this option in --help output. */ ++ NO_HELP ++}; ++ ++struct ld_option ++{ ++ /* The long option information. */ ++ struct option opt; ++ /* The short option with the same meaning ('\0' if none). */ ++ char shortopt; ++ /* The name of the argument (NULL if none). */ ++ const char *arg; ++ /* The documentation string. If this is NULL, this is a synonym for ++ the previous option. */ ++ const char *doc; ++ enum control_enum control; ++}; ++ ++static const struct ld_option ld_options[] = ++{ ++ { {NULL, required_argument, NULL, '\0'}, ++ 'a', N_("KEYWORD"), N_("Shared library control for HP/UX compatibility"), ++ ONE_DASH }, ++ { {"architecture", required_argument, NULL, 'A'}, ++ 'A', N_("ARCH"), N_("Set architecture") , TWO_DASHES }, ++ { {"format", required_argument, NULL, 'b'}, ++ 'b', N_("TARGET"), N_("Specify target for following input files"), ++ TWO_DASHES }, ++ { {"mri-script", required_argument, NULL, 'c'}, ++ 'c', N_("FILE"), N_("Read MRI format linker script"), TWO_DASHES }, ++ { {"dc", no_argument, NULL, 'd'}, ++ 'd', NULL, N_("Force common symbols to be defined"), ONE_DASH }, ++ { {"dp", no_argument, NULL, 'd'}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"dependency-file", required_argument, NULL, OPTION_DEPENDENCY_FILE}, ++ '\0', N_("FILE"), N_("Write dependency file"), TWO_DASHES }, ++ { {"force-group-allocation", no_argument, NULL, ++ OPTION_FORCE_GROUP_ALLOCATION}, ++ '\0', NULL, N_("Force group members out of groups"), TWO_DASHES }, ++ { {"entry", required_argument, NULL, 'e'}, ++ 'e', N_("ADDRESS"), N_("Set start address"), TWO_DASHES }, ++ { {"export-dynamic", no_argument, NULL, OPTION_EXPORT_DYNAMIC}, ++ 'E', NULL, N_("Export all dynamic symbols"), TWO_DASHES }, ++ { {"no-export-dynamic", no_argument, NULL, OPTION_NO_EXPORT_DYNAMIC}, ++ '\0', NULL, N_("Undo the effect of --export-dynamic"), TWO_DASHES }, ++ { {"enable-non-contiguous-regions", no_argument, NULL, OPTION_NON_CONTIGUOUS_REGIONS}, ++ '\0', NULL, N_("Enable support of non-contiguous memory regions"), TWO_DASHES }, ++ { {"enable-non-contiguous-regions-warnings", no_argument, NULL, OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS}, ++ '\0', NULL, N_("Enable warnings when --enable-non-contiguous-regions may cause unexpected behaviour"), TWO_DASHES }, ++ { {"disable-linker-version", no_argument, NULL, OPTION_DISABLE_LINKER_VERSION}, ++ '\0', NULL, N_("Disable the LINKER_VERSION linker script directive"), TWO_DASHES }, ++ { {"enable-linker-version", no_argument, NULL, OPTION_ENABLE_LINKER_VERSION}, ++ '\0', NULL, N_("Enable the LINKER_VERSION linker script directive"), TWO_DASHES }, ++ { {"EB", no_argument, NULL, OPTION_EB}, ++ '\0', NULL, N_("Link big-endian objects"), ONE_DASH }, ++ { {"EL", no_argument, NULL, OPTION_EL}, ++ '\0', NULL, N_("Link little-endian objects"), ONE_DASH }, ++ { {"auxiliary", required_argument, NULL, 'f'}, ++ 'f', N_("SHLIB"), N_("Auxiliary filter for shared object symbol table"), ++ TWO_DASHES }, ++ { {"filter", required_argument, NULL, 'F'}, ++ 'F', N_("SHLIB"), N_("Filter for shared object symbol table"), ++ TWO_DASHES }, ++ { {NULL, no_argument, NULL, '\0'}, ++ 'g', NULL, N_("Ignored"), ONE_DASH }, ++ { {"gpsize", required_argument, NULL, 'G'}, ++ 'G', N_("SIZE"), N_("Small data size (if no size, same as --shared)"), ++ TWO_DASHES }, ++ { {"soname", required_argument, NULL, OPTION_SONAME}, ++ 'h', N_("FILENAME"), N_("Set internal name of shared library"), ONE_DASH }, ++ { {"dynamic-linker", required_argument, NULL, OPTION_DYNAMIC_LINKER}, ++ 'I', N_("PROGRAM"), N_("Set PROGRAM as the dynamic linker to use"), ++ TWO_DASHES }, ++ { {"no-dynamic-linker", no_argument, NULL, OPTION_NO_DYNAMIC_LINKER}, ++ '\0', NULL, N_("Produce an executable with no program interpreter header"), ++ TWO_DASHES }, ++ { {"library", required_argument, NULL, 'l'}, ++ 'l', N_("LIBNAME"), N_("Search for library LIBNAME"), TWO_DASHES }, ++ { {"library-path", required_argument, NULL, 'L'}, ++ 'L', N_("DIRECTORY"), N_("Add DIRECTORY to library search path"), ++ TWO_DASHES }, ++ { {"sysroot=", required_argument, NULL, OPTION_SYSROOT}, ++ '\0', NULL, N_("Override the default sysroot location"), TWO_DASHES }, ++ { {NULL, required_argument, NULL, '\0'}, ++ 'm', N_("EMULATION"), N_("Set emulation"), ONE_DASH }, ++ { {"print-map", no_argument, NULL, 'M'}, ++ 'M', NULL, N_("Print map file on standard output"), TWO_DASHES }, ++ { {"nmagic", no_argument, NULL, 'n'}, ++ 'n', NULL, N_("Do not page align data"), TWO_DASHES }, ++ { {"omagic", no_argument, NULL, 'N'}, ++ 'N', NULL, N_("Do not page align data, do not make text readonly"), ++ EXACTLY_TWO_DASHES }, ++ { {"no-omagic", no_argument, NULL, OPTION_NO_OMAGIC}, ++ '\0', NULL, N_("Page align data, make text readonly"), ++ EXACTLY_TWO_DASHES }, ++ { {"output", required_argument, NULL, 'o'}, ++ 'o', N_("FILE"), N_("Set output file name"), EXACTLY_TWO_DASHES }, ++ { {NULL, required_argument, NULL, '\0'}, ++ 'O', NULL, N_("Optimize output file"), ONE_DASH }, ++ { {"out-implib", required_argument, NULL, OPTION_OUT_IMPLIB}, ++ '\0', N_("FILE"), N_("Generate import library"), TWO_DASHES }, ++#if BFD_SUPPORTS_PLUGINS ++ { {"plugin", required_argument, NULL, OPTION_PLUGIN}, ++ '\0', N_("PLUGIN"), N_("Load named plugin"), ONE_DASH }, ++ { {"plugin-opt", required_argument, NULL, OPTION_PLUGIN_OPT}, ++ '\0', N_("ARG"), N_("Send arg to last-loaded plugin"), ONE_DASH }, ++ { {"flto", optional_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for GCC LTO option compatibility"), ++ ONE_DASH }, ++ { {"flto-partition=", required_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for GCC LTO option compatibility"), ++ ONE_DASH }, ++#else ++ { {"plugin", required_argument, NULL, OPTION_IGNORE}, ++ '\0', N_("PLUGIN"), N_("Load named plugin (ignored)"), ONE_DASH }, ++ { {"plugin-opt", required_argument, NULL, OPTION_IGNORE}, ++ '\0', N_("ARG"), N_("Send arg to last-loaded plugin (ignored)"), ONE_DASH }, ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ { {"fuse-ld=", required_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for GCC linker option compatibility"), ++ ONE_DASH }, ++ { {"map-whole-files", optional_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for gold option compatibility"), ++ TWO_DASHES }, ++ { {"no-map-whole-files", optional_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for gold option compatibility"), ++ TWO_DASHES }, ++ { {"Qy", no_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for SVR4 compatibility"), ONE_DASH }, ++ { {"emit-relocs", no_argument, NULL, 'q'}, ++ 'q', NULL, "Generate relocations in final output", TWO_DASHES }, ++ { {"relocatable", no_argument, NULL, 'r'}, ++ 'r', NULL, N_("Generate relocatable output"), TWO_DASHES }, ++ { {NULL, no_argument, NULL, '\0'}, ++ 'i', NULL, NULL, ONE_DASH }, ++ { {"just-symbols", required_argument, NULL, 'R'}, ++ 'R', N_("FILE"), N_("Just link symbols (if directory, same as --rpath)"), ++ TWO_DASHES }, ++ ++ { {"remap-inputs-file", required_argument, NULL, OPTION_REMAP_INPUTS_FILE}, ++ '\0', N_("FILE"), "Provide a FILE containing input remapings", TWO_DASHES }, ++ { {"remap-inputs", required_argument, NULL, OPTION_REMAP_INPUTS}, ++ '\0', N_("PATTERN=FILE"), "Remap input files matching PATTERN to FILE", TWO_DASHES }, ++ ++ { {"strip-all", no_argument, NULL, 's'}, ++ 's', NULL, N_("Strip all symbols"), TWO_DASHES }, ++ { {"strip-debug", no_argument, NULL, 'S'}, ++ 'S', NULL, N_("Strip debugging symbols"), TWO_DASHES }, ++ { {"strip-discarded", no_argument, NULL, OPTION_STRIP_DISCARDED}, ++ '\0', NULL, N_("Strip symbols in discarded sections"), TWO_DASHES }, ++ { {"no-strip-discarded", no_argument, NULL, OPTION_NO_STRIP_DISCARDED}, ++ '\0', NULL, N_("Do not strip symbols in discarded sections"), TWO_DASHES }, ++ { {"trace", no_argument, NULL, 't'}, ++ 't', NULL, N_("Trace file opens"), TWO_DASHES }, ++ { {"script", required_argument, NULL, 'T'}, ++ 'T', N_("FILE"), N_("Read linker script"), TWO_DASHES }, ++ { {"default-script", required_argument, NULL, OPTION_DEFAULT_SCRIPT}, ++ '\0', N_("FILE"), N_("Read default linker script"), TWO_DASHES }, ++ { {"dT", required_argument, NULL, OPTION_DEFAULT_SCRIPT}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"undefined", required_argument, NULL, 'u'}, ++ 'u', N_("SYMBOL"), N_("Start with undefined reference to SYMBOL"), ++ TWO_DASHES }, ++ { {"require-defined", required_argument, NULL, OPTION_REQUIRE_DEFINED_SYMBOL}, ++ '\0', N_("SYMBOL"), N_("Require SYMBOL be defined in the final output"), ++ TWO_DASHES }, ++ { {"unique", optional_argument, NULL, OPTION_UNIQUE}, ++ '\0', N_("[=SECTION]"), ++ N_("Don't merge input [SECTION | orphan] sections"), TWO_DASHES }, ++ { {"Ur", no_argument, NULL, OPTION_UR}, ++ '\0', NULL, N_("Build global constructor/destructor tables"), ONE_DASH }, ++ { {"version", no_argument, NULL, OPTION_VERSION}, ++ 'v', NULL, N_("Print version information"), TWO_DASHES }, ++ { {NULL, no_argument, NULL, '\0'}, ++ 'V', NULL, N_("Print version and emulation information"), ONE_DASH }, ++ { {"discard-all", no_argument, NULL, 'x'}, ++ 'x', NULL, N_("Discard all local symbols"), TWO_DASHES }, ++ { {"discard-locals", no_argument, NULL, 'X'}, ++ 'X', NULL, N_("Discard temporary local symbols (default)"), TWO_DASHES }, ++ { {"discard-none", no_argument, NULL, OPTION_DISCARD_NONE}, ++ '\0', NULL, N_("Don't discard any local symbols"), TWO_DASHES }, ++ { {"trace-symbol", required_argument, NULL, 'y'}, ++ 'y', N_("SYMBOL"), N_("Trace mentions of SYMBOL"), TWO_DASHES }, ++ { {NULL, required_argument, NULL, '\0'}, ++ 'Y', N_("PATH"), N_("Default search path for Solaris compatibility"), ++ ONE_DASH }, ++ { {"start-group", no_argument, NULL, '('}, ++ '(', NULL, N_("Start a group"), TWO_DASHES }, ++ { {"end-group", no_argument, NULL, ')'}, ++ ')', NULL, N_("End a group"), TWO_DASHES }, ++ { {"accept-unknown-input-arch", no_argument, NULL, ++ OPTION_ACCEPT_UNKNOWN_INPUT_ARCH}, ++ '\0', NULL, ++ N_("Accept input files whose architecture cannot be determined"), ++ TWO_DASHES }, ++ { {"no-accept-unknown-input-arch", no_argument, NULL, ++ OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH}, ++ '\0', NULL, N_("Reject input files whose architecture is unknown"), ++ TWO_DASHES }, ++ ++ /* The next two options are deprecated because of their similarity to ++ --as-needed and --no-as-needed. They have been replaced by ++ --copy-dt-needed-entries and --no-copy-dt-needed-entries. */ ++ { {"add-needed", no_argument, NULL, OPTION_ADD_DT_NEEDED_FOR_DYNAMIC}, ++ '\0', NULL, NULL, NO_HELP }, ++ { {"no-add-needed", no_argument, NULL, OPTION_NO_ADD_DT_NEEDED_FOR_DYNAMIC}, ++ '\0', NULL, NULL, NO_HELP }, ++ ++ { {"as-needed", no_argument, NULL, OPTION_ADD_DT_NEEDED_FOR_REGULAR}, ++ '\0', NULL, N_("Only set DT_NEEDED for following dynamic libs if used"), ++ TWO_DASHES }, ++ { {"no-as-needed", no_argument, NULL, OPTION_NO_ADD_DT_NEEDED_FOR_REGULAR}, ++ '\0', NULL, N_("Always set DT_NEEDED for dynamic libraries mentioned on\n" ++ " the command line"), ++ TWO_DASHES }, ++ { {"assert", required_argument, NULL, OPTION_ASSERT}, ++ '\0', N_("KEYWORD"), N_("Ignored for SunOS compatibility"), ONE_DASH }, ++ { {"Bdynamic", no_argument, NULL, OPTION_CALL_SHARED}, ++ '\0', NULL, N_("Link against shared libraries"), ONE_DASH }, ++ { {"dy", no_argument, NULL, OPTION_CALL_SHARED}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"call_shared", no_argument, NULL, OPTION_CALL_SHARED}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"Bstatic", no_argument, NULL, OPTION_NON_SHARED}, ++ '\0', NULL, N_("Do not link against shared libraries"), ONE_DASH }, ++ { {"dn", no_argument, NULL, OPTION_NON_SHARED}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"non_shared", no_argument, NULL, OPTION_NON_SHARED}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"static", no_argument, NULL, OPTION_NON_SHARED}, ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"Bno-symbolic", no_argument, NULL, OPTION_NO_SYMBOLIC}, ++ '\0', NULL, N_("Don't bind global references locally"), ONE_DASH }, ++ { {"Bsymbolic", no_argument, NULL, OPTION_SYMBOLIC}, ++ '\0', NULL, N_("Bind global references locally"), ONE_DASH }, ++ { {"Bsymbolic-functions", no_argument, NULL, OPTION_SYMBOLIC_FUNCTIONS}, ++ '\0', NULL, N_("Bind global function references locally"), ONE_DASH }, ++ { {"check-sections", no_argument, NULL, OPTION_CHECK_SECTIONS}, ++ '\0', NULL, N_("Check section addresses for overlaps (default)"), ++ TWO_DASHES }, ++ { {"no-check-sections", no_argument, NULL, OPTION_NO_CHECK_SECTIONS}, ++ '\0', NULL, N_("Do not check section addresses for overlaps"), ++ TWO_DASHES }, ++ { {"copy-dt-needed-entries", no_argument, NULL, ++ OPTION_ADD_DT_NEEDED_FOR_DYNAMIC}, ++ '\0', NULL, N_("Copy DT_NEEDED links mentioned inside DSOs that follow"), ++ TWO_DASHES }, ++ { {"no-copy-dt-needed-entries", no_argument, NULL, ++ OPTION_NO_ADD_DT_NEEDED_FOR_DYNAMIC}, ++ '\0', NULL, N_("Do not copy DT_NEEDED links mentioned inside DSOs that follow"), ++ TWO_DASHES }, ++ ++ { {"cref", no_argument, NULL, OPTION_CREF}, ++ '\0', NULL, N_("Output cross reference table"), TWO_DASHES }, ++ { {"defsym", required_argument, NULL, OPTION_DEFSYM}, ++ '\0', N_("SYMBOL=EXPRESSION"), N_("Define a symbol"), TWO_DASHES }, ++ { {"demangle", optional_argument, NULL, OPTION_DEMANGLE}, ++ '\0', N_("[=STYLE]"), N_("Demangle symbol names [using STYLE]"), ++ TWO_DASHES }, ++ { {"disable-multiple-abs-defs", no_argument, NULL, ++ OPTION_DISABLE_MULTIPLE_DEFS_ABS}, ++ '\0', NULL, N_("Do not allow multiple definitions with symbols included\n" ++ " in filename invoked by -R " ++ "or --just-symbols"), ++ TWO_DASHES}, ++ { {"embedded-relocs", no_argument, NULL, OPTION_EMBEDDED_RELOCS}, ++ '\0', NULL, N_("Generate embedded relocs"), TWO_DASHES}, ++ { {"fatal-warnings", no_argument, NULL, OPTION_WARN_FATAL}, ++ '\0', NULL, N_("Treat warnings as errors"), ++ TWO_DASHES }, ++ { {"no-fatal-warnings", no_argument, NULL, OPTION_NO_WARN_FATAL}, ++ '\0', NULL, N_("Do not treat warnings as errors (default)"), ++ TWO_DASHES }, ++ { {"fini", required_argument, NULL, OPTION_FINI}, ++ '\0', N_("SYMBOL"), N_("Call SYMBOL at unload-time"), ONE_DASH }, ++ { {"force-exe-suffix", no_argument, NULL, OPTION_FORCE_EXE_SUFFIX}, ++ '\0', NULL, N_("Force generation of file with .exe suffix"), TWO_DASHES}, ++ { {"gc-sections", no_argument, NULL, OPTION_GC_SECTIONS}, ++ '\0', NULL, N_("Remove unused sections (on some targets)"), ++ TWO_DASHES }, ++ { {"no-gc-sections", no_argument, NULL, OPTION_NO_GC_SECTIONS}, ++ '\0', NULL, N_("Don't remove unused sections (default)"), ++ TWO_DASHES }, ++ { {"print-gc-sections", no_argument, NULL, OPTION_PRINT_GC_SECTIONS}, ++ '\0', NULL, N_("List removed unused sections on stderr"), ++ TWO_DASHES }, ++ { {"no-print-gc-sections", no_argument, NULL, OPTION_NO_PRINT_GC_SECTIONS}, ++ '\0', NULL, N_("Do not list removed unused sections"), ++ TWO_DASHES }, ++ { {"gc-keep-exported", no_argument, NULL, OPTION_GC_KEEP_EXPORTED}, ++ '\0', NULL, N_("Keep exported symbols when removing unused sections"), ++ TWO_DASHES }, ++ { {"hash-size=", required_argument, NULL, OPTION_HASH_SIZE}, ++ '\0', NULL, N_("Set default hash table size close to "), ++ TWO_DASHES }, ++ { {"help", no_argument, NULL, OPTION_HELP}, ++ '\0', NULL, N_("Print option help"), TWO_DASHES }, ++ { {"init", required_argument, NULL, OPTION_INIT}, ++ '\0', N_("SYMBOL"), N_("Call SYMBOL at load-time"), ONE_DASH }, ++ { {"Map", required_argument, NULL, OPTION_MAP}, ++ '\0', N_("FILE/DIR"), N_("Write a linker map to FILE or DIR/.map"), ONE_DASH }, ++ { {"no-define-common", no_argument, NULL, OPTION_NO_DEFINE_COMMON}, ++ '\0', NULL, N_("Do not define Common storage"), TWO_DASHES }, ++ { {"no-demangle", no_argument, NULL, OPTION_NO_DEMANGLE }, ++ '\0', NULL, N_("Do not demangle symbol names"), TWO_DASHES }, ++ { {"no-keep-memory", no_argument, NULL, OPTION_NO_KEEP_MEMORY}, ++ '\0', NULL, N_("Use less memory and more disk I/O"), TWO_DASHES }, ++ { {"no-undefined", no_argument, NULL, OPTION_NO_UNDEFINED}, ++ '\0', NULL, N_("Do not allow unresolved references in object files"), ++ TWO_DASHES }, ++ { {"no-warnings", no_argument, NULL, OPTION_NO_WARNINGS}, ++ 'w', NULL, N_("Do not display any warning or error messages"), ++ TWO_DASHES }, ++ { {"allow-shlib-undefined", no_argument, NULL, OPTION_ALLOW_SHLIB_UNDEFINED}, ++ '\0', NULL, N_("Allow unresolved references in shared libraries"), ++ TWO_DASHES }, ++ { {"no-allow-shlib-undefined", no_argument, NULL, ++ OPTION_NO_ALLOW_SHLIB_UNDEFINED}, ++ '\0', NULL, N_("Do not allow unresolved references in shared libs"), ++ TWO_DASHES }, ++ { {"allow-multiple-definition", no_argument, NULL, ++ OPTION_ALLOW_MULTIPLE_DEFINITION}, ++ '\0', NULL, N_("Allow multiple definitions"), TWO_DASHES }, ++#if SUPPORT_ERROR_HANDLING_SCRIPT ++ { {"error-handling-script", required_argument, NULL, ++ OPTION_ERROR_HANDLING_SCRIPT}, ++ '\0', N_("SCRIPT"), N_("Provide a script to help with undefined symbol errors"), TWO_DASHES}, ++#endif ++ { {"undefined-version", no_argument, NULL, OPTION_UNDEFINED_VERSION}, ++ '\0', NULL, N_("Allow undefined version"), EXACTLY_TWO_DASHES }, ++ { {"no-undefined-version", no_argument, NULL, OPTION_NO_UNDEFINED_VERSION}, ++ '\0', NULL, N_("Disallow undefined version"), TWO_DASHES }, ++ { {"default-symver", no_argument, NULL, OPTION_DEFAULT_SYMVER}, ++ '\0', NULL, N_("Create default symbol version"), TWO_DASHES }, ++ { {"default-imported-symver", no_argument, NULL, ++ OPTION_DEFAULT_IMPORTED_SYMVER}, ++ '\0', NULL, N_("Create default symbol version for imported symbols"), ++ TWO_DASHES }, ++ { {"no-warn-mismatch", no_argument, NULL, OPTION_NO_WARN_MISMATCH}, ++ '\0', NULL, N_("Don't warn about mismatched input files"), TWO_DASHES}, ++ { {"no-warn-search-mismatch", no_argument, NULL, ++ OPTION_NO_WARN_SEARCH_MISMATCH}, ++ '\0', NULL, N_("Don't warn on finding an incompatible library"), ++ TWO_DASHES}, ++ { {"no-whole-archive", no_argument, NULL, OPTION_NO_WHOLE_ARCHIVE}, ++ '\0', NULL, N_("Turn off --whole-archive"), TWO_DASHES }, ++ { {"noinhibit-exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, ++ '\0', NULL, N_("Create an output file even if errors occur"), ++ TWO_DASHES }, ++ { {"noinhibit_exec", no_argument, NULL, OPTION_NOINHIBIT_EXEC}, ++ '\0', NULL, NULL, NO_HELP }, ++ { {"nostdlib", no_argument, NULL, OPTION_NOSTDLIB}, ++ '\0', NULL, N_("Only use library directories specified on\n" ++ " the command line"), ++ ONE_DASH }, ++ { {"oformat", required_argument, NULL, OPTION_OFORMAT}, ++ '\0', N_("TARGET"), N_("Specify target of output file"), ++ EXACTLY_TWO_DASHES }, ++ { {"print-output-format", no_argument, NULL, OPTION_PRINT_OUTPUT_FORMAT}, ++ '\0', NULL, N_("Print default output format"), TWO_DASHES }, ++ { {"print-sysroot", no_argument, NULL, OPTION_PRINT_SYSROOT}, ++ '\0', NULL, N_("Print current sysroot"), TWO_DASHES }, ++ { {"qmagic", no_argument, NULL, OPTION_IGNORE}, ++ '\0', NULL, N_("Ignored for Linux compatibility"), ONE_DASH }, ++ { {"reduce-memory-overheads", no_argument, NULL, ++ OPTION_REDUCE_MEMORY_OVERHEADS}, ++ '\0', NULL, N_("Reduce memory overheads, possibly taking much longer"), ++ TWO_DASHES }, ++ { {"max-cache-size=SIZE", required_argument, NULL, ++ OPTION_MAX_CACHE_SIZE}, ++ '\0', NULL, N_("Set the maximum cache size to SIZE bytes"), ++ TWO_DASHES }, ++ { {"relax", no_argument, NULL, OPTION_RELAX}, ++ '\0', NULL, N_("Reduce code size by using target specific optimizations"), TWO_DASHES }, ++ { {"no-relax", no_argument, NULL, OPTION_NO_RELAX}, ++ '\0', NULL, N_("Do not use relaxation techniques to reduce code size"), TWO_DASHES }, ++ { {"retain-symbols-file", required_argument, NULL, ++ OPTION_RETAIN_SYMBOLS_FILE}, ++ '\0', N_("FILE"), N_("Keep only symbols listed in FILE"), TWO_DASHES }, ++ { {"rpath", required_argument, NULL, OPTION_RPATH}, ++ '\0', N_("PATH"), N_("Set runtime shared library search path"), ONE_DASH }, ++ { {"rpath-link", required_argument, NULL, OPTION_RPATH_LINK}, ++ '\0', N_("PATH"), N_("Set link time shared library search path"), ++ ONE_DASH }, ++ { {"shared", no_argument, NULL, OPTION_SHARED}, ++ '\0', NULL, N_("Create a shared library"), ONE_DASH }, ++ { {"Bshareable", no_argument, NULL, OPTION_SHARED }, /* FreeBSD. */ ++ '\0', NULL, NULL, ONE_DASH }, ++ { {"pie", no_argument, NULL, OPTION_PIE}, ++ '\0', NULL, N_("Create a position independent executable"), ONE_DASH }, ++ { {"pic-executable", no_argument, NULL, OPTION_PIE}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-pie", no_argument, NULL, OPTION_NO_PIE}, ++ '\0', NULL, N_("Create a position dependent executable (default)"), ONE_DASH }, ++ { {"sort-common", optional_argument, NULL, OPTION_SORT_COMMON}, ++ '\0', N_("[=ascending|descending]"), ++ N_("Sort common symbols by alignment [in specified order]"), ++ TWO_DASHES }, ++ { {"sort_common", no_argument, NULL, OPTION_SORT_COMMON}, ++ '\0', NULL, NULL, NO_HELP }, ++ { {"sort-section", required_argument, NULL, OPTION_SORT_SECTION}, ++ '\0', N_("name|alignment"), ++ N_("Sort sections by name or maximum alignment"), TWO_DASHES }, ++ { {"spare-dynamic-tags", required_argument, NULL, OPTION_SPARE_DYNAMIC_TAGS}, ++ '\0', N_("COUNT"), N_("How many tags to reserve in .dynamic section"), ++ TWO_DASHES }, ++ { {"split-by-file", optional_argument, NULL, OPTION_SPLIT_BY_FILE}, ++ '\0', N_("[=SIZE]"), N_("Split output sections every SIZE octets"), ++ TWO_DASHES }, ++ { {"split-by-reloc", optional_argument, NULL, OPTION_SPLIT_BY_RELOC}, ++ '\0', N_("[=COUNT]"), N_("Split output sections every COUNT relocs"), ++ TWO_DASHES }, ++ { {"stats", no_argument, NULL, OPTION_STATS}, ++ '\0', NULL, N_("Print memory usage statistics"), TWO_DASHES }, ++ { {"target-help", no_argument, NULL, OPTION_TARGET_HELP}, ++ '\0', NULL, N_("Display target specific options"), TWO_DASHES }, ++ { {"task-link", required_argument, NULL, OPTION_TASK_LINK}, ++ '\0', N_("SYMBOL"), N_("Do task level linking"), TWO_DASHES }, ++ { {"traditional-format", no_argument, NULL, OPTION_TRADITIONAL_FORMAT}, ++ '\0', NULL, N_("Use same format as native linker"), TWO_DASHES }, ++ { {"section-start", required_argument, NULL, OPTION_SECTION_START}, ++ '\0', N_("SECTION=ADDRESS"), N_("Set address of named section"), ++ TWO_DASHES }, ++ { {"Tbss", required_argument, NULL, OPTION_TBSS}, ++ '\0', N_("ADDRESS"), N_("Set address of .bss section"), ONE_DASH }, ++ { {"Tdata", required_argument, NULL, OPTION_TDATA}, ++ '\0', N_("ADDRESS"), N_("Set address of .data section"), ONE_DASH }, ++ { {"Ttext", required_argument, NULL, OPTION_TTEXT}, ++ '\0', N_("ADDRESS"), N_("Set address of .text section"), ONE_DASH }, ++ { {"Ttext-segment", required_argument, NULL, OPTION_TTEXT_SEGMENT}, ++ '\0', N_("ADDRESS"), N_("Set address of text segment"), ONE_DASH }, ++ { {"Trodata-segment", required_argument, NULL, OPTION_TRODATA_SEGMENT}, ++ '\0', N_("ADDRESS"), N_("Set address of rodata segment"), ONE_DASH }, ++ { {"Tldata-segment", required_argument, NULL, OPTION_TLDATA_SEGMENT}, ++ '\0', N_("ADDRESS"), N_("Set address of ldata segment"), ONE_DASH }, ++ { {"unresolved-symbols=", required_argument, NULL, ++ OPTION_UNRESOLVED_SYMBOLS}, ++ '\0', NULL, N_("How to handle unresolved symbols. is:\n" ++ " ignore-all, report-all, ignore-in-object-files,\n" ++ " ignore-in-shared-libs"), ++ TWO_DASHES }, ++ { {"verbose", optional_argument, NULL, OPTION_VERBOSE}, ++ '\0', N_("[=NUMBER]"), ++ N_("Output lots of information during link"), TWO_DASHES }, ++ { {"dll-verbose", no_argument, NULL, OPTION_VERBOSE}, /* Linux. */ ++ '\0', NULL, NULL, NO_HELP }, ++ { {"version-script", required_argument, NULL, OPTION_VERSION_SCRIPT }, ++ '\0', N_("FILE"), N_("Read version information script"), TWO_DASHES }, ++ { {"version-exports-section", required_argument, NULL, ++ OPTION_VERSION_EXPORTS_SECTION }, ++ '\0', N_("SYMBOL"), N_("Take export symbols list from .exports, using\n" ++ " SYMBOL as the version."), ++ TWO_DASHES }, ++ { {"dynamic-list-data", no_argument, NULL, OPTION_DYNAMIC_LIST_DATA}, ++ '\0', NULL, N_("Add data symbols to dynamic list"), TWO_DASHES }, ++ { {"dynamic-list-cpp-new", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_NEW}, ++ '\0', NULL, N_("Use C++ operator new/delete dynamic list"), TWO_DASHES }, ++ { {"dynamic-list-cpp-typeinfo", no_argument, NULL, OPTION_DYNAMIC_LIST_CPP_TYPEINFO}, ++ '\0', NULL, N_("Use C++ typeinfo dynamic list"), TWO_DASHES }, ++ { {"dynamic-list", required_argument, NULL, OPTION_DYNAMIC_LIST}, ++ '\0', N_("FILE"), N_("Read dynamic list"), TWO_DASHES }, ++ { {"export-dynamic-symbol", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL}, ++ '\0', N_("SYMBOL"), N_("Export the specified symbol"), EXACTLY_TWO_DASHES }, ++ { {"export-dynamic-symbol-list", required_argument, NULL, OPTION_EXPORT_DYNAMIC_SYMBOL_LIST}, ++ '\0', N_("FILE"), N_("Read export dynamic symbol list"), EXACTLY_TWO_DASHES }, ++ { {"warn-common", no_argument, NULL, OPTION_WARN_COMMON}, ++ '\0', NULL, N_("Warn about duplicate common symbols"), TWO_DASHES }, ++ { {"warn-constructors", no_argument, NULL, OPTION_WARN_CONSTRUCTORS}, ++ '\0', NULL, N_("Warn if global constructors/destructors are seen"), ++ TWO_DASHES }, ++ ++ { {"error-execstack", no_argument, NULL, OPTION_ERROR_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-error-execstack", no_argument, NULL, OPTION_NO_ERROR_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"warn-execstack-objects", no_argument, NULL, OPTION_WARN_EXECSTACK_OBJECTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"warn-execstack", no_argument, NULL, OPTION_WARN_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-warn-execstack", no_argument, NULL, OPTION_NO_WARN_EXECSTACK}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ ++ { {"error-rwx-segments", no_argument, NULL, OPTION_ERROR_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-error-rwx-segments", no_argument, NULL, OPTION_NO_ERROR_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"warn-rwx-segments", no_argument, NULL, OPTION_WARN_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ { {"no-warn-rwx-segments", no_argument, NULL, OPTION_NO_WARN_RWX_SEGMENTS}, ++ '\0', NULL, NULL, TWO_DASHES }, ++ ++ { {"warn-multiple-gp", no_argument, NULL, OPTION_WARN_MULTIPLE_GP}, ++ '\0', NULL, N_("Warn if the multiple GP values are used"), TWO_DASHES }, ++ { {"warn-once", no_argument, NULL, OPTION_WARN_ONCE}, ++ '\0', NULL, N_("Warn only once per undefined symbol"), TWO_DASHES }, ++ { {"warn-section-align", no_argument, NULL, OPTION_WARN_SECTION_ALIGN}, ++ '\0', NULL, N_("Warn if start of section changes due to alignment"), ++ TWO_DASHES }, ++ { {"warn-textrel", no_argument, NULL, OPTION_WARN_TEXTREL}, ++ '\0', NULL, ++#if DEFAULT_LD_TEXTREL_CHECK_WARNING ++ N_("Warn if output has DT_TEXTREL (default)"), ++#else ++ N_("Warn if output has DT_TEXTREL"), ++#endif ++ TWO_DASHES }, ++ { {"warn-shared-textrel", no_argument, NULL, OPTION_WARN_TEXTREL}, ++ '\0', NULL, NULL, NO_HELP }, ++ { {"warn-alternate-em", no_argument, NULL, OPTION_WARN_ALTERNATE_EM}, ++ '\0', NULL, N_("Warn if an object has alternate ELF machine code"), ++ TWO_DASHES }, ++ { {"warn-unresolved-symbols", no_argument, NULL, ++ OPTION_WARN_UNRESOLVED_SYMBOLS}, ++ '\0', NULL, N_("Report unresolved symbols as warnings"), TWO_DASHES }, ++ { {"error-unresolved-symbols", no_argument, NULL, ++ OPTION_ERROR_UNRESOLVED_SYMBOLS}, ++ '\0', NULL, N_("Report unresolved symbols as errors"), TWO_DASHES }, ++ { {"whole-archive", no_argument, NULL, OPTION_WHOLE_ARCHIVE}, ++ '\0', NULL, N_("Include all objects from following archives"), ++ TWO_DASHES }, ++ { {"wrap", required_argument, NULL, OPTION_WRAP}, ++ '\0', N_("SYMBOL"), N_("Use wrapper functions for SYMBOL"), TWO_DASHES }, ++ { {"ignore-unresolved-symbol", required_argument, NULL, ++ OPTION_IGNORE_UNRESOLVED_SYMBOL}, ++ '\0', N_("SYMBOL"), ++ N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES }, ++ { {"push-state", no_argument, NULL, OPTION_PUSH_STATE}, ++ '\0', NULL, N_("Push state of flags governing input file handling"), ++ TWO_DASHES }, ++ { {"pop-state", no_argument, NULL, OPTION_POP_STATE}, ++ '\0', NULL, N_("Pop state of flags governing input file handling"), ++ TWO_DASHES }, ++ { {"print-memory-usage", no_argument, NULL, OPTION_PRINT_MEMORY_USAGE}, ++ '\0', NULL, N_("Report target memory usage"), TWO_DASHES }, ++ { {"orphan-handling", required_argument, NULL, OPTION_ORPHAN_HANDLING}, ++ '\0', N_("=MODE"), N_("Control how orphan sections are handled."), ++ TWO_DASHES }, ++ { {"print-map-discarded", no_argument, NULL, OPTION_PRINT_MAP_DISCARDED}, ++ '\0', NULL, N_("Show discarded sections in map file output (default)"), ++ TWO_DASHES }, ++ { {"no-print-map-discarded", no_argument, NULL, OPTION_NO_PRINT_MAP_DISCARDED}, ++ '\0', NULL, N_("Do not show discarded sections in map file output"), ++ TWO_DASHES }, ++ { {"print-map-locals", no_argument, NULL, OPTION_PRINT_MAP_LOCALS}, ++ '\0', NULL, N_("Show local symbols in map file output"), ++ TWO_DASHES }, ++ { {"no-print-map-locals", no_argument, NULL, OPTION_NO_PRINT_MAP_LOCALS}, ++ '\0', NULL, N_("Do not show local symbols in map file output (default)"), ++ TWO_DASHES }, ++ { {"ctf-variables", no_argument, NULL, OPTION_CTF_VARIABLES}, ++ '\0', NULL, N_("Emit names and types of static variables in CTF"), ++ TWO_DASHES }, ++ { {"no-ctf-variables", no_argument, NULL, OPTION_NO_CTF_VARIABLES}, ++ '\0', NULL, N_("Do not emit names and types of static variables in CTF"), ++ TWO_DASHES }, ++ { {"ctf-share-types=", required_argument, NULL, ++ OPTION_CTF_SHARE_TYPES}, ++ '\0', NULL, N_("How to share CTF types between translation units.\n" ++ " is: share-unconflicted (default),\n" ++ " share-duplicated"), ++ TWO_DASHES }, ++}; ++ ++#define OPTION_COUNT ARRAY_SIZE (ld_options) ++ ++void ++parse_args (unsigned argc, char **argv) ++{ ++ unsigned i; ++ int is, il, irl; ++ int ingroup = 0; ++ char *default_dirlist = NULL; ++ char *shortopts; ++ struct option *longopts; ++ struct option *really_longopts; ++ int last_optind; ++ enum symbolic_enum ++ { ++ symbolic_unset = 0, ++ symbolic, ++ symbolic_functions, ++ } opt_symbolic = symbolic_unset; ++ enum dynamic_list_enum ++ { ++ dynamic_list_unset = 0, ++ dynamic_list_data, ++ dynamic_list ++ } opt_dynamic_list = dynamic_list_unset; ++ struct bfd_elf_dynamic_list *export_list = NULL; ++ ++ shortopts = (char *) xmalloc (OPTION_COUNT * 3 + 2); ++ longopts = (struct option *) ++ xmalloc (sizeof (*longopts) * (OPTION_COUNT + 1)); ++ really_longopts = (struct option *) ++ xmalloc (sizeof (*really_longopts) * (OPTION_COUNT + 1)); ++ ++ /* Starting the short option string with '-' is for programs that ++ expect options and other ARGV-elements in any order and that care about ++ the ordering of the two. We describe each non-option ARGV-element ++ as if it were the argument of an option with character code 1. */ ++ shortopts[0] = '-'; ++ is = 1; ++ il = 0; ++ irl = 0; ++ for (i = 0; i < OPTION_COUNT; i++) ++ { ++ if (ld_options[i].shortopt != '\0') ++ { ++ shortopts[is] = ld_options[i].shortopt; ++ ++is; ++ if (ld_options[i].opt.has_arg == required_argument ++ || ld_options[i].opt.has_arg == optional_argument) ++ { ++ shortopts[is] = ':'; ++ ++is; ++ if (ld_options[i].opt.has_arg == optional_argument) ++ { ++ shortopts[is] = ':'; ++ ++is; ++ } ++ } ++ } ++ if (ld_options[i].opt.name != NULL) ++ { ++ if (ld_options[i].control == EXACTLY_TWO_DASHES) ++ { ++ really_longopts[irl] = ld_options[i].opt; ++ ++irl; ++ } ++ else ++ { ++ longopts[il] = ld_options[i].opt; ++ ++il; ++ } ++ } ++ } ++ shortopts[is] = '\0'; ++ longopts[il].name = NULL; ++ really_longopts[irl].name = NULL; ++ ++ ldemul_add_options (is, &shortopts, il, &longopts, irl, &really_longopts); ++ ++ /* The -G option is ambiguous on different platforms. Sometimes it ++ specifies the largest data size to put into the small data ++ section. Sometimes it is equivalent to --shared. Unfortunately, ++ the first form takes an argument, while the second does not. ++ ++ We need to permit the --shared form because on some platforms, ++ such as Solaris, gcc -shared will pass -G to the linker. ++ ++ To permit either usage, we look through the argument list. If we ++ find -G not followed by a number, we change it into --shared. ++ This will work for most normal cases. */ ++ for (i = 1; i < argc; i++) ++ if (strcmp (argv[i], "-G") == 0 ++ && (i + 1 >= argc ++ || ! ISDIGIT (argv[i + 1][0]))) ++ argv[i] = (char *) "--shared"; ++ ++ /* Because we permit long options to start with a single dash, and ++ we have a --library option, and the -l option is conventionally ++ used with an immediately following argument, we can have bad ++ results if somebody tries to use -l with a library whose name ++ happens to start with "ibrary", as in -li. We avoid problems by ++ simply turning -l into --library. This means that users will ++ have to use two dashes in order to use --library, which is OK ++ since that's how it is documented. ++ ++ FIXME: It's possible that this problem can arise for other short ++ options as well, although the user does always have the recourse ++ of adding a space between the option and the argument. */ ++ for (i = 1; i < argc; i++) ++ { ++ if (argv[i][0] == '-' ++ && argv[i][1] == 'l' ++ && argv[i][2] != '\0') ++ { ++ char *n; ++ ++ n = (char *) xmalloc (strlen (argv[i]) + 20); ++ sprintf (n, "--library=%s", argv[i] + 2); ++ argv[i] = n; ++ } ++ } ++ ++ last_optind = -1; ++ while (1) ++ { ++ int longind = 0; ++ int optc; ++ static unsigned int defsym_count; ++ ++ /* Using last_optind lets us avoid calling ldemul_parse_args ++ multiple times on a single option, which would lead to ++ confusion in the internal static variables maintained by ++ getopt. This could otherwise happen for an argument like ++ -nx, in which the -n is parsed as a single option, and we ++ loop around to pick up the -x. */ ++ if (optind != last_optind) ++ if (ldemul_parse_args (argc, argv)) ++ continue; ++ ++ /* getopt_long_only is like getopt_long, but '-' as well as '--' ++ can indicate a long option. */ ++ opterr = 0; ++ last_optind = optind; ++ optc = getopt_long_only (argc, argv, shortopts, longopts, &longind); ++ if (optc == '?') ++ { ++ optind = last_optind; ++ optc = getopt_long (argc, argv, "-", really_longopts, &longind); ++ } ++ /* Attempt to detect grouped short options, eg: "-non-start". ++ Accepting such options is error prone as it is not clear if the user ++ intended "-n -o n-start" or "--non-start". */ ++ else if (longind == 0 /* This is a short option. */ ++ && optc > 32 /* It is a valid option. */ ++ /* The character is not the second character of argv[last_optind]. */ ++ && optc != argv[last_optind][1]) ++ { ++ if (optarg) ++ einfo (_("%F%P: Error: unable to disambiguate: %s (did you mean -%s ?)\n"), ++ argv[last_optind], argv[last_optind]); ++ else ++ einfo (_("%P: Warning: grouped short command line options are deprecated: %s\n"), argv[last_optind]); ++ } ++ ++ if (ldemul_handle_option (optc)) ++ continue; ++ ++ if (optc == -1) ++ break; ++ ++ switch (optc) ++ { ++ case '?': ++ { ++ /* If the last word on the command line is an option that ++ requires an argument, getopt will refuse to recognise it. ++ Try to catch such options here and issue a more helpful ++ error message than just "unrecognized option". */ ++ int opt; ++ ++ for (opt = ARRAY_SIZE (ld_options); opt--;) ++ if (ld_options[opt].opt.has_arg == required_argument ++ /* FIXME: There are a few short options that do not ++ have long equivalents, but which require arguments. ++ We should handle them too. */ ++ && ld_options[opt].opt.name != NULL ++ && strcmp (argv[last_optind] + ld_options[opt].control, ld_options[opt].opt.name) == 0) ++ { ++ einfo (_("%P: %s: missing argument\n"), argv[last_optind]); ++ break; ++ } ++ ++ if (opt == -1) ++ einfo (_("%P: unrecognized option '%s'\n"), argv[last_optind]); ++ } ++ /* Fall through. */ ++ ++ default: ++ einfo (_("%F%P: use the --help option for usage information\n")); ++ break; ++ ++ case 1: /* File name. */ ++ lang_add_input_file (optarg, lang_input_file_is_file_enum, NULL); ++ break; ++ ++ case OPTION_IGNORE: ++ break; ++ case 'a': ++ /* For HP/UX compatibility. Actually -a shared should mean ++ ``use only shared libraries'' but, then, we don't ++ currently support shared libraries on HP/UX anyhow. */ ++ if (strcmp (optarg, "archive") == 0) ++ input_flags.dynamic = false; ++ else if (strcmp (optarg, "shared") == 0 ++ || strcmp (optarg, "default") == 0) ++ input_flags.dynamic = true; ++ else ++ einfo (_("%F%P: unrecognized -a option `%s'\n"), optarg); ++ break; ++ case OPTION_ASSERT: ++ /* FIXME: We just ignore these, but we should handle them. */ ++ if (strcmp (optarg, "definitions") == 0) ++ ; ++ else if (strcmp (optarg, "nodefinitions") == 0) ++ ; ++ else if (strcmp (optarg, "nosymbolic") == 0) ++ ; ++ else if (strcmp (optarg, "pure-text") == 0) ++ ; ++ else ++ einfo (_("%F%P: unrecognized -assert option `%s'\n"), optarg); ++ break; ++ case 'A': ++ ldfile_add_arch (optarg); ++ break; ++ case 'b': ++ lang_add_target (optarg); ++ break; ++ case 'c': ++ ldfile_open_command_file (optarg); ++ parser_input = input_mri_script; ++ yyparse (); ++ break; ++ case OPTION_CALL_SHARED: ++ input_flags.dynamic = true; ++ break; ++ case OPTION_NON_SHARED: ++ input_flags.dynamic = false; ++ break; ++ case OPTION_CREF: ++ command_line.cref = true; ++ link_info.notice_all = true; ++ break; ++ case 'd': ++ command_line.force_common_definition = true; ++ break; ++ case OPTION_FORCE_GROUP_ALLOCATION: ++ command_line.force_group_allocation = true; ++ break; ++ case OPTION_DEFSYM: ++ lex_string = optarg; ++ lex_redirect (optarg, "--defsym", ++defsym_count); ++ parser_input = input_defsym; ++ yyparse (); ++ lex_string = NULL; ++ break; ++ case OPTION_DEMANGLE: ++ demangling = true; ++ if (optarg != NULL) ++ { ++ enum demangling_styles style; ++ ++ style = cplus_demangle_name_to_style (optarg); ++ if (style == unknown_demangling) ++ einfo (_("%F%P: unknown demangling style `%s'\n"), ++ optarg); ++ ++ cplus_demangle_set_style (style); ++ } ++ break; ++ case 'I': /* Used on Solaris. */ ++ case OPTION_DYNAMIC_LINKER: ++ command_line.interpreter = optarg; ++ link_info.nointerp = 0; ++ break; ++ case OPTION_NO_DYNAMIC_LINKER: ++ link_info.nointerp = 1; ++ break; ++ case OPTION_SYSROOT: ++ /* Already handled in ldmain.c. */ ++ break; ++ case OPTION_EB: ++ command_line.endian = ENDIAN_BIG; ++ break; ++ case OPTION_EL: ++ command_line.endian = ENDIAN_LITTLE; ++ break; ++ case OPTION_EMBEDDED_RELOCS: ++ command_line.embedded_relocs = true; ++ break; ++ case OPTION_EXPORT_DYNAMIC: ++ case 'E': /* HP/UX compatibility. */ ++ link_info.export_dynamic = true; ++ break; ++ case OPTION_NO_EXPORT_DYNAMIC: ++ link_info.export_dynamic = false; ++ break; ++ case OPTION_NON_CONTIGUOUS_REGIONS: ++ link_info.non_contiguous_regions = true; ++ break; ++ case OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS: ++ link_info.non_contiguous_regions_warnings = true; ++ break; ++ ++ case OPTION_ERROR_EXECSTACK: ++ link_info.error_execstack = 1; ++ break; ++ case OPTION_NO_ERROR_EXECSTACK: ++ link_info.error_execstack = 0; ++ break; ++ case OPTION_WARN_EXECSTACK_OBJECTS: ++ link_info.warn_execstack = 2; ++ break; ++ case OPTION_WARN_EXECSTACK: ++ link_info.warn_execstack = 1; ++ break; ++ case OPTION_NO_WARN_EXECSTACK: ++ link_info.warn_execstack = 0; ++ break; ++ ++ case OPTION_ERROR_RWX_SEGMENTS: ++ link_info.warn_is_error_for_rwx_segments = 1; ++ break; ++ case OPTION_NO_ERROR_RWX_SEGMENTS: ++ link_info.warn_is_error_for_rwx_segments = 0; ++ break; ++ case OPTION_WARN_RWX_SEGMENTS: ++ link_info.no_warn_rwx_segments = 0; ++ link_info.user_warn_rwx_segments = 1; ++ break; ++ case OPTION_NO_WARN_RWX_SEGMENTS: ++ link_info.no_warn_rwx_segments = 1; ++ link_info.user_warn_rwx_segments = 1; ++ break; ++ ++ case 'e': ++ lang_add_entry (optarg, true); ++ break; ++ case 'f': ++ if (command_line.auxiliary_filters == NULL) ++ { ++ command_line.auxiliary_filters = (char **) ++ xmalloc (2 * sizeof (char *)); ++ command_line.auxiliary_filters[0] = optarg; ++ command_line.auxiliary_filters[1] = NULL; ++ } ++ else ++ { ++ int c; ++ char **p; ++ ++ c = 0; ++ for (p = command_line.auxiliary_filters; *p != NULL; p++) ++ ++c; ++ command_line.auxiliary_filters = (char **) ++ xrealloc (command_line.auxiliary_filters, ++ (c + 2) * sizeof (char *)); ++ command_line.auxiliary_filters[c] = optarg; ++ command_line.auxiliary_filters[c + 1] = NULL; ++ } ++ break; ++ case 'F': ++ command_line.filter_shlib = optarg; ++ break; ++ case OPTION_FORCE_EXE_SUFFIX: ++ command_line.force_exe_suffix = true; ++ break; ++ case 'G': ++ { ++ char *end; ++ g_switch_value = strtoul (optarg, &end, 0); ++ if (*end) ++ einfo (_("%F%P: invalid number `%s'\n"), optarg); ++ } ++ break; ++ case 'g': ++ /* Ignore. */ ++ break; ++ case OPTION_GC_SECTIONS: ++ link_info.gc_sections = true; ++ break; ++ case OPTION_PRINT_GC_SECTIONS: ++ link_info.print_gc_sections = true; ++ break; ++ case OPTION_GC_KEEP_EXPORTED: ++ link_info.gc_keep_exported = true; ++ break; ++ case OPTION_HELP: ++ help (); ++ xexit (0); ++ break; ++ case 'L': ++ ldfile_add_library_path (optarg, true); ++ break; ++ case 'l': ++ lang_add_input_file (optarg, lang_input_file_is_l_enum, NULL); ++ break; ++ case 'M': ++ config.map_filename = "-"; ++ break; ++ case 'm': ++ /* Ignore. Was handled in a pre-parse. */ ++ break; ++ case OPTION_MAP: ++ config.map_filename = optarg; ++ break; ++ case 'N': ++ config.text_read_only = false; ++ config.magic_demand_paged = false; ++ input_flags.dynamic = false; ++ break; ++ case OPTION_NO_OMAGIC: ++ config.text_read_only = true; ++ config.magic_demand_paged = true; ++ /* NB/ Does not set input_flags.dynamic to TRUE. ++ Use --call-shared or -Bdynamic for this. */ ++ break; ++ case 'n': ++ config.text_read_only = true; ++ config.magic_demand_paged = false; ++ input_flags.dynamic = false; ++ break; ++ case OPTION_NO_DEFINE_COMMON: ++ link_info.inhibit_common_definition = true; ++ break; ++ case OPTION_NO_DEMANGLE: ++ demangling = false; ++ break; ++ case OPTION_NO_GC_SECTIONS: ++ link_info.gc_sections = false; ++ break; ++ case OPTION_NO_PRINT_GC_SECTIONS: ++ link_info.print_gc_sections = false; ++ break; ++ case OPTION_NO_KEEP_MEMORY: ++ link_info.keep_memory = false; ++ break; ++ case OPTION_NO_UNDEFINED: ++ link_info.unresolved_syms_in_objects = RM_DIAGNOSE; ++ break; ++ case OPTION_ALLOW_SHLIB_UNDEFINED: ++ link_info.unresolved_syms_in_shared_libs = RM_IGNORE; ++ break; ++ case OPTION_NO_ALLOW_SHLIB_UNDEFINED: ++ link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE; ++ break; ++ case OPTION_UNRESOLVED_SYMBOLS: ++ if (strcmp (optarg, "ignore-all") == 0) ++ { ++ link_info.unresolved_syms_in_objects = RM_IGNORE; ++ link_info.unresolved_syms_in_shared_libs = RM_IGNORE; ++ } ++ else if (strcmp (optarg, "report-all") == 0) ++ { ++ link_info.unresolved_syms_in_objects = RM_DIAGNOSE; ++ link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE; ++ } ++ else if (strcmp (optarg, "ignore-in-object-files") == 0) ++ { ++ link_info.unresolved_syms_in_objects = RM_IGNORE; ++ link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE; ++ } ++ else if (strcmp (optarg, "ignore-in-shared-libs") == 0) ++ { ++ link_info.unresolved_syms_in_objects = RM_DIAGNOSE; ++ link_info.unresolved_syms_in_shared_libs = RM_IGNORE; ++ } ++ else ++ einfo (_("%F%P: bad --unresolved-symbols option: %s\n"), optarg); ++ break; ++ case OPTION_WARN_UNRESOLVED_SYMBOLS: ++ link_info.warn_unresolved_syms = true; ++ break; ++ case OPTION_ERROR_UNRESOLVED_SYMBOLS: ++ link_info.warn_unresolved_syms = false; ++ break; ++ case OPTION_ALLOW_MULTIPLE_DEFINITION: ++ link_info.allow_multiple_definition = true; ++ break; ++ ++#if SUPPORT_ERROR_HANDLING_SCRIPT ++ case OPTION_ERROR_HANDLING_SCRIPT: ++ /* FIXME: Should we warn if the script is being overridden by another ? ++ Or maybe they should be chained together ? */ ++ error_handling_script = optarg; ++ break; ++#endif ++ ++ case OPTION_ENABLE_LINKER_VERSION: ++ enable_linker_version = true; ++ break; ++ case OPTION_DISABLE_LINKER_VERSION: ++ enable_linker_version = false; ++ break; ++ ++ case OPTION_UNDEFINED_VERSION: ++ link_info.allow_undefined_version = true; ++ break; ++ case OPTION_NO_UNDEFINED_VERSION: ++ link_info.allow_undefined_version = false; ++ break; ++ case OPTION_DEFAULT_SYMVER: ++ link_info.create_default_symver = true; ++ break; ++ case OPTION_DEFAULT_IMPORTED_SYMVER: ++ link_info.default_imported_symver = true; ++ break; ++ case OPTION_NO_WARN_MISMATCH: ++ command_line.warn_mismatch = false; ++ break; ++ case OPTION_NO_WARN_SEARCH_MISMATCH: ++ command_line.warn_search_mismatch = false; ++ break; ++ case OPTION_NOINHIBIT_EXEC: ++ force_make_executable = true; ++ break; ++ case OPTION_NOSTDLIB: ++ config.only_cmd_line_lib_dirs = true; ++ break; ++ case OPTION_NO_WHOLE_ARCHIVE: ++ input_flags.whole_archive = false; ++ break; ++ case 'O': ++ /* FIXME "-O " used to set the address of ++ section . Was this for compatibility with ++ something, or can we create a new option to do that ++ (with a syntax similar to -defsym)? ++ getopt can't handle two args to an option without kludges. */ ++ ++ /* Enable optimizations of output files. */ ++ link_info.optimize = strtoul (optarg, NULL, 0) != 0; ++ break; ++ case 'o': ++ lang_add_output (optarg, 0); ++ break; ++ case OPTION_OFORMAT: ++ lang_add_output_format (optarg, NULL, NULL, 0); ++ break; ++ case OPTION_OUT_IMPLIB: ++ command_line.out_implib_filename = xstrdup (optarg); ++ break; ++ case OPTION_PRINT_SYSROOT: ++ if (*ld_sysroot) ++ puts (ld_sysroot); ++ xexit (0); ++ break; ++ case OPTION_PRINT_OUTPUT_FORMAT: ++ command_line.print_output_format = true; ++ break; ++#if BFD_SUPPORTS_PLUGINS ++ case OPTION_PLUGIN: ++ plugin_opt_plugin (optarg); ++ break; ++ case OPTION_PLUGIN_OPT: ++ if (plugin_opt_plugin_arg (optarg)) ++ einfo (_("%F%P: bad -plugin-opt option\n")); ++ break; ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ case 'q': ++ link_info.emitrelocations = true; ++ break; ++ case 'i': ++ case 'r': ++ if (optind == last_optind) ++ /* This can happen if the user put "-rpath,a" on the command ++ line. (Or something similar. The comma is important). ++ Getopt becomes confused and thinks that this is a -r option ++ but it cannot parse the text after the -r so it refuses to ++ increment the optind counter. Detect this case and issue ++ an error message here. We cannot just make this a warning, ++ increment optind, and continue because getopt is too confused ++ and will seg-fault the next time around. */ ++ einfo(_("%F%P: unrecognised option: %s\n"), argv[optind]); ++ ++ if (bfd_link_pic (&link_info)) ++ einfo (_("%F%P: -r and %s may not be used together\n"), ++ bfd_link_dll (&link_info) ? "-shared" : "-pie"); ++ ++ link_info.type = type_relocatable; ++ config.build_constructors = false; ++ config.magic_demand_paged = false; ++ config.text_read_only = false; ++ input_flags.dynamic = false; ++ break; ++ case 'R': ++ /* The GNU linker traditionally uses -R to mean to include ++ only the symbols from a file. The Solaris linker uses -R ++ to set the path used by the runtime linker to find ++ libraries. This is the GNU linker -rpath argument. We ++ try to support both simultaneously by checking the file ++ named. If it is a directory, rather than a regular file, ++ we assume -rpath was meant. */ ++ { ++ struct stat s; ++ ++ if (stat (optarg, &s) >= 0 ++ && ! S_ISDIR (s.st_mode)) ++ { ++ lang_add_input_file (optarg, ++ lang_input_file_is_symbols_only_enum, ++ NULL); ++ break; ++ } ++ } ++ /* Fall through. */ ++ case OPTION_RPATH: ++ if (command_line.rpath == NULL) ++ command_line.rpath = xstrdup (optarg); ++ else ++ { ++ size_t rpath_len = strlen (command_line.rpath); ++ size_t optarg_len = strlen (optarg); ++ char *buf; ++ char *cp = command_line.rpath; ++ ++ /* First see whether OPTARG is already in the path. */ ++ do ++ { ++ if (strncmp (optarg, cp, optarg_len) == 0 ++ && (cp[optarg_len] == 0 ++ || cp[optarg_len] == config.rpath_separator)) ++ /* We found it. */ ++ break; ++ ++ /* Not yet found. */ ++ cp = strchr (cp, config.rpath_separator); ++ if (cp != NULL) ++ ++cp; ++ } ++ while (cp != NULL); ++ ++ if (cp == NULL) ++ { ++ buf = (char *) xmalloc (rpath_len + optarg_len + 2); ++ sprintf (buf, "%s%c%s", command_line.rpath, ++ config.rpath_separator, optarg); ++ free (command_line.rpath); ++ command_line.rpath = buf; ++ } ++ } ++ break; ++ case OPTION_RPATH_LINK: ++ if (command_line.rpath_link == NULL) ++ command_line.rpath_link = xstrdup (optarg); ++ else ++ { ++ char *buf; ++ ++ buf = (char *) xmalloc (strlen (command_line.rpath_link) ++ + strlen (optarg) ++ + 2); ++ sprintf (buf, "%s%c%s", command_line.rpath_link, ++ config.rpath_separator, optarg); ++ free (command_line.rpath_link); ++ command_line.rpath_link = buf; ++ } ++ break; ++ case OPTION_NO_RELAX: ++ DISABLE_RELAXATION; ++ break; ++ case OPTION_RELAX: ++ ENABLE_RELAXATION; ++ break; ++ case OPTION_RETAIN_SYMBOLS_FILE: ++ add_keepsyms_file (optarg); ++ break; ++ case 'S': ++ link_info.strip = strip_debugger; ++ break; ++ case 's': ++ link_info.strip = strip_all; ++ break; ++ case OPTION_STRIP_DISCARDED: ++ link_info.strip_discarded = true; ++ break; ++ case OPTION_NO_STRIP_DISCARDED: ++ link_info.strip_discarded = false; ++ break; ++ case OPTION_DISABLE_MULTIPLE_DEFS_ABS: ++ link_info.prohibit_multiple_definition_absolute = true; ++ break; ++ case OPTION_SHARED: ++ if (config.has_shared) ++ { ++ if (bfd_link_relocatable (&link_info)) ++ einfo (_("%F%P: -r and %s may not be used together\n"), ++ "-shared"); ++ ++ link_info.type = type_dll; ++ /* When creating a shared library, the default ++ behaviour is to ignore any unresolved references. */ ++ if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET) ++ link_info.unresolved_syms_in_objects = RM_IGNORE; ++ if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET) ++ link_info.unresolved_syms_in_shared_libs = RM_IGNORE; ++ } ++ else ++ einfo (_("%F%P: -shared not supported\n")); ++ break; ++ case OPTION_NO_PIE: ++ link_info.type = type_pde; ++ break; ++ case OPTION_PIE: ++ if (config.has_shared) ++ { ++ if (bfd_link_relocatable (&link_info)) ++ einfo (_("%F%P: -r and %s may not be used together\n"), "-pie"); ++ ++ link_info.type = type_pie; ++ } ++ else ++ einfo (_("%F%P: -pie not supported\n")); ++ break; ++ case 'h': /* Used on Solaris. */ ++ case OPTION_SONAME: ++ if (optarg[0] == '\0' && command_line.soname ++ && command_line.soname[0]) ++ einfo (_("%P: SONAME must not be empty string; keeping previous one\n")); ++ else ++ command_line.soname = optarg; ++ break; ++ case OPTION_SORT_COMMON: ++ if (optarg == NULL ++ || strcmp (optarg, N_("descending")) == 0) ++ config.sort_common = sort_descending; ++ else if (strcmp (optarg, N_("ascending")) == 0) ++ config.sort_common = sort_ascending; ++ else ++ einfo (_("%F%P: invalid common section sorting option: %s\n"), ++ optarg); ++ break; ++ case OPTION_SORT_SECTION: ++ if (strcmp (optarg, N_("name")) == 0) ++ sort_section = by_name; ++ else if (strcmp (optarg, N_("alignment")) == 0) ++ sort_section = by_alignment; ++ else ++ einfo (_("%F%P: invalid section sorting option: %s\n"), ++ optarg); ++ break; ++ case OPTION_STATS: ++ config.stats = true; ++ break; ++ case OPTION_NO_SYMBOLIC: ++ opt_symbolic = symbolic_unset; ++ break; ++ case OPTION_SYMBOLIC: ++ opt_symbolic = symbolic; ++ break; ++ case OPTION_SYMBOLIC_FUNCTIONS: ++ opt_symbolic = symbolic_functions; ++ break; ++ case 't': ++ ++trace_files; ++ break; ++ case 'T': ++ previous_script_handle = saved_script_handle; ++ ldfile_open_script_file (optarg); ++ parser_input = input_script; ++ yyparse (); ++ previous_script_handle = NULL; ++ break; ++ case OPTION_DEFAULT_SCRIPT: ++ command_line.default_script = optarg; ++ break; ++ case OPTION_SECTION_START: ++ { ++ char *optarg2; ++ char *sec_name; ++ int len; ++ ++ /* Check for =... */ ++ optarg2 = strchr (optarg, '='); ++ if (optarg2 == NULL) ++ einfo (_("%F%P: invalid argument to option" ++ " \"--section-start\"\n")); ++ ++ optarg2++; ++ ++ /* So far so good. Are all the args present? */ ++ if ((*optarg == '\0') || (*optarg2 == '\0')) ++ einfo (_("%F%P: missing argument(s) to option" ++ " \"--section-start\"\n")); ++ ++ /* We must copy the section name as set_section_start ++ doesn't do it for us. */ ++ len = optarg2 - optarg; ++ sec_name = (char *) xmalloc (len); ++ memcpy (sec_name, optarg, len - 1); ++ sec_name[len - 1] = 0; ++ ++ /* Then set it... */ ++ set_section_start (sec_name, optarg2); ++ } ++ break; ++ case OPTION_TARGET_HELP: ++ /* Mention any target specific options. */ ++ ldemul_list_emulation_options (stdout); ++ exit (0); ++ case OPTION_TBSS: ++ set_segment_start (".bss", optarg); ++ break; ++ case OPTION_TDATA: ++ set_segment_start (".data", optarg); ++ break; ++ case OPTION_TTEXT: ++ set_segment_start (".text", optarg); ++ break; ++ case OPTION_TTEXT_SEGMENT: ++ set_segment_start (".text-segment", optarg); ++ break; ++ case OPTION_TRODATA_SEGMENT: ++ set_segment_start (".rodata-segment", optarg); ++ break; ++ case OPTION_TLDATA_SEGMENT: ++ set_segment_start (".ldata-segment", optarg); ++ break; ++ case OPTION_TRADITIONAL_FORMAT: ++ link_info.traditional_format = true; ++ break; ++ case OPTION_TASK_LINK: ++ link_info.task_link = true; ++ /* Fall through. */ ++ case OPTION_UR: ++ if (bfd_link_pic (&link_info)) ++ einfo (_("%F%P: -r and %s may not be used together\n"), ++ bfd_link_dll (&link_info) ? "-shared" : "-pie"); ++ ++ link_info.type = type_relocatable; ++ config.build_constructors = true; ++ config.magic_demand_paged = false; ++ config.text_read_only = false; ++ input_flags.dynamic = false; ++ break; ++ case 'u': ++ ldlang_add_undef (optarg, true); ++ break; ++ case OPTION_REQUIRE_DEFINED_SYMBOL: ++ ldlang_add_require_defined (optarg); ++ break; ++ case OPTION_UNIQUE: ++ if (optarg != NULL) ++ lang_add_unique (optarg); ++ else ++ config.unique_orphan_sections = true; ++ break; ++ case OPTION_VERBOSE: ++ ldversion (1); ++ version_printed = true; ++ verbose = true; ++ overflow_cutoff_limit = -2; ++ if (optarg != NULL) ++ { ++ char *end; ++ int level ATTRIBUTE_UNUSED = strtoul (optarg, &end, 0); ++ if (*end) ++ einfo (_("%F%P: invalid number `%s'\n"), optarg); ++#if BFD_SUPPORTS_PLUGINS ++ report_plugin_symbols = level > 1; ++#endif /* BFD_SUPPORTS_PLUGINS */ ++ } ++ break; ++ case 'v': ++ ldversion (0); ++ version_printed = true; ++ break; ++ case 'V': ++ ldversion (1); ++ version_printed = true; ++ break; ++ case OPTION_VERSION: ++ ldversion (2); ++ xexit (0); ++ break; ++ case OPTION_VERSION_SCRIPT: ++ /* This option indicates a small script that only specifies ++ version information. Read it, but don't assume that ++ we've seen a linker script. */ ++ { ++ FILE *hold_script_handle; ++ ++ hold_script_handle = saved_script_handle; ++ ldfile_open_command_file (optarg); ++ saved_script_handle = hold_script_handle; ++ parser_input = input_version_script; ++ yyparse (); ++ } ++ break; ++ case OPTION_VERSION_EXPORTS_SECTION: ++ /* This option records a version symbol to be applied to the ++ symbols listed for export to be found in the object files ++ .exports sections. */ ++ command_line.version_exports_section = optarg; ++ break; ++ case OPTION_DYNAMIC_LIST_DATA: ++ opt_dynamic_list = dynamic_list_data; ++ break; ++ case OPTION_DYNAMIC_LIST_CPP_TYPEINFO: ++ lang_append_dynamic_list_cpp_typeinfo (); ++ if (opt_dynamic_list != dynamic_list_data) ++ opt_dynamic_list = dynamic_list; ++ break; ++ case OPTION_DYNAMIC_LIST_CPP_NEW: ++ lang_append_dynamic_list_cpp_new (); ++ if (opt_dynamic_list != dynamic_list_data) ++ opt_dynamic_list = dynamic_list; ++ break; ++ case OPTION_DYNAMIC_LIST: ++ /* This option indicates a small script that only specifies ++ a dynamic list. Read it, but don't assume that we've ++ seen a linker script. */ ++ { ++ FILE *hold_script_handle; ++ ++ hold_script_handle = saved_script_handle; ++ ldfile_open_command_file (optarg); ++ saved_script_handle = hold_script_handle; ++ parser_input = input_dynamic_list; ++ current_dynamic_list_p = &link_info.dynamic_list; ++ yyparse (); ++ } ++ if (opt_dynamic_list != dynamic_list_data) ++ opt_dynamic_list = dynamic_list; ++ break; ++ case OPTION_EXPORT_DYNAMIC_SYMBOL: ++ { ++ struct bfd_elf_version_expr *expr ++ = lang_new_vers_pattern (NULL, xstrdup (optarg), NULL, ++ false); ++ lang_append_dynamic_list (&export_list, expr); ++ } ++ break; ++ case OPTION_EXPORT_DYNAMIC_SYMBOL_LIST: ++ /* This option indicates a small script that only specifies ++ an export list. Read it, but don't assume that we've ++ seen a linker script. */ ++ { ++ FILE *hold_script_handle; ++ ++ hold_script_handle = saved_script_handle; ++ ldfile_open_command_file (optarg); ++ saved_script_handle = hold_script_handle; ++ parser_input = input_dynamic_list; ++ current_dynamic_list_p = &export_list; ++ yyparse (); ++ } ++ break; ++ case OPTION_WARN_COMMON: ++ config.warn_common = true; ++ break; ++ case OPTION_WARN_CONSTRUCTORS: ++ config.warn_constructors = true; ++ break; ++ case OPTION_WARN_FATAL: ++ config.fatal_warnings = true; ++ break; ++ case OPTION_NO_WARN_FATAL: ++ config.fatal_warnings = false; ++ break; ++ case OPTION_NO_WARNINGS: ++ case 'w': ++ config.no_warnings = true; ++ config.fatal_warnings = false; ++ break; ++ case OPTION_WARN_MULTIPLE_GP: ++ config.warn_multiple_gp = true; ++ break; ++ case OPTION_WARN_ONCE: ++ config.warn_once = true; ++ break; ++ case OPTION_WARN_SECTION_ALIGN: ++ config.warn_section_align = true; ++ break; ++ case OPTION_WARN_TEXTREL: ++ link_info.textrel_check = textrel_check_warning; ++ break; ++ case OPTION_WARN_ALTERNATE_EM: ++ link_info.warn_alternate_em = true; ++ break; ++ case OPTION_WHOLE_ARCHIVE: ++ input_flags.whole_archive = true; ++ break; ++ case OPTION_ADD_DT_NEEDED_FOR_DYNAMIC: ++ input_flags.add_DT_NEEDED_for_dynamic = true; ++ break; ++ case OPTION_NO_ADD_DT_NEEDED_FOR_DYNAMIC: ++ input_flags.add_DT_NEEDED_for_dynamic = false; ++ break; ++ case OPTION_ADD_DT_NEEDED_FOR_REGULAR: ++ input_flags.add_DT_NEEDED_for_regular = true; ++ break; ++ case OPTION_NO_ADD_DT_NEEDED_FOR_REGULAR: ++ input_flags.add_DT_NEEDED_for_regular = false; ++ break; ++ case OPTION_WRAP: ++ add_wrap (optarg); ++ break; ++ case OPTION_IGNORE_UNRESOLVED_SYMBOL: ++ add_ignoresym (&link_info, optarg); ++ break; ++ case OPTION_DISCARD_NONE: ++ link_info.discard = discard_none; ++ break; ++ case 'X': ++ link_info.discard = discard_l; ++ break; ++ case 'x': ++ link_info.discard = discard_all; ++ break; ++ case 'Y': ++ if (startswith (optarg, "P,")) ++ optarg += 2; ++ free (default_dirlist); ++ default_dirlist = xstrdup (optarg); ++ break; ++ case 'y': ++ add_ysym (optarg); ++ break; ++ case OPTION_SPARE_DYNAMIC_TAGS: ++ link_info.spare_dynamic_tags = strtoul (optarg, NULL, 0); ++ break; ++ case OPTION_SPLIT_BY_RELOC: ++ if (optarg != NULL) ++ config.split_by_reloc = strtoul (optarg, NULL, 0); ++ else ++ config.split_by_reloc = 32768; ++ break; ++ case OPTION_SPLIT_BY_FILE: ++ if (optarg != NULL) ++ config.split_by_file = bfd_scan_vma (optarg, NULL, 0); ++ else ++ config.split_by_file = 1; ++ break; ++ case OPTION_CHECK_SECTIONS: ++ command_line.check_section_addresses = 1; ++ break; ++ case OPTION_NO_CHECK_SECTIONS: ++ command_line.check_section_addresses = 0; ++ break; ++ case OPTION_ACCEPT_UNKNOWN_INPUT_ARCH: ++ command_line.accept_unknown_input_arch = true; ++ break; ++ case OPTION_NO_ACCEPT_UNKNOWN_INPUT_ARCH: ++ command_line.accept_unknown_input_arch = false; ++ break; ++ case '(': ++ lang_enter_group (); ++ ingroup++; ++ break; ++ case ')': ++ if (! ingroup) ++ einfo (_("%F%P: group ended before it began (--help for usage)\n")); ++ ++ lang_leave_group (); ++ ingroup--; ++ break; ++ ++ case OPTION_INIT: ++ link_info.init_function = optarg; ++ break; ++ ++ case OPTION_FINI: ++ link_info.fini_function = optarg; ++ break; ++ ++ case OPTION_REMAP_INPUTS_FILE: ++ if (! ldfile_add_remap_file (optarg)) ++ einfo (_("%F%P: failed to add remap file %s\n"), optarg); ++ break; ++ ++ case OPTION_REMAP_INPUTS: ++ { ++ char *optarg2 = strchr (optarg, '='); ++ if (optarg2 == NULL) ++ /* FIXME: Should we allow --remap-inputs=@myfile as a synonym ++ for --remap-inputs-file=myfile ? */ ++ einfo (_("%F%P: invalid argument to option --remap-inputs\n")); ++ size_t len = optarg2 - optarg; ++ char * pattern = xmalloc (len + 1); ++ memcpy (pattern, optarg, len); ++ pattern[len] = 0; ++ ldfile_add_remap (pattern, optarg2 + 1); ++ free (pattern); ++ } ++ break; ++ ++ case OPTION_REDUCE_MEMORY_OVERHEADS: ++ link_info.reduce_memory_overheads = true; ++ if (config.hash_table_size == 0) ++ config.hash_table_size = 1021; ++ break; ++ ++ case OPTION_MAX_CACHE_SIZE: ++ { ++ char *end; ++ bfd_size_type cache_size = strtoul (optarg, &end, 0); ++ if (*end != '\0') ++ einfo (_("%F%P: invalid cache memory size: %s\n"), ++ optarg); ++ link_info.max_cache_size = cache_size; ++ } ++ break; ++ ++ case OPTION_HASH_SIZE: ++ { ++ bfd_size_type new_size; ++ ++ new_size = strtoul (optarg, NULL, 0); ++ if (new_size) ++ config.hash_table_size = new_size; ++ else ++ einfo (_("%X%P: --hash-size needs a numeric argument\n")); ++ } ++ break; ++ ++ case OPTION_PUSH_STATE: ++ input_flags.pushed = xmemdup (&input_flags, ++ sizeof (input_flags), ++ sizeof (input_flags)); ++ break; ++ ++ case OPTION_POP_STATE: ++ if (input_flags.pushed == NULL) ++ einfo (_("%F%P: no state pushed before popping\n")); ++ else ++ { ++ struct lang_input_statement_flags *oldp = input_flags.pushed; ++ memcpy (&input_flags, oldp, sizeof (input_flags)); ++ free (oldp); ++ } ++ break; ++ ++ case OPTION_PRINT_MEMORY_USAGE: ++ command_line.print_memory_usage = true; ++ break; ++ ++ case OPTION_ORPHAN_HANDLING: ++ if (strcasecmp (optarg, "place") == 0) ++ config.orphan_handling = orphan_handling_place; ++ else if (strcasecmp (optarg, "warn") == 0) ++ config.orphan_handling = orphan_handling_warn; ++ else if (strcasecmp (optarg, "error") == 0) ++ config.orphan_handling = orphan_handling_error; ++ else if (strcasecmp (optarg, "discard") == 0) ++ config.orphan_handling = orphan_handling_discard; ++ else ++ einfo (_("%F%P: invalid argument to option" ++ " \"--orphan-handling\"\n")); ++ break; ++ ++ case OPTION_NO_PRINT_MAP_DISCARDED: ++ config.print_map_discarded = false; ++ break; ++ ++ case OPTION_PRINT_MAP_DISCARDED: ++ config.print_map_discarded = true; ++ break; ++ ++ case OPTION_NO_PRINT_MAP_LOCALS: ++ config.print_map_locals = false; ++ break; ++ ++ case OPTION_PRINT_MAP_LOCALS: ++ config.print_map_locals = true; ++ break; ++ ++ case OPTION_DEPENDENCY_FILE: ++ config.dependency_file = optarg; ++ break; ++ ++ case OPTION_CTF_VARIABLES: ++ config.ctf_variables = true; ++ break; ++ ++ case OPTION_NO_CTF_VARIABLES: ++ config.ctf_variables = false; ++ break; ++ ++ case OPTION_CTF_SHARE_TYPES: ++ if (strcmp (optarg, "share-unconflicted") == 0) ++ config.ctf_share_duplicated = false; ++ else if (strcmp (optarg, "share-duplicated") == 0) ++ config.ctf_share_duplicated = true; ++ else ++ einfo (_("%F%P: bad --ctf-share-types option: %s\n"), optarg); ++ break; ++ } ++ } ++ ++ free (really_longopts); ++ free (longopts); ++ free (shortopts); ++ ++ /* Run a couple of checks on the map filename. */ ++ if (config.map_filename) ++ { ++ char * new_name = NULL; ++ char * percent; ++ int res = 0; ++ ++ if (config.map_filename[0] == 0) ++ { ++ einfo (_("%P: no file/directory name provided for map output; ignored\n")); ++ config.map_filename = NULL; ++ } ++ else if (strcmp (config.map_filename, "-") == 0) ++ ; /* Write to stdout. Handled in main(). */ ++ else if ((percent = strchr (config.map_filename, '%')) != NULL) ++ { ++ /* FIXME: Check for a second % character and issue an error ? */ ++ ++ /* Construct a map file by replacing the % character with the (full) ++ output filename. If the % character was the last character in ++ the original map filename then add a .map extension. */ ++ percent[0] = 0; ++ res = asprintf (&new_name, "%s%s%s", config.map_filename, ++ output_filename, ++ percent[1] ? percent + 1 : ".map"); ++ ++ /* FIXME: Should we ensure that any directory components in new_name exist ? */ ++ } ++ else ++ { ++ struct stat s; ++ ++ /* If the map filename is actually a directory then create ++ a file inside it, based upon the output filename. */ ++ if (stat (config.map_filename, &s) < 0) ++ { ++ if (errno != ENOENT) ++ einfo (_("%P: cannot stat linker map file: %E\n")); ++ } ++ else if (S_ISDIR (s.st_mode)) ++ { ++ char lastc = config.map_filename[strlen (config.map_filename) - 1]; ++ res = asprintf (&new_name, "%s%s%s.map", ++ config.map_filename, ++ IS_DIR_SEPARATOR (lastc) ? "" : "/", ++ lbasename (output_filename)); ++ } ++ else if (! S_ISREG (s.st_mode)) ++ { ++ einfo (_("%P: linker map file is not a regular file\n")); ++ config.map_filename = NULL; ++ } ++ /* else FIXME: Check write permission ? */ ++ } ++ ++ if (res < 0) ++ { ++ /* If the asprintf failed then something is probably very ++ wrong. Better to halt now rather than continue on ++ into more problems. */ ++ einfo (_("%P%F: cannot create name for linker map file: %E\n")); ++ } ++ else if (new_name != NULL) ++ { ++ /* This is a trivial memory leak. */ ++ config.map_filename = new_name; ++ } ++ } ++ ++ if (command_line.soname && command_line.soname[0] == '\0') ++ { ++ einfo (_("%P: SONAME must not be empty string; ignored\n")); ++ command_line.soname = NULL; ++ } ++ ++ while (ingroup) ++ { ++ einfo (_("%P: missing --end-group; added as last command line option\n")); ++ lang_leave_group (); ++ ingroup--; ++ } ++ ++ if (default_dirlist != NULL) ++ { ++ set_default_dirlist (default_dirlist); ++ free (default_dirlist); ++ } ++ ++ if (link_info.unresolved_syms_in_objects == RM_NOT_YET_SET) ++ /* FIXME: Should we allow emulations a chance to set this ? */ ++ link_info.unresolved_syms_in_objects = RM_DIAGNOSE; ++ ++ if (link_info.unresolved_syms_in_shared_libs == RM_NOT_YET_SET) ++ /* FIXME: Should we allow emulations a chance to set this ? */ ++ link_info.unresolved_syms_in_shared_libs = RM_DIAGNOSE; ++ ++ if (bfd_link_relocatable (&link_info) ++ && command_line.check_section_addresses < 0) ++ command_line.check_section_addresses = 0; ++ ++ if (export_list) ++ { ++ struct bfd_elf_version_expr *head = export_list->head.list; ++ struct bfd_elf_version_expr *next; ++ ++ /* For --export-dynamic-symbol[-list]: ++ 1. When building executable, treat like --dynamic-list. ++ 2. When building shared object: ++ a. If -Bsymbolic or --dynamic-list are used, treat like ++ --dynamic-list. ++ b. Otherwise, ignored. ++ */ ++ if (!bfd_link_relocatable (&link_info) ++ && (bfd_link_executable (&link_info) ++ || opt_symbolic != symbolic_unset ++ || opt_dynamic_list != dynamic_list_unset)) ++ { ++ /* Append the export list to link_info.dynamic_list. */ ++ if (link_info.dynamic_list) ++ { ++ for (next = head; next->next != NULL; next = next->next) ++ ; ++ next->next = link_info.dynamic_list->head.list; ++ link_info.dynamic_list->head.list = head; ++ } ++ else ++ link_info.dynamic_list = export_list; ++ ++ if (opt_dynamic_list != dynamic_list_data) ++ opt_dynamic_list = dynamic_list; ++ } ++ else ++ { ++ /* Free the export list. */ ++ for (; head->next != NULL; head = next) ++ { ++ next = head->next; ++ free (head); ++ } ++ free (export_list); ++ } ++ } ++ ++ switch (opt_dynamic_list) ++ { ++ case dynamic_list_unset: ++ break; ++ case dynamic_list_data: ++ link_info.dynamic_data = true; ++ /* Fall through. */ ++ case dynamic_list: ++ link_info.dynamic = true; ++ opt_symbolic = symbolic_unset; ++ break; ++ } ++ ++ /* -Bsymbolic and -Bsymbols-functions are for shared library output. */ ++ if (bfd_link_dll (&link_info)) ++ switch (opt_symbolic) ++ { ++ case symbolic_unset: ++ break; ++ case symbolic: ++ link_info.symbolic = true; ++ if (link_info.dynamic_list) ++ { ++ struct bfd_elf_version_expr *ent, *next; ++ for (ent = link_info.dynamic_list->head.list; ent; ent = next) ++ { ++ next = ent->next; ++ free (ent); ++ } ++ free (link_info.dynamic_list); ++ link_info.dynamic_list = NULL; ++ } ++ break; ++ case symbolic_functions: ++ link_info.dynamic = true; ++ link_info.dynamic_data = true; ++ break; ++ } ++ ++ /* -z nosectionheader implies --strip-all. */ ++ if (config.no_section_header) ++ { ++ if (bfd_link_relocatable (&link_info)) ++ einfo (_("%F%P: -r and -z nosectionheader may not be used together\n")); ++ ++ link_info.strip = strip_all; ++ } ++ ++ if (!bfd_link_dll (&link_info)) ++ { ++ if (command_line.filter_shlib) ++ einfo (_("%F%P: -F may not be used without -shared\n")); ++ if (command_line.auxiliary_filters) ++ einfo (_("%F%P: -f may not be used without -shared\n")); ++ } ++ ++ /* Treat ld -r -s as ld -r -S -x (i.e., strip all local symbols). I ++ don't see how else this can be handled, since in this case we ++ must preserve all externally visible symbols. */ ++ if (bfd_link_relocatable (&link_info) && link_info.strip == strip_all) ++ { ++ link_info.strip = strip_debugger; ++ if (link_info.discard == discard_sec_merge) ++ link_info.discard = discard_all; ++ } ++} ++ ++/* Add the (colon-separated) elements of DIRLIST_PTR to the ++ library search path. */ ++ ++static void ++set_default_dirlist (char *dirlist_ptr) ++{ ++ char *p; ++ ++ while (1) ++ { ++ p = strchr (dirlist_ptr, PATH_SEPARATOR); ++ if (p != NULL) ++ *p = '\0'; ++ if (*dirlist_ptr != '\0') ++ ldfile_add_library_path (dirlist_ptr, true); ++ if (p == NULL) ++ break; ++ dirlist_ptr = p + 1; ++ } ++} ++ ++static void ++set_section_start (char *sect, char *valstr) ++{ ++ const char *end; ++ bfd_vma val = bfd_scan_vma (valstr, &end, 16); ++ if (*end) ++ einfo (_("%F%P: invalid hex number `%s'\n"), valstr); ++ lang_section_start (sect, exp_intop (val), NULL); ++} ++ ++static void ++set_segment_start (const char *section, char *valstr) ++{ ++ const char *name; ++ const char *end; ++ segment_type *seg; ++ ++ bfd_vma val = bfd_scan_vma (valstr, &end, 16); ++ if (*end) ++ einfo (_("%F%P: invalid hex number `%s'\n"), valstr); ++ /* If we already have an entry for this segment, update the existing ++ value. */ ++ name = section + 1; ++ for (seg = segments; seg; seg = seg->next) ++ if (strcmp (seg->name, name) == 0) ++ { ++ seg->value = val; ++ lang_section_start (section, exp_intop (val), seg); ++ return; ++ } ++ /* There was no existing value so we must create a new segment ++ entry. */ ++ seg = stat_alloc (sizeof (*seg)); ++ seg->name = name; ++ seg->value = val; ++ seg->used = false; ++ /* Add it to the linked list of segments. */ ++ seg->next = segments; ++ segments = seg; ++ /* Historically, -Ttext and friends set the base address of a ++ particular section. For backwards compatibility, we still do ++ that. If a SEGMENT_START directive is seen, the section address ++ assignment will be disabled. */ ++ lang_section_start (section, exp_intop (val), seg); ++} ++ ++static void ++elf_shlib_list_options (FILE *file) ++{ ++ fprintf (file, _("\ ++ --audit=AUDITLIB Specify a library to use for auditing\n")); ++ fprintf (file, _("\ ++ -Bgroup Selects group name lookup rules for DSO\n")); ++ fprintf (file, _("\ ++ --disable-new-dtags Disable new dynamic tags\n")); ++ fprintf (file, _("\ ++ --enable-new-dtags Enable new dynamic tags\n")); ++ fprintf (file, _("\ ++ --eh-frame-hdr Create .eh_frame_hdr section\n")); ++ fprintf (file, _("\ ++ --no-eh-frame-hdr Do not create .eh_frame_hdr section\n")); ++ fprintf (file, _("\ ++ --exclude-libs=LIBS Make all symbols in LIBS hidden\n")); ++ fprintf (file, _("\ ++ --hash-style=STYLE Set hash style to sysv/gnu/both. Default: ")); ++ if (DEFAULT_EMIT_SYSV_HASH) ++ { ++ /* Note - these strings are not translated as ++ they are keywords not descriptive text. */ ++ if (DEFAULT_EMIT_GNU_HASH) ++ fprintf (file, "both\n"); ++ else ++ fprintf (file, "sysv\n"); ++ } ++ else ++ { ++ if (DEFAULT_EMIT_GNU_HASH) ++ fprintf (file, "gnu\n"); ++ else ++ /* FIXME: Can this happen ? */ ++ fprintf (file, "none\n"); ++ } ++ fprintf (file, _("\ ++ -P AUDITLIB, --depaudit=AUDITLIB\n" "\ ++ Specify a library to use for auditing dependencies\n")); ++ fprintf (file, _("\ ++ -z combreloc Merge dynamic relocs into one section and sort\n")); ++ fprintf (file, _("\ ++ -z nocombreloc Don't merge dynamic relocs into one section\n")); ++ fprintf (file, _("\ ++ -z global Make symbols in DSO available for subsequently\n\ ++ loaded objects\n")); ++ fprintf (file, _("\ ++ -z initfirst Mark DSO to be initialized first at runtime\n")); ++ fprintf (file, _("\ ++ -z interpose Mark object to interpose all DSOs but executable\n")); ++ fprintf (file, _("\ ++ -z unique Mark DSO to be loaded at most once by default, and only in the main namespace\n")); ++ fprintf (file, _("\ ++ -z nounique Don't mark DSO as a loadable at most once\n")); ++ fprintf (file, _("\ ++ -z lazy Mark object lazy runtime binding (default)\n")); ++ fprintf (file, _("\ ++ -z loadfltr Mark object requiring immediate process\n")); ++ fprintf (file, _("\ ++ -z nocopyreloc Don't create copy relocs\n")); ++ fprintf (file, _("\ ++ -z nodefaultlib Mark object not to use default search paths\n")); ++ fprintf (file, _("\ ++ -z nodelete Mark DSO non-deletable at runtime\n")); ++ fprintf (file, _("\ ++ -z nodlopen Mark DSO not available to dlopen\n")); ++ fprintf (file, _("\ ++ -z nodump Mark DSO not available to dldump\n")); ++ fprintf (file, _("\ ++ -z now Mark object non-lazy runtime binding\n")); ++ fprintf (file, _("\ ++ -z origin Mark object requiring immediate $ORIGIN\n\ ++ processing at runtime\n")); ++#if DEFAULT_LD_Z_RELRO ++ fprintf (file, _("\ ++ -z relro Create RELRO program header (default)\n")); ++ fprintf (file, _("\ ++ -z norelro Don't create RELRO program header\n")); ++#else ++ fprintf (file, _("\ ++ -z relro Create RELRO program header\n")); ++ fprintf (file, _("\ ++ -z norelro Don't create RELRO program header (default)\n")); ++#endif ++#if DEFAULT_LD_Z_SEPARATE_CODE ++ fprintf (file, _("\ ++ -z separate-code Create separate code program header (default)\n")); ++ fprintf (file, _("\ ++ -z noseparate-code Don't create separate code program header\n")); ++#else ++ fprintf (file, _("\ ++ -z separate-code Create separate code program header\n")); ++ fprintf (file, _("\ ++ -z noseparate-code Don't create separate code program header (default)\n")); ++#endif ++ fprintf (file, _("\ ++ -z common Generate common symbols with STT_COMMON type\n")); ++ fprintf (file, _("\ ++ -z nocommon Generate common symbols with STT_OBJECT type\n")); ++ if (link_info.textrel_check == textrel_check_error) ++ fprintf (file, _("\ ++ -z text Treat DT_TEXTREL in output as error (default)\n")); ++ else ++ fprintf (file, _("\ ++ -z text Treat DT_TEXTREL in output as error\n")); ++ if (link_info.textrel_check == textrel_check_none) ++ { ++ fprintf (file, _("\ ++ -z notext Don't treat DT_TEXTREL in output as error (default)\n")); ++ fprintf (file, _("\ ++ -z textoff Don't treat DT_TEXTREL in output as error (default)\n")); ++ } ++ else ++ { ++ fprintf (file, _("\ ++ -z notext Don't treat DT_TEXTREL in output as error\n")); ++ fprintf (file, _("\ ++ -z textoff Don't treat DT_TEXTREL in output as error\n")); ++ } ++} ++ ++static void ++elf_static_list_options (FILE *file) ++{ ++ fprintf (file, _("\ ++ --build-id[=STYLE] Generate build ID note\n")); ++ fprintf (file, _("\ ++ --package-metadata[=JSON] Generate package metadata note\n")); ++ fprintf (file, _("\ ++ --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi|zstd]\n\ ++ Compress DWARF debug sections\n")); ++ fprintf (file, _("\ ++ Default: %s\n"), ++ bfd_get_compression_algorithm_name (config.compress_debug)); ++ fprintf (file, _("\ ++ -z common-page-size=SIZE Set common page size to SIZE\n")); ++ fprintf (file, _("\ ++ -z max-page-size=SIZE Set maximum page size to SIZE\n")); ++ fprintf (file, _("\ ++ -z defs Report unresolved symbols in object files\n")); ++ fprintf (file, _("\ ++ -z undefs Ignore unresolved symbols in object files\n")); ++ fprintf (file, _("\ ++ -z muldefs Allow multiple definitions\n")); ++ fprintf (file, _("\ ++ -z stack-size=SIZE Set size of stack segment\n")); ++ ++ fprintf (file, _("\ ++ -z execstack Mark executable as requiring executable stack\n")); ++ fprintf (file, _("\ ++ -z noexecstack Mark executable as not requiring executable stack\n")); ++ fprintf (file, _("\ ++ --warn-execstack-objects Generate a warning if an object file requests an executable stack\n")); ++#if DEFAULT_LD_WARN_EXECSTACK == 0 ++ fprintf (file, _("\ ++ --warn-execstack Generate a warning if creating an executable stack\n")); ++#else ++ fprintf (file, _("\ ++ --warn-execstack Generate a warning if creating an executable stack (default)\n")); ++#endif ++#if DEFAULT_LD_WARN_EXECSTACK == 0 ++ fprintf (file, _("\ ++ --no-warn-execstack Do not generate a warning if creating an executable stack (default)\n")); ++#else ++ fprintf (file, _("\ ++ --no-warn-execstack Do not generate a warning if creating an executable stack\n")); ++#endif ++ fprintf (file, _("\ ++ --error-execstack Turn warnings about executable stacks into errors\n")); ++ fprintf (file, _("\ ++ --no-error-execstack Do not turn warnings about executable stacks into errors\n")); ++ ++#if DEFAULT_LD_WARN_RWX_SEGMENTS ++ fprintf (file, _("\ ++ --warn-rwx-segments Generate a warning if a LOAD segment has RWX permissions (default)\n")); ++ fprintf (file, _("\ ++ --no-warn-rwx-segments Do not generate a warning if a LOAD segments has RWX permissions\n")); ++#else ++ fprintf (file, _("\ ++ --warn-rwx-segments Generate a warning if a LOAD segment has RWX permissions\n")); ++ fprintf (file, _("\ ++ --no-warn-rwx-segments Do not generate a warning if a LOAD segments has RWX permissions (default)\n")); ++#endif ++ fprintf (file, _("\ ++ --error-rwx-segments Turn warnings about loadable RWX segments into errors\n")); ++ fprintf (file, _("\ ++ --no-error-rwx-segments Do not turn warnings about loadable RWX segments into errors\n")); ++ ++ fprintf (file, _("\ ++ -z unique-symbol Avoid duplicated local symbol names\n")); ++ fprintf (file, _("\ ++ -z nounique-symbol Keep duplicated local symbol names (default)\n")); ++ fprintf (file, _("\ ++ -z globalaudit Mark executable requiring global auditing\n")); ++ fprintf (file, _("\ ++ -z start-stop-gc Enable garbage collection on __start/__stop\n")); ++ fprintf (file, _("\ ++ -z nostart-stop-gc Don't garbage collect __start/__stop (default)\n")); ++ fprintf (file, _("\ ++ -z start-stop-visibility=V Set visibility of built-in __start/__stop symbols\n\ ++ to DEFAULT, PROTECTED, HIDDEN or INTERNAL\n")); ++ fprintf (file, _("\ ++ -z sectionheader Generate section header (default)\n")); ++ fprintf (file, _("\ ++ -z nosectionheader Do not generate section header\n")); ++} ++ ++static void ++elf_plt_unwind_list_options (FILE *file) ++{ ++ fprintf (file, _("\ ++ --ld-generated-unwind-info Generate exception handling info for PLT\n")); ++ fprintf (file, _("\ ++ --no-ld-generated-unwind-info\n\ ++ Don't generate exception handling info for PLT\n")); ++} ++ ++static void ++ld_list_options (FILE *file, bool elf, bool shlib, bool plt_unwind) ++{ ++ if (!elf) ++ return; ++ printf (_("ELF emulations:\n")); ++ if (plt_unwind) ++ elf_plt_unwind_list_options (file); ++ elf_static_list_options (file); ++ if (shlib) ++ elf_shlib_list_options (file); ++} ++ ++ ++/* Print help messages for the options. */ ++ ++static void ++help (void) ++{ ++ unsigned i; ++ const char **targets, **pp; ++ int len; ++ ++ printf (_("Usage: %s [options] file...\n"), program_name); ++ ++ printf (_("Options:\n")); ++ for (i = 0; i < OPTION_COUNT; i++) ++ { ++ if (ld_options[i].doc != NULL) ++ { ++ bool comma; ++ unsigned j; ++ ++ printf (" "); ++ ++ comma = false; ++ len = 2; ++ ++ j = i; ++ do ++ { ++ if (ld_options[j].shortopt != '\0' ++ && ld_options[j].control != NO_HELP) ++ { ++ printf ("%s-%c", comma ? ", " : "", ld_options[j].shortopt); ++ len += (comma ? 2 : 0) + 2; ++ if (ld_options[j].arg != NULL) ++ { ++ if (ld_options[j].opt.has_arg != optional_argument) ++ { ++ printf (" "); ++ ++len; ++ } ++ printf ("%s", _(ld_options[j].arg)); ++ len += strlen (_(ld_options[j].arg)); ++ } ++ comma = true; ++ } ++ ++j; ++ } ++ while (j < OPTION_COUNT && ld_options[j].doc == NULL); ++ ++ j = i; ++ do ++ { ++ if (ld_options[j].opt.name != NULL ++ && ld_options[j].control != NO_HELP) ++ { ++ int two_dashes = ++ (ld_options[j].control == TWO_DASHES ++ || ld_options[j].control == EXACTLY_TWO_DASHES); ++ ++ printf ("%s-%s%s", ++ comma ? ", " : "", ++ two_dashes ? "-" : "", ++ ld_options[j].opt.name); ++ len += ((comma ? 2 : 0) ++ + 1 ++ + (two_dashes ? 1 : 0) ++ + strlen (ld_options[j].opt.name)); ++ if (ld_options[j].arg != NULL) ++ { ++ printf (" %s", _(ld_options[j].arg)); ++ len += 1 + strlen (_(ld_options[j].arg)); ++ } ++ comma = true; ++ } ++ ++j; ++ } ++ while (j < OPTION_COUNT && ld_options[j].doc == NULL); ++ ++ if (len >= 30) ++ { ++ printf ("\n"); ++ len = 0; ++ } ++ ++ for (; len < 30; len++) ++ putchar (' '); ++ ++ printf ("%s\n", _(ld_options[i].doc)); ++ } ++ } ++ printf (_(" @FILE")); ++ for (len = strlen (" @FILE"); len < 30; len++) ++ putchar (' '); ++ printf (_("Read options from FILE\n")); ++ ++ /* Note: Various tools (such as libtool) depend upon the ++ format of the listings below - do not change them. */ ++ /* xgettext:c-format */ ++ printf (_("%s: supported targets:"), program_name); ++ targets = bfd_target_list (); ++ for (pp = targets; *pp != NULL; pp++) ++ printf (" %s", *pp); ++ free (targets); ++ printf ("\n"); ++ ++ /* xgettext:c-format */ ++ printf (_("%s: supported emulations: "), program_name); ++ ldemul_list_emulations (stdout); ++ printf ("\n"); ++ ++ /* xgettext:c-format */ ++ printf (_("%s: emulation specific options:\n"), program_name); ++ ld_list_options (stdout, ELF_LIST_OPTIONS, ELF_SHLIB_LIST_OPTIONS, ++ ELF_PLT_UNWIND_LIST_OPTIONS); ++ ldemul_list_emulation_options (stdout); ++ printf ("\n"); ++ ++ if (REPORT_BUGS_TO[0]) ++ printf (_("Report bugs to %s\n"), REPORT_BUGS_TO); ++} +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1a.d binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.d +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1a.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.d 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,22 @@ ++#name: Text Section Ordering (section-order-1a) ++#source: section-order-1b.s ++#source: section-order-1a.s ++#source: start.s ++#ld: --section-ordering-file section-order-1a.t ++#nm: -n ++ ++#... ++[0-9a-f]+ T yyy ++#... ++[0-9a-f]+ T bar ++#... ++[0-9a-f]+ T [_]+start ++#... ++[0-9a-f]+ T xxx ++#... ++[0-9a-f]+ T foo ++#... ++[0-9a-f]+ T qqq ++#... ++[0-9a-f]+ T zzz ++#pass +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1a.s binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.s +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1a.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.s 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,29 @@ ++ .section .text.foo ++ .globl foo ++foo: ++ .dc.a 0 ++ ++ .section .text.bar ++ .globl bar ++bar: ++ .dc.a 0 ++ ++ .section .data.small ++ .globl small ++small: ++ .dc.a 0 ++ ++ .section .bar ++ .global bar ++bart: ++ .dc.a 0 ++ ++ .section .text.zzz ++ .global zzz ++zzz: ++ .dc.a 0 ++ ++ .section .data.bbb ++ .global bbb ++bbb: ++ .dc.a 0 +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1a.t binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.t +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1a.t 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1a.t 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,14 @@ ++.text : { ++ *(.text.yyy) ++ *(.text.b?r) ++ *(.text) ++ *(.text.xxx .text.foo) ++} ++ ++.data : { ++ *(.data.small) ++ *(.big*) ++ *(.bar .baz*) ++ *(.data.ccc) ++} ++ +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1b.d binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.d +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1b.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.d 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,18 @@ ++#name: Text Section Ordering (section-order-1b) ++#source: section-order-1a.s ++#source: section-order-1b.s ++#source: start.s ++#ld: --section-ordering-file section-order-1b.t ++#nm: -n ++ ++#... ++[0-9a-f]+ T yyy ++#... ++[0-9a-f]+ T bar ++#... ++[0-9a-f]+ T [_]+start ++#... ++[0-9a-f]+ T xxx ++#... ++[0-9a-f]+ T foo ++#pass +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1b.s binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.s +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1b.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.s 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,34 @@ ++ .section .text.xxx ++ .globl xxx ++xxx: ++ .dc.a 0 ++ ++ .section .text.yyy ++ .globl yyy ++yyy: ++ .dc.a 0 ++ ++ .section .big ++ .global big ++big: ++ .dc.a 0 ++ ++ .section .baz ++ .global baz ++baz: ++ .dc.a 0 ++ ++ .section .text.qqq ++ .global qqq ++qqq: ++ .dc.a 0 ++ ++ .section .data.ccc ++ .global ccc ++ccc: ++ .dc.a 0 ++ ++ .data ++ .global data_symbol ++data_symbol: ++ .dc.a 0 +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1b.t binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.t +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1b.t 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1b.t 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,7 @@ ++.text : { ++ *(.text.yyy) ++ *(.text.b?r) ++ *(*t) ++ *(.text.xxx) ++ *(.text.foo) ++} +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1c.d binutils-2.41/ld/testsuite/ld-scripts/section-order-1c.d +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1c.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1c.d 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,14 @@ ++#name: Data Section Ordering (section-order-1c) ++#source: section-order-1b.s ++#source: section-order-1a.s ++#source: start.s ++#ld: --section-ordering-file section-order-1a.t ++#nm: -n ++ ++#... ++[0-9a-f]+ D small ++#... ++[0-9a-f]+ D big ++#... ++[0-9a-f]+ D ba.* ++#pass +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order-1d.d binutils-2.41/ld/testsuite/ld-scripts/section-order-1d.d +--- binutils.orig/ld/testsuite/ld-scripts/section-order-1d.d 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order-1d.d 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,18 @@ ++#name: Data Section Ordering (section-order-1d) ++#source: section-order-1a.s ++#source: section-order-1b.s ++#source: start.s ++#ld: --section-ordering-file section-order-1a.t ++#nm: -n ++ ++#... ++[0-9a-f]+ D small ++#... ++[0-9a-f]+ D big ++#... ++[0-9a-f]+ d bart ++#... ++[0-9a-f]+ D ccc ++#... ++[0-9a-f]+ D bbb ++#pass +diff -rupN binutils.orig/ld/testsuite/ld-scripts/section-order.exp binutils-2.41/ld/testsuite/ld-scripts/section-order.exp +--- binutils.orig/ld/testsuite/ld-scripts/section-order.exp 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/section-order.exp 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,45 @@ ++# Test for --section-ordering-file FILE. ++# Copyright (C) 2024 Free Software Foundation, Inc. ++# ++# This file is part of the GNU Binutils. ++# ++# This program is free software; you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation; either version 3 of the License, or ++# (at your option) any later version. ++# ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with this program; if not, write to the Free Software ++# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, ++# MA 02110-1301, USA. ++ ++# The --section-ordering-file option is only supported by ELF and ++# PE COFF linkers, which allow for arbitrarily named sections, eg: ++# .text.* ++if { !([is_elf_format] || [is_pecoff_format]) } { ++ return ++} ++ ++set old_ldflags $LDFLAGS ++if { [istarget spu*-*-*] } then { ++ set LDFLAGS "$LDFLAGS --local-store 0:0 --no-overlays" ++} elseif { [is_pecoff_format] } then { ++ set LDFLAGS "$LDFLAGS --image-base 0" ++} elseif { [is_xcoff_format] } then { ++ set LDFLAGS "$LDFLAGS -bnogc" ++} ++ ++set test_list [lsort [glob -nocomplain $srcdir/$subdir/section-order*.d]] ++foreach test_file $test_list { ++ set test_name [file rootname $test_file] ++ set map_file "tmpdir/[file tail $test_name].map" ++ verbose $test_name ++ run_dump_test $test_name ++} ++ ++set LDFLAGS $old_ldflags +diff -rupN binutils.orig/ld/testsuite/ld-scripts/start.s binutils-2.41/ld/testsuite/ld-scripts/start.s +--- binutils.orig/ld/testsuite/ld-scripts/start.s 1970-01-01 01:00:00.000000000 +0100 ++++ binutils-2.41/ld/testsuite/ld-scripts/start.s 2024-05-13 13:04:08.599633306 +0100 +@@ -0,0 +1,14 @@ ++ .text ++ .global start /* Used by SH targets. */ ++start: ++ .global _start ++_start: ++ .global __start ++__start: ++ .global _mainCRTStartup /* Used by PE targets. */ ++_mainCRTStartup: ++ .global main /* Used by HPPA targets. */ ++main: ++ .globl _main /* Used by LynxOS targets. */ ++_main: ++ .dc.a 0 diff --git a/binutils.spec b/binutils.spec index bca8376..4314476 100644 --- a/binutils.spec +++ b/binutils.spec @@ -2,7 +2,7 @@ Summary: A GNU collection of binary utilities Name: binutils%{?_with_debug:-debug} Version: 2.41 -Release: 36%{?dist} +Release: 37%{?dist} License: GPL-3.0-or-later AND (GPL-3.0-or-later WITH Bison-exception-2.2) AND (LGPL-2.0-or-later WITH GCC-exception-2.0) AND BSD-3-Clause AND GFDL-1.3-or-later AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later URL: https://sourceware.org/binutils @@ -1370,6 +1370,9 @@ exit 0 #---------------------------------------------------------------------------- %changelog +* Mon May 13 2024 Nick Clifton - 2.41-37 +- Add section-ordering patch to bfd linker. (PTG-287) + * Tue Apr 02 2024 Nick Clifton - 2.41-36 - Fix verification of ld.bfd installation. (RHEL-30887) diff --git a/gating.yaml b/gating.yaml index 8beaedd..9e0be38 100644 --- a/gating.yaml +++ b/gating.yaml @@ -8,9 +8,10 @@ rules: - !PassingTestCaseRule {test_case_name: fedora-ci.koji-build.tier0.functional} --- !Policy product_versions: - - rhel-9 + - rhel-10 decision_context: osci_compose_gate rules: + - !PassingTestCaseRule {test_case_name: osci.brew-build.rebuild.validation} - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.gate-build-fast-lane.functional} - !PassingTestCaseRule {test_case_name: baseos-ci.brew-build.gate-build-slow-lane.functional} --- !Policy