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