[PATCH v2 4/5] aarch64: add tests for non-contiguous memory regions

Alice Carlotti alice.carlotti@arm.com
Thu Jan 22 11:44:07 GMT 2026


On Tue, Oct 14, 2025 at 11:46:10AM +0100, Matthieu Longo wrote:
> This patch adds AArch64 test cases for all non-contiguous memory scenarios.
> Those tests were copy-pasted from AArch32, and adapted for AArch64.
> It also adds a new test case inspired from a real case where several sections
> containing interrupt vector tables, declared in different compilation units,
> and all aligned on 2KB, are supposed to be merged into one output section
> fitting on 2KB memory.

Apologies for the long delay.  This looks mostly ok to me, with just a few
minor nits indicated below.

I think Jan has approved most of the rest of the series, but he requested an
arm maintainer to approve patch 3/5 so you may need to ping Richard for that.

Alice

> ---
>  .../aarch64-non-contiguous-mem.exp            | 34 +++++++
>  .../non-contiguous-mem/non-contiguous-mem-1.s | 37 ++++++++
>  .../non-contiguous-mem/non-contiguous-mem-2.s | 17 ++++
>  .../non-contiguous-mem-3-ivt.s                | 15 ++++
>  .../non-contiguous-mem/non-contiguous-mem-3.s | 74 ++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-nok-1.d |  9 ++
>  .../non-contiguous-nok-1.ld                   | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-nok-2.d |  8 ++
>  .../non-contiguous-nok-2.ld                   | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-nok-3.d |  6 ++
>  .../non-contiguous-nok-3.err                  |  4 +
>  .../non-contiguous-nok-3.ld                   | 26 ++++++
>  .../non-contiguous-mem/non-contiguous-nok-4.d | 15 ++++
>  .../non-contiguous-nok-4.ld                   | 24 +++++
>  .../non-contiguous-mem/non-contiguous-nok-5.d | 10 +++
>  .../non-contiguous-nok-5.err                  |  7 ++
>  .../non-contiguous-nok-5.ld                   | 30 +++++++
>  .../non-contiguous-mem/non-contiguous-ok-1.d  | 80 +++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-ok-1.ld | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-ok-2.d  | 88 +++++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-ok-2.ld | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-ok-3.d  | 80 +++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-ok-3.ld | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-ok-4.d  | 83 +++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-ok-4.ld | 28 ++++++
>  .../non-contiguous-mem/non-contiguous-ok-5.d  | 87 ++++++++++++++++++
>  .../non-contiguous-mem/non-contiguous-ok-5.ld | 31 +++++++
>  .../non-contiguous-ok-5.warn                  | 10 +++
>  28 files changed, 943 insertions(+)
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/aarch64-non-contiguous-mem.exp
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-1.s
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-2.s
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3-ivt.s
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3.s
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.err
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.err
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.d
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.ld
>  create mode 100644 ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
> 
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/aarch64-non-contiguous-mem.exp b/ld/testsuite/ld-aarch64/non-contiguous-mem/aarch64-non-contiguous-mem.exp
> new file mode 100644
> index 00000000000..2eaa6b58249
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/aarch64-non-contiguous-mem.exp
> @@ -0,0 +1,34 @@
> +# Expect script for AARCH64 ELF tests related to GNU properties.
> +# Copyright (C) 2025 Free Software Foundation, Inc.

This date presumably needs adjusting now.

> +#
> +# 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.
> +
> +# Exclude non-aarch64-ELF targets.
> +if { ![is_elf_format] || ![istarget "aarch64*-*-*"] } {
> +  return
> +}
> +
> +load_file $srcdir/$subdir/../lib/aarch64-elf-lib.exp
> +
> +set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
> +
> +foreach t $test_list {
> +  # We need to strip the ".d", but can leave the dirname.
> +  run_dump_test [file rootname $t] \
> +    [list [list as "-I\$srcdir/\$subdir"]]
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-1.s b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-1.s
> new file mode 100644
> index 00000000000..5696cba88ba
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-1.s
> @@ -0,0 +1,37 @@
> +	.section .code.1, "ax", %progbits
> +	# Fit in RAML
> +	.global code1
> +	.type code1, %function
> +code1:
> +	nop
> +	nop
> +	bl code2
> +	.size code1, . - code1
> +
> +	.section .code.2, "ax", %progbits
> +	# Fit in RAML
> +	.global code2
> +	.type code2, %function
> +code2:
> +	nop
> +	nop
> +	bl code3
> +	.size code2, . - code2
> +
> +	.section .code.3, "ax", %progbits
> +	# Fit in RAMU
> +	.global code3
> +	.type code3, %function
> +code3:
> +	nop
> +	bl code4
> +	.size code3, . - code3
> +
> +	.section .code.4, "ax", %progbits
> +	# Fit in RAMZ
> +	.global code4
> +	.type code4, %function
> +code4:
> +$a:

This is the mapping symbol for the start of a region of A32 code, so it doesn't
belong in an AArch64 test.

> +	.fill 20, 4, 0xe1a00000

This encoding corresponds to the A32 instruction 'mov r0, r0', but in aarch64
it's an unallocated encoding in the SME encoding space.  I don't think it
matters, but it may be better to use a real encoding such as 0xd503201f (nop).

> +	.size code4, . - code4
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-2.s b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-2.s
> new file mode 100644
> index 00000000000..a52ac366770
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-2.s
> @@ -0,0 +1,17 @@
> +	.section .bss.MY_BUF, "aw", %nobits
> +	.global MY_BUF
> +	.type MY_BUF, %object
> +MY_BUF:
> +	.space 102400 /* 100KB */
> +	.size MY_BUF, . - MY_BUF
> +
> +
> +	.section .text.foo,"ax",%progbits
> +	.global foo
> +	.type	foo, %function
> +foo:
> +	ldr x0, .L3
> +	br lr

'lr' is a gas-only alias, so this should be replaced with a standard register name.

> +.L3:
> +	.word	MY_BUF
> +	.size	foo, .-foo
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3-ivt.s b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3-ivt.s
> new file mode 100644
> index 00000000000..dd0efdae55b
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3-ivt.s
> @@ -0,0 +1,15 @@
> +	/* Interrupt vector table.  */
> +	.section  .vectors,"ax"
> +	.p2align 11  /* 2KB alignment (2^11) */
> +	.global vector_table2
> +vector_table2:
> +	b irqhandler2
> +	b irqhandler1
> +	.size vector_table2, . - vector_table2
> +
> +	.global irqhandler2
> +	.type irqhandler2, %function
> +irqhandler2:
> +	b foo
> +	eret
> +	.size irqhandler2, . - irqhandler2
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3.s b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3.s
> new file mode 100644
> index 00000000000..31cd9ee0ce3
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-mem-3.s
> @@ -0,0 +1,74 @@
> +	.section .boot, "ax", %progbits
> +	.p2align 11  /* 2KB alignment (2^11) */
> +	# Fit in RAML
> +	.global bootloader
> +	.type bootloader, %function
> +bootloader:
> +	nop
> +	nop
> +	bl code2
> +	.size bootloader, . - bootloader
> +
> +
> +	/* Interrupt vector table.  */
> +	.section  .vectors,"ax"
> +	.p2align 11  /* 2KB alignment (2^11) */
> +	.global vector_table1
> +vector_table1:
> +	b irqhandler1
> +	.size vector_table1, . - vector_table1
> +
> +	.global irqhandler1
> +	.type irqhandler1, %function
> +irqhandler1:
> +	eret
> +	.size irqhandler1, . - irqhandler1
> +
> +
> +	.section .code.2, "ax", %progbits
> +	# Fit in RAMU
> +	.global code2
> +	.type code2, %function
> +code2:
> +	nop
> +	nop
> +	bl code3
> +	.size code2, . - code2
> +
> +
> +	/* Interrupt vector table.  */
> +	.section  .vectors
> +	.global vector_table3
> +vector_table3:
> +	b irqhandler3
> +	.size vector_table3, . - vector_table3
> +
> +	.global irqhandler3
> +	.type irqhandler3, %function
> +irqhandler3:
> +	eret
> +	.size irqhandler3, . - irqhandler3
> +
> +	.section .code.3, "ax", %progbits
> +	# Fit in RAMU
> +	.global code3
> +	.type code3, %function
> +code3:
> +	nop
> +	bl code4
> +	.size code3, . - code3
> +
> +	.section .code.4, "ax", %progbits
> +	# Fit in RAMU
> +	.global code4
> +	.type code4, %function
> +code4:
> +$a:
> +	.fill 20, 4, 0xe1a00000

See comments on -1.s.

> +	.size code4, . - code4
> +
> +	.global foo
> +	.type foo, %function
> +foo:
> +	ret
> +	.size foo, . - foo
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.d
> new file mode 100644
> index 00000000000..1b540743cb6
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.d
> @@ -0,0 +1,9 @@
> +#name: last section .code.4 is too big to fit in any of the available memories.
> +## Use case description:
> +## - sections .code.1 and .code.2 fit in .raml
> +## - section .code.3 fits in .ramu
> +## - section .code.4 is too large to fit in .ramz, we should expect an error
> +##   message about unability to assign the input section to an output one.
s/unability/inability/

> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions -T non-contiguous-nok-1.ld
> +# error: .*Could not assign .?\.code\.4.? to an output section. Retry without --enable-non-contiguous-regions\.
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.ld
> new file mode 100644
> index 00000000000..ff1b6619448
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-1.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
> +  RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040
> +  RAMZ (rwx) : ORIGIN = 0x20040000, LENGTH = 0x00040
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.d
> new file mode 100644
> index 00000000000..9cbab256ccb
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.d
> @@ -0,0 +1,8 @@
> +#name: all code sections fit in the available memories BUT farcall stub to jump to code4 DOES NOT not fits in .ramu
> +## Use case description:
> +## - sections .code.1 and .code.2 fit in .raml
> +## - section .code.3 fits in .ramu, but not its farcall stub to jump to code4.
> +## - section .code.4 fits in .ramz
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions -T non-contiguous-nok-2.ld
> +# error: Memory region `RAMU' not large enough for the linker-created stubs section `\.code\.3\.stub' associated to output section `\.ramu'
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.ld
> new file mode 100644
> index 00000000000..6c23900de16
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-2.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
> +  RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x0000c
> +  RAMZ (rwx) : ORIGIN = 0x30040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.d
> new file mode 100644
> index 00000000000..34198eef8d0
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.d
> @@ -0,0 +1,6 @@
> +#name: .bss section bigger than all the available RAMs.
> +## Use case description:
> +## The section .bss.MY_BUF (100KB) won't fit in RAM1 (64KB) or RAM2 (96KB)
> +#source: non-contiguous-mem-2.s
> +#ld: -T non-contiguous-nok-3.ld --enable-non-contiguous-regions --enable-non-contiguous-regions-warnings
> +#error_output: non-contiguous-nok-3.err
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.err b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.err
> new file mode 100644
> index 00000000000..ca23fc6b0b5
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.err
> @@ -0,0 +1,4 @@
> +.*: warning: --enable-non-contiguous-regions may change behaviour for section .?\.bss.? from .*
> +.*: warning: --enable-non-contiguous-regions may change behaviour for section .?\.bss\.MY_BUF.? from .*
> +.*: error: --enable-non-contiguous-regions was not able to allocate the input section `.bss.MY_BUF' \(.*non-contiguous-mem-2\.o\) to an output section
> +.*: final link failed
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.ld
> new file mode 100644
> index 00000000000..5d8100676cf
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-3.ld
> @@ -0,0 +1,26 @@
> +MEMORY
> +{
> +  ROM  (rx)    : ORIGIN = 0x8000000,    LENGTH = 10K
> +  RAM1 (xrw)   : ORIGIN = 0x10000000,   LENGTH = 64K
> +  RAM2 (xrw)   : ORIGIN = 0x20000000,   LENGTH = 96K
> +}
> +
> +SECTIONS
> +{
> +  .text :
> +  {
> +    KEEP(*(.text.foo)) ;
> +  } >ROM
> +
> +  .bss_ram1 :
> +  { _sbss_ram1 = .;
> +    *(.bss) *(.bss*) ;
> +    _ebss_ram1 = .;
> +  } >RAM1
> +
> +  .bss_ram2 :
> +  { _sbss_ram2 = .;
> +    *(.bss) *(.bss*) ;
> +    _ebss_ram2 = .;
> +  } >RAM2
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.d
> new file mode 100644
> index 00000000000..260eb76dece
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.d
> @@ -0,0 +1,15 @@
> +#name: Discard 2nd interrupt vector table because of alignment requirements
> +## Use case description:
> +## 3 IVTs are defined in section .vectors (2KB):
> +## - vector_table1 and vector_table3 in the first file, and vector_table3 does
> +##   not redefine the section, so is directly appended after vector_table1.
> +## - vector_table2 is defined in a second file, and redefines the section
> +##   .vectors with an alignment of 2KB.
> +## Since all .vectors sections should be moved to the VECTORS memory (2KB),
> +## vector_table2 will be discarded as the space was taken by the padding of
> +## the section defined in the first file.
> +#source: non-contiguous-mem-3.s
> +#source: non-contiguous-mem-3-ivt.s
> +#ld: -T non-contiguous-nok-4.ld --enable-non-contiguous-regions
> +#error: --enable-non-contiguous-regions was not able to allocate the input section `\.vectors' \(.*non-contiguous-mem-3-ivt\.o\) to an output section
> +#error: .*: final link failed$
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.ld
> new file mode 100644
> index 00000000000..43fa2c19b71
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-4.ld
> @@ -0,0 +1,24 @@
> +MEMORY
> +{
> +  RAML    (rwx) : ORIGIN = 0x8000000,          LENGTH = 2K
> +  VECTORS (xrw) : ORIGIN = (0x8000000 + 2048), LENGTH = 2K
> +  RAMU    (xrw) : ORIGIN = 0x40000000,         LENGTH = 64K
> +}
> +
> +SECTIONS
> +{
> +  RAM_REGION_START = ORIGIN(RAML);
> +  .boot : {
> +    *(.bootloader) *(.bootloader.*);
> +  } >RAML
> +
> +  .vectors : AT ( ADDR (.boot) + SIZEOF (.boot) ) {
> +    *(.vectors)
> +  } >VECTORS
> +
> +  .text : AT ( ADDR (.vectors) + SIZEOF (.vectors) )
> +  { _text_start = . ;
> +    *(.code) *(.code.*) ;
> +    _text_end = . ;
> +  } > RAMU
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.d
> new file mode 100644
> index 00000000000..2e42375c59c
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.d
> @@ -0,0 +1,10 @@
> +#name: input section is discarded because the output section match clauses succeed the matching DISCARD clause.
> +## Use case description:
> +## - sections .code.1, .code.2 and .code.3 (+ farcall stub) fit in .raml
> +## - section .code.4 fits in .ramz
> +## - nothing fits in .ramu
> +## The linker script contains a DISCARD clause for ".code.4" that precedes all
> +## the output clauses.
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions --enable-non-contiguous-regions-warnings -T non-contiguous-nok-5.ld
> +#error_output: non-contiguous-nok-5.err
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.err b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.err
> new file mode 100644
> index 00000000000..4b14de9f429
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.err
> @@ -0,0 +1,7 @@
> +.*: warning: .* may change behaviour for section `\.code\.1' from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section `\.code\.2' from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section `\.code\.3' from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section `\.code\.1' from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +.*: warning: .* may change behaviour for section `\.code\.2' from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +.*: warning: .* may change behaviour for section `\.code\.3' from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +`code4' referenced in section `\.code\.3' of .*: defined in discarded section `\.code\.4' of .*\Z
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.ld
> new file mode 100644
> index 00000000000..9aea032face
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-nok-5.ld
> @@ -0,0 +1,30 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00040
> +  RAMU (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00010
> +  RAMZ (rwx) : ORIGIN = 0x40040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  /DISCARD/ : { *(.code.4) }
> +
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.d
> new file mode 100644
> index 00000000000..25e437dddd6
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.d
> @@ -0,0 +1,80 @@
> +# name: all sections fit in the available memories + no farcall stub.
> +## Use case description:
> +## - sections .code.1 and .code.2 fit in .raml
> +## - section .code.3 fits in .ramu and does not need a farcall stub to jump
> +##   to code4
> +## - section .code.4 fits in .ramz
> +# source: non-contiguous-mem-1.s
> +# ld: --enable-non-contiguous-regions -T non-contiguous-ok-1.ld
> +# objdump: -rdth
> +
> +.*:     file format elf64-(little|big)aarch64
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.raml         00000018  000000001fff0000  000000001fff0000  00010000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  1 \.ramu         00000008  0000000020000000  000000001fff0018  00020000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  2 \.ramz         00000050  0000000020040000  0000000020000008  00030000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +SYMBOL TABLE:
> +000000001fff0000 l    d  \.raml	0000000000000000 \.raml
> +0000000020000000 l    d  \.ramu	0000000000000000 \.ramu
> +0000000020040000 l    d  \.ramz	0000000000000000 \.ramz
> +0000000000000000 l    df \*ABS\*	0000000000000000 non-contiguous-mem-.*\.o
> +0000000020040000 l       \.ramz	0000000000000000 \$a
> +000000001fff0018 g       \.raml	0000000000000000 _raml_end
> +0000000020000000 g       \.ramu	0000000000000000 _ramu_start
> +000000001fff000c g     F \.raml	000000000000000c code2
> +0000000020040000 g       \.ramz	0000000000000000 _ramz_start
> +000000001fff0000 g       \.raml	0000000000000000 _raml_start
> +0000000020000000 g     F \.ramu	0000000000000008 code3
> +000000001fff0000 g     F \.raml	000000000000000c code1
> +0000000020040050 g       \.ramz	0000000000000000 _ramz_end
> +0000000020040000 g     F \.ramz	0000000000000050 code4
> +0000000020000008 g       \.ramu	0000000000000000 _ramu_end
> +
> +
> +
> +Disassembly of section \.raml:
> +
> +000000001fff0000 \<code1\>:
> +    1fff0000:	d503201f 	nop
> +    1fff0004:	d503201f 	nop
> +    1fff0008:	94000001 	bl	1fff000c \<code2\>
> +
> +000000001fff000c \<code2\>:
> +    1fff000c:	d503201f 	nop
> +    1fff0010:	d503201f 	nop
> +    1fff0014:	94003ffb 	bl	20000000 \<code3\>
> +
> +Disassembly of section \.ramu:
> +
> +0000000020000000 \<code3\>:
> +    20000000:	d503201f 	nop
> +    20000004:	9400ffff 	bl	20040000 \<code4\>
> +
> +Disassembly of section \.ramz:
> +
> +0000000020040000 \<code4\>:
> +    20040000:	e1a00000 	\.word	0xe1a00000
> +    20040004:	e1a00000 	\.word	0xe1a00000
> +    20040008:	e1a00000 	\.word	0xe1a00000
> +    2004000c:	e1a00000 	\.word	0xe1a00000
> +    20040010:	e1a00000 	\.word	0xe1a00000
> +    20040014:	e1a00000 	\.word	0xe1a00000
> +    20040018:	e1a00000 	\.word	0xe1a00000
> +    2004001c:	e1a00000 	\.word	0xe1a00000
> +    20040020:	e1a00000 	\.word	0xe1a00000
> +    20040024:	e1a00000 	\.word	0xe1a00000
> +    20040028:	e1a00000 	\.word	0xe1a00000
> +    2004002c:	e1a00000 	\.word	0xe1a00000
> +    20040030:	e1a00000 	\.word	0xe1a00000
> +    20040034:	e1a00000 	\.word	0xe1a00000
> +    20040038:	e1a00000 	\.word	0xe1a00000
> +    2004003c:	e1a00000 	\.word	0xe1a00000
> +    20040040:	e1a00000 	\.word	0xe1a00000
> +    20040044:	e1a00000 	\.word	0xe1a00000
> +    20040048:	e1a00000 	\.word	0xe1a00000
> +    2004004c:	e1a00000 	\.word	0xe1a00000
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.ld
> new file mode 100644
> index 00000000000..257a4ca905c
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-1.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
> +  RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008
> +  RAMZ (rwx) : ORIGIN = 0x20040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.d
> new file mode 100644
> index 00000000000..4ab720b133e
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.d
> @@ -0,0 +1,88 @@
> +#name: all code sections fit in the available memories AND farcall stub to jump to code4 ALSO fits in .ramu
> +## Use case description:
> +## - sections .code.1 and .code.2 fit in .raml
> +## - both section .code.3 and farcall stub to jump to code4 fits in .ramu
> +## - section .code.4 fits in .ramz
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions -T non-contiguous-ok-2.ld
> +#objdump: -rdth
> +
> +.*:     file format elf64-(little|big)aarch64
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.raml         00000018  000000001fff0000  000000001fff0000  00010000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  1 \.ramu         00000028  0000000020000000  000000001fff0018  00020000  2\*\*3
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  2 \.ramz         00000050  0000000030040000  0000000020000028  00030000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +SYMBOL TABLE:
> +000000001fff0000 l    d  \.raml	0000000000000000 \.raml
> +0000000020000000 l    d  \.ramu	0000000000000000 \.ramu
> +0000000030040000 l    d  \.ramz	0000000000000000 \.ramz
> +0000000000000000 l    df \*ABS\*	0000000000000000 non-contiguous-mem-.*\.o
> +0000000030040000 l       \.ramz	0000000000000000 \$a
> +0000000020000010 l     F \.ramu	000000000000000c __code4_veneer
> +000000001fff0018 g       \.raml	0000000000000000 _raml_end
> +0000000020000000 g       \.ramu	0000000000000000 _ramu_start
> +000000001fff000c g     F \.raml	000000000000000c code2
> +0000000030040000 g       \.ramz	0000000000000000 _ramz_start
> +000000001fff0000 g       \.raml	0000000000000000 _raml_start
> +0000000020000000 g     F \.ramu	0000000000000008 code3
> +000000001fff0000 g     F \.raml	000000000000000c code1
> +0000000030040050 g       \.ramz	0000000000000000 _ramz_end
> +0000000030040000 g     F \.ramz	0000000000000050 code4
> +0000000020000028 g       \.ramu	0000000000000000 _ramu_end
> +
> +
> +
> +Disassembly of section \.raml:
> +
> +000000001fff0000 \<code1\>:
> +    1fff0000:	d503201f 	nop
> +    1fff0004:	d503201f 	nop
> +    1fff0008:	94000001 	bl	1fff000c \<code2\>
> +
> +000000001fff000c \<code2\>:
> +    1fff000c:	d503201f 	nop
> +    1fff0010:	d503201f 	nop
> +    1fff0014:	94003ffb 	bl	20000000 \<code3\>
> +
> +Disassembly of section \.ramu:
> +
> +0000000020000000 \<code3\>:
> +    20000000:	d503201f 	nop
> +    20000004:	94000003 	bl	20000010 \<__code4_veneer\>
> +    20000008:	14000008 	b	20000028 \<_ramu_end\>
> +    2000000c:	d503201f 	nop
> +
> +0000000020000010 \<__code4_veneer\>:
> +    20000010:	90080210 	adrp	x16, 30040000 \<code4\>
> +    20000014:	91000210 	add	x16, x16, #0x0
> +    20000018:	d61f0200 	br	x16
> +	\.\.\.
> +
> +Disassembly of section \.ramz:
> +
> +0000000030040000 \<code4\>:
> +    30040000:	e1a00000 	\.word	0xe1a00000
> +    30040004:	e1a00000 	\.word	0xe1a00000
> +    30040008:	e1a00000 	\.word	0xe1a00000
> +    3004000c:	e1a00000 	\.word	0xe1a00000
> +    30040010:	e1a00000 	\.word	0xe1a00000
> +    30040014:	e1a00000 	\.word	0xe1a00000
> +    30040018:	e1a00000 	\.word	0xe1a00000
> +    3004001c:	e1a00000 	\.word	0xe1a00000
> +    30040020:	e1a00000 	\.word	0xe1a00000
> +    30040024:	e1a00000 	\.word	0xe1a00000
> +    30040028:	e1a00000 	\.word	0xe1a00000
> +    3004002c:	e1a00000 	\.word	0xe1a00000
> +    30040030:	e1a00000 	\.word	0xe1a00000
> +    30040034:	e1a00000 	\.word	0xe1a00000
> +    30040038:	e1a00000 	\.word	0xe1a00000
> +    3004003c:	e1a00000 	\.word	0xe1a00000
> +    30040040:	e1a00000 	\.word	0xe1a00000
> +    30040044:	e1a00000 	\.word	0xe1a00000
> +    30040048:	e1a00000 	\.word	0xe1a00000
> +    3004004c:	e1a00000 	\.word	0xe1a00000
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.ld
> new file mode 100644
> index 00000000000..56b75c5856f
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-2.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
> +  RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00028
> +  RAMZ (rwx) : ORIGIN = 0x30040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.d
> new file mode 100644
> index 00000000000..fa257e72521
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.d
> @@ -0,0 +1,80 @@
> +#name: subsequent sections should not be swapped, even if they fit in a previous hole.
> +## Use case description:
> +## - section .code.1 fits in .raml
> +## - section .code.2 does not fit in .raml and goes to .ramu
> +## - section .code.3 would fit in .raml, but goes to .ramu:  Check that .code.2 and .code.3 are not swapped
> +## - section .code.4 fits in .ramz
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions -T non-contiguous-ok-3.ld
> +#objdump: -rdth
> +
> +.*:     file format elf64-(little|big)aarch64
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.raml         0000000c  000000001fff0000  000000001fff0000  00010000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  1 \.ramu         00000014  0000000020000000  000000001fff000c  00020000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  2 \.ramz         00000050  0000000020040000  0000000020000014  00030000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +SYMBOL TABLE:
> +000000001fff0000 l    d  \.raml	0000000000000000 \.raml
> +0000000020000000 l    d  \.ramu	0000000000000000 \.ramu
> +0000000020040000 l    d  \.ramz	0000000000000000 \.ramz
> +0000000000000000 l    df \*ABS\*	0000000000000000 non-contiguous-mem-.*\.o
> +0000000020040000 l       \.ramz	0000000000000000 \$a
> +000000001fff000c g       \.raml	0000000000000000 _raml_end
> +0000000020000000 g       \.ramu	0000000000000000 _ramu_start
> +0000000020000000 g     F \.ramu	000000000000000c code2
> +0000000020040000 g       \.ramz	0000000000000000 _ramz_start
> +000000001fff0000 g       \.raml	0000000000000000 _raml_start
> +000000002000000c g     F \.ramu	0000000000000008 code3
> +000000001fff0000 g     F \.raml	000000000000000c code1
> +0000000020040050 g       \.ramz	0000000000000000 _ramz_end
> +0000000020040000 g     F \.ramz	0000000000000050 code4
> +0000000020000014 g       \.ramu	0000000000000000 _ramu_end
> +
> +
> +
> +Disassembly of section \.raml:
> +
> +000000001fff0000 \<code1\>:
> +    1fff0000:	d503201f 	nop
> +    1fff0004:	d503201f 	nop
> +    1fff0008:	94003ffe 	bl	20000000 \<code2\>
> +
> +Disassembly of section \.ramu:
> +
> +0000000020000000 \<code2\>:
> +    20000000:	d503201f 	nop
> +    20000004:	d503201f 	nop
> +    20000008:	94000001 	bl	2000000c \<code3\>
> +
> +000000002000000c \<code3\>:
> +    2000000c:	d503201f 	nop
> +    20000010:	9400fffc 	bl	20040000 \<code4\>
> +
> +Disassembly of section \.ramz:
> +
> +0000000020040000 \<code4\>:
> +    20040000:	e1a00000 	\.word	0xe1a00000
> +    20040004:	e1a00000 	\.word	0xe1a00000
> +    20040008:	e1a00000 	\.word	0xe1a00000
> +    2004000c:	e1a00000 	\.word	0xe1a00000
> +    20040010:	e1a00000 	\.word	0xe1a00000
> +    20040014:	e1a00000 	\.word	0xe1a00000
> +    20040018:	e1a00000 	\.word	0xe1a00000
> +    2004001c:	e1a00000 	\.word	0xe1a00000
> +    20040020:	e1a00000 	\.word	0xe1a00000
> +    20040024:	e1a00000 	\.word	0xe1a00000
> +    20040028:	e1a00000 	\.word	0xe1a00000
> +    2004002c:	e1a00000 	\.word	0xe1a00000
> +    20040030:	e1a00000 	\.word	0xe1a00000
> +    20040034:	e1a00000 	\.word	0xe1a00000
> +    20040038:	e1a00000 	\.word	0xe1a00000
> +    2004003c:	e1a00000 	\.word	0xe1a00000
> +    20040040:	e1a00000 	\.word	0xe1a00000
> +    20040044:	e1a00000 	\.word	0xe1a00000
> +    20040048:	e1a00000 	\.word	0xe1a00000
> +    2004004c:	e1a00000 	\.word	0xe1a00000
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.ld
> new file mode 100644
> index 00000000000..e6b3cd3b0f7
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-3.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00014
> +  RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020
> +  RAMZ (rwx) : ORIGIN = 0x20040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.d
> new file mode 100644
> index 00000000000..6fbe17ea385
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.d
> @@ -0,0 +1,83 @@
> +#name: a "middle" memory is too small to fit anything, the sections are moved to the next available memory.
> +## Use case description:
> +## - sections .code.1, .code.2 and .code.3 (+ farcall stub) fit in .raml
> +## - section .code.4 fits in .ramz
> +## - nothing fits in .ramu
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions -T non-contiguous-ok-4.ld
> +#objdump: -rdth
> +
> +.*:     file format elf64-(little|big)aarch64
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.raml         00000040  000000001fff0000  000000001fff0000  00010000  2\*\*3
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  1 \.ramz         00000050  0000000040040000  0000000030000000  00020000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +SYMBOL TABLE:
> +000000001fff0000 l    d  \.raml	0000000000000000 \.raml
> +0000000040040000 l    d  \.ramz	0000000000000000 \.ramz
> +0000000000000000 l    df \*ABS\*	0000000000000000 non-contiguous-mem-.*\.o
> +0000000040040000 l       \.ramz	0000000000000000 \$a
> +000000001fff0028 l     F \.raml	000000000000000c __code4_veneer
> +000000001fff0040 g       \.raml	0000000000000000 _raml_end
> +0000000030000000 g       \.raml	0000000000000000 _ramu_start
> +000000001fff000c g     F \.raml	000000000000000c code2
> +0000000040040000 g       \.ramz	0000000000000000 _ramz_start
> +000000001fff0000 g       \.raml	0000000000000000 _raml_start
> +000000001fff0018 g     F \.raml	0000000000000008 code3
> +000000001fff0000 g     F \.raml	000000000000000c code1
> +0000000040040050 g       \.ramz	0000000000000000 _ramz_end
> +0000000040040000 g     F \.ramz	0000000000000050 code4
> +0000000030000000 g       \.raml	0000000000000000 _ramu_end
> +
> +
> +
> +Disassembly of section \.raml:
> +
> +000000001fff0000 \<code1\>:
> +    1fff0000:	d503201f 	nop
> +    1fff0004:	d503201f 	nop
> +    1fff0008:	94000001 	bl	1fff000c \<code2\>
> +
> +000000001fff000c \<code2\>:
> +    1fff000c:	d503201f 	nop
> +    1fff0010:	d503201f 	nop
> +    1fff0014:	94000001 	bl	1fff0018 \<code3\>
> +
> +000000001fff0018 \<code3\>:
> +    1fff0018:	d503201f 	nop
> +    1fff001c:	94000003 	bl	1fff0028 \<__code4_veneer\>
> +    1fff0020:	14000008 	b	1fff0040 \<_raml_end\>
> +    1fff0024:	d503201f 	nop
> +
> +000000001fff0028 \<__code4_veneer\>:
> +    1fff0028:	90100290 	adrp	x16, 40040000 \<code4\>
> +    1fff002c:	91000210 	add	x16, x16, #0x0
> +    1fff0030:	d61f0200 	br	x16
> +	...
> +
> +Disassembly of section \.ramz:
> +
> +0000000040040000 \<code4\>:
> +    40040000:	e1a00000 	.word	0xe1a00000
> +    40040004:	e1a00000 	.word	0xe1a00000
> +    40040008:	e1a00000 	.word	0xe1a00000
> +    4004000c:	e1a00000 	.word	0xe1a00000
> +    40040010:	e1a00000 	.word	0xe1a00000
> +    40040014:	e1a00000 	.word	0xe1a00000
> +    40040018:	e1a00000 	.word	0xe1a00000
> +    4004001c:	e1a00000 	.word	0xe1a00000
> +    40040020:	e1a00000 	.word	0xe1a00000
> +    40040024:	e1a00000 	.word	0xe1a00000
> +    40040028:	e1a00000 	.word	0xe1a00000
> +    4004002c:	e1a00000 	.word	0xe1a00000
> +    40040030:	e1a00000 	.word	0xe1a00000
> +    40040034:	e1a00000 	.word	0xe1a00000
> +    40040038:	e1a00000 	.word	0xe1a00000
> +    4004003c:	e1a00000 	.word	0xe1a00000
> +    40040040:	e1a00000 	.word	0xe1a00000
> +    40040044:	e1a00000 	.word	0xe1a00000
> +    40040048:	e1a00000 	.word	0xe1a00000
> +    4004004c:	e1a00000 	.word	0xe1a00000
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.ld
> new file mode 100644
> index 00000000000..bdafce7587d
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-4.ld
> @@ -0,0 +1,28 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00040
> +  RAMU (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00010
> +  RAMZ (rwx) : ORIGIN = 0x40040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.d b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.d
> new file mode 100644
> index 00000000000..e160d8b9540
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.d
> @@ -0,0 +1,87 @@
> +#name: input section is kept because a match clause precedes the matching DISCARD clause.
> +## Use case description:
> +## - sections .code.1, .code.2 and .code.3 (+ farcall stub) fit in .raml
> +## - section .code.4 fits in .ramz
> +## - nothing fits in .ramu
> +## The linker script contains a ".code.4" match clause for .raml, before
> +## the DISCARD clause.
> +#source: non-contiguous-mem-1.s
> +#ld: --enable-non-contiguous-regions --enable-non-contiguous-regions-warnings -T non-contiguous-ok-5.ld
> +#warning_output: non-contiguous-ok-5.warn
> +
> +#objdump: -rdth
> +
> +.*:     file format elf64-(little|big)aarch64
> +
> +Sections:
> +Idx Name          Size      VMA               LMA               File off  Algn
> +  0 \.raml         00000040  000000001fff0000  000000001fff0000  00010000  2\*\*3
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +  1 \.ramz         00000050  0000000040040000  0000000030000000  00020000  2\*\*2
> +                  CONTENTS, ALLOC, LOAD, READONLY, CODE
> +SYMBOL TABLE:
> +000000001fff0000 l    d  \.raml	0000000000000000 \.raml
> +0000000040040000 l    d  \.ramz	0000000000000000 \.ramz
> +0000000000000000 l    df \*ABS\*	0000000000000000 non-contiguous-mem-.*\.o
> +0000000040040000 l       \.ramz	0000000000000000 \$a
> +000000001fff0028 l     F \.raml	000000000000000c __code4_veneer
> +000000001fff0040 g       \.raml	0000000000000000 _raml_end
> +0000000030000000 g       \.raml	0000000000000000 _ramu_start
> +000000001fff000c g     F \.raml	000000000000000c code2
> +0000000040040000 g       \.ramz	0000000000000000 _ramz_start
> +000000001fff0000 g       \.raml	0000000000000000 _raml_start
> +000000001fff0018 g     F \.raml	0000000000000008 code3
> +000000001fff0000 g     F \.raml	000000000000000c code1
> +0000000040040050 g       \.ramz	0000000000000000 _ramz_end
> +0000000040040000 g     F \.ramz	0000000000000050 code4
> +0000000030000000 g       \.raml	0000000000000000 _ramu_end
> +
> +
> +
> +Disassembly of section \.raml:
> +
> +000000001fff0000 \<code1\>:
> +    1fff0000:	d503201f 	nop
> +    1fff0004:	d503201f 	nop
> +    1fff0008:	94000001 	bl	1fff000c \<code2\>
> +
> +000000001fff000c \<code2\>:
> +    1fff000c:	d503201f 	nop
> +    1fff0010:	d503201f 	nop
> +    1fff0014:	94000001 	bl	1fff0018 \<code3\>
> +
> +000000001fff0018 \<code3\>:
> +    1fff0018:	d503201f 	nop
> +    1fff001c:	94000003 	bl	1fff0028 \<__code4_veneer\>
> +    1fff0020:	14000008 	b	1fff0040 \<_raml_end\>
> +    1fff0024:	d503201f 	nop
> +
> +000000001fff0028 \<__code4_veneer\>:
> +    1fff0028:	90100290 	adrp	x16, 40040000 \<code4\>
> +    1fff002c:	91000210 	add	x16, x16, #0x0
> +    1fff0030:	d61f0200 	br	x16
> +	...
> +
> +Disassembly of section \.ramz:
> +
> +0000000040040000 \<code4\>:
> +    40040000:	e1a00000 	.word	0xe1a00000
> +    40040004:	e1a00000 	.word	0xe1a00000
> +    40040008:	e1a00000 	.word	0xe1a00000
> +    4004000c:	e1a00000 	.word	0xe1a00000
> +    40040010:	e1a00000 	.word	0xe1a00000
> +    40040014:	e1a00000 	.word	0xe1a00000
> +    40040018:	e1a00000 	.word	0xe1a00000
> +    4004001c:	e1a00000 	.word	0xe1a00000
> +    40040020:	e1a00000 	.word	0xe1a00000
> +    40040024:	e1a00000 	.word	0xe1a00000
> +    40040028:	e1a00000 	.word	0xe1a00000
> +    4004002c:	e1a00000 	.word	0xe1a00000
> +    40040030:	e1a00000 	.word	0xe1a00000
> +    40040034:	e1a00000 	.word	0xe1a00000
> +    40040038:	e1a00000 	.word	0xe1a00000
> +    4004003c:	e1a00000 	.word	0xe1a00000
> +    40040040:	e1a00000 	.word	0xe1a00000
> +    40040044:	e1a00000 	.word	0xe1a00000
> +    40040048:	e1a00000 	.word	0xe1a00000
> +    4004004c:	e1a00000 	.word	0xe1a00000
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.ld b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.ld
> new file mode 100644
> index 00000000000..127e179b93e
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.ld
> @@ -0,0 +1,31 @@
> +MEMORY
> +{
> +  RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00040
> +  RAMU (rwx) : ORIGIN = 0x30000000, LENGTH = 0x00010
> +  RAMZ (rwx) : ORIGIN = 0x40040000, LENGTH = 0x00400
> +}
> +
> +SECTIONS
> +{
> +  .raml :
> +  { _raml_start = . ;
> +    *(.boot) ;
> +    *(.code) *(.code.*) ;
> +    _raml_end = . ;
> +  } > RAML
> +
> +  .ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
> +  { _ramu_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramu_end = . ;
> +  } > RAMU
> +
> +  /DISCARD/ :
> +  { *(.code.2) *(.code.4) }
> +
> +  .ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
> +  { _ramz_start = . ;
> +    *(.code) *(.code.*) ;
> +    _ramz_end = . ;
> +  } > RAMZ
> +}
> diff --git a/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
> new file mode 100644
> index 00000000000..730599ef289
> --- /dev/null
> +++ b/ld/testsuite/ld-aarch64/non-contiguous-mem/non-contiguous-ok-5.warn
> @@ -0,0 +1,10 @@
> +.*: warning: .* may change behaviour for section .\.code\.1. from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section .\.code\.2. from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section .\.code\.3. from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* may change behaviour for section .\.code\.4. from .* \(assigned to \.raml, but additional match: \.ramu\)
> +.*: warning: .* makes section .\.code\.2. from .* match /DISCARD/ clause\.
> +.*: warning: .* makes section .\.code\.4. from .* match /DISCARD/ clause\.
> +.*: warning: .* may change behaviour for section .\.code\.1. from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +.*: warning: .* may change behaviour for section .\.code\.2. from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +.*: warning: .* may change behaviour for section .\.code\.3. from .* \(assigned to \.ramu, but additional match: \.ramz\)
> +.*: warning: .* may change behaviour for section .\.code\.4. from .* \(assigned to \.ramu, but additional match: \.ramz\)
> -- 
> 2.51.0
> 


More information about the Binutils mailing list