Add support for non-contiguous memory regions

2020-01-06  Christophe Lyon  <christophe.lyon@linaro.org>

	bfd/
	* bfd-in2.h: Regenerate.
	* section.c (asection): Add already_assigned field.
	(BFD_FAKE_SECTION): Add default initializer for it.
	* ecoff.c (bfd_debug_section): Initialize already_assigned field.
	* elf32-arm.c (arm_build_one_stub): Add support for
	non_contiguous_regions.
	* elf32-csky.c (csky_build_one_stub): Likewise.
	* elf32-hppa.c (hppa_build_one_stub): Likewise.
	* elf32-m68hc11.c (m68hc11_elf_build_one_stub): Likewise.
	* elf32-m68hc12.c (m68hc12_elf_build_one_stub): Likewise.
	* elf32-metag.c (metag_build_one_stub): Likewise.
	* elf32-nios2.c (nios2_build_one_stub): Likewise.
	* elf64-ppc.c (ppc_build_one_stub): Likewise.
	(ppc_size_one_stub): Likewise.
	* elfnn-aarch64.c (aarch64_build_one_stub): Likewise.
	* elflink.c (elf_link_input_bfd): Likewise.

	include/
	* bfdlink.h (bfd_link_info): Add non_contiguous_regions and
	non_contiguous_regions_warnings fields.

	ld/
	* ldlang.c (lang_add_section): Add support for
	non_contiguous_regions.
	(size_input_section): Likewise.
	(lang_size_sections_1): Likewise.
	(process_insert_statements): Likewise.
	* ldlex.h (option_values): Add OPTION_NON_CONTIGUOUS_REGIONS and
	OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS.
	* lexsup.c (ld_options): Add entries for
	--enable-non-contiguous-regions and
	--enable-non-contiguous-regions-warnings.
	(parse_args): Handle it.
	* NEWS: Add --enable-non-contiguous-regions and
	--enable-non-contiguous-regions-warnings.
	* ld.texi: Add --enable-non-contiguous-regions and
	--enable-non-contiguous-regions-warnings documentation.
	* emultempl/armelf.em (elf32_arm_add_stub_section): Add
	SEC_LINKER_CREATED flag.
	* emultempl/xtensaelf.em (ld_build_required_section_dependence):
	Emit an error when --enable-non-contiguous-regions is used.
	* testsuite/ld-elf/non-contiguous.d: New.
	* testsuite/ld-elf/non-contiguous.ld: New.
	* testsuite/ld-elf/non-contiguous.s: New.
	* testsuite/ld-arm/arm-elf.exp: Run the new tests.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm.s: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm.ld: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm2.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm3.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm4.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm4.ld: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm5.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm5.ld: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm6.d: New.
	* testsuite/ld-arm/arm-elf/non-contiguous-arm6.ld: New.
	* testsuite/ld-powerpc/powerpc.exp: Run new tests.
	* testsuite/ld-powerpc/non-contiguous-powerpc.d: New.
	* testsuite/ld-powerpc/non-contiguous-powerpc.ld: New.
	* testsuite/ld-powerpc/non-contiguous-powerpc.sd: New.
	* testsuite/ld-powerpc/non-contiguous-powerpc64.d: New.
This commit is contained in:
Christophe Lyon 2019-11-25 08:55:37 +00:00
parent 74e10d1742
commit abf874aafe
46 changed files with 1186 additions and 11 deletions

View File

@ -1,3 +1,22 @@
2020-03-13 Christophe Lyon <christophe.lyon@linaro.org>
* bfd-in2.h: Regenerate.
* section.c (asection): Add already_assigned field.
(BFD_FAKE_SECTION): Add default initializer for it.
* ecoff.c (bfd_debug_section): Initialize already_assigned field.
* elf32-arm.c (arm_build_one_stub): Add support for
non_contiguous_regions.
* elf32-csky.c (csky_build_one_stub): Likewise.
* elf32-hppa.c (hppa_build_one_stub): Likewise.
* elf32-m68hc11.c (m68hc11_elf_build_one_stub): Likewise.
* elf32-m68hc12.c (m68hc12_elf_build_one_stub): Likewise.
* elf32-metag.c (metag_build_one_stub): Likewise.
* elf32-nios2.c (nios2_build_one_stub): Likewise.
* elf64-ppc.c (ppc_build_one_stub): Likewise.
(ppc_size_one_stub): Likewise.
* elfnn-aarch64.c (aarch64_build_one_stub): Likewise.
* elflink.c (elf_link_input_bfd): Likewise.
2020-03-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/24920

View File

@ -1192,6 +1192,10 @@ typedef struct bfd_section
struct bfd_section *s;
const char *linked_to_symbol_name;
} map_head, map_tail;
/* Points to the output section this section is already assigned to, if any.
This is used when support for non-contiguous memory regions is enabled. */
struct bfd_section *already_assigned;
} asection;
/* Relax table contains information about instructions which can
@ -1373,7 +1377,10 @@ discarded_section (const asection *sec)
(struct bfd_symbol *) SYM, &SEC.symbol, \
\
/* map_head, map_tail */ \
{ NULL }, { NULL } \
{ NULL }, { NULL }, \
\
/* already_assigned */ \
NULL \
}
/* We use a macro to initialize the static asymbol structures because

View File

@ -78,8 +78,10 @@ static asection bfd_debug_section =
NULL,
/* symbol_ptr_ptr, */
NULL,
/* map_head, map_tail */
{ NULL }, { NULL }
/* map_head, map_tail, */
{ NULL }, { NULL },
/* already_assigned */
NULL,
};
/* Create an ECOFF object. */

View File

@ -5064,6 +5064,17 @@ arm_build_one_stub (struct bfd_hash_entry *gen_entry,
stub_entry = (struct elf32_arm_stub_hash_entry *) gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
globals = elf32_arm_hash_table (info);
if (globals == NULL)
return FALSE;

View File

@ -3621,6 +3621,17 @@ csky_build_one_stub (struct bfd_hash_entry *gen_entry,
stub_entry = (struct elf32_csky_stub_hash_entry *)gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
globals = csky_elf_hash_table (info);
if (globals == NULL)
return FALSE;

View File

@ -731,6 +731,17 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
switch (hsh->stub_type)
{
case hppa_stub_long_branch:
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (hsh->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
hsh->target_section);
abort();
}
/* Create the long branch. A long branch is formed with "ldil"
loading the upper bits of the target address into a register,
then branching with "be" which adds in the lower bits.
@ -751,6 +762,16 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
break;
case hppa_stub_long_branch_shared:
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (hsh->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign %pA to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
hsh->target_section);
abort();
}
/* Branches are relative. This is where we are going to. */
sym_value = (hsh->target_value
+ hsh->target_section->output_offset
@ -823,6 +844,16 @@ hppa_build_one_stub (struct bfd_hash_entry *bh, void *in_arg)
break;
case hppa_stub_export:
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (hsh->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign %pA to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
hsh->target_section);
abort();
}
/* Branches are relative. This is where we are going to. */
sym_value = (hsh->target_value
+ hsh->target_section->output_offset

View File

@ -415,6 +415,17 @@ m68hc11_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
htab = m68hc11_elf_hash_table (info);
if (htab == NULL)
return FALSE;

View File

@ -535,6 +535,17 @@ m68hc12_elf_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry = (struct elf32_m68hc11_stub_hash_entry *) gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
htab = m68hc11_elf_hash_table (info);
stub_sec = stub_entry->stub_sec;

View File

@ -3459,7 +3459,7 @@ metag_type_of_stub (asection *input_sec,
#define MOV_PC_A0_3 0xa3180ca0
static bfd_boolean
metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_UNUSED)
metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
{
struct elf_metag_stub_hash_entry *hsh;
asection *stub_sec;
@ -3467,9 +3467,22 @@ metag_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U
bfd_byte *loc;
bfd_vma sym_value;
int size;
struct bfd_link_info *info;
/* Massage our args to the form they really have. */
hsh = (struct elf_metag_stub_hash_entry *) gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (hsh->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
hsh->target_section);
abort();
}
stub_sec = hsh->stub_sec;

View File

@ -2490,7 +2490,20 @@ nios2_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg ATTRIBUTE_U
= (struct elf32_nios2_stub_hash_entry *) gen_entry;
asection *stub_sec = hsh->stub_sec;
bfd_vma sym_value;
struct bfd_link_info *info;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (hsh->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
hsh->target_section);
abort();
}
/* Make a note of the offset within the stubs for this entry. */
hsh->stub_offset = stub_sec->size;

View File

@ -11362,6 +11362,31 @@ ppc_build_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
stub_entry = (struct ppc_stub_hash_entry *) gen_entry;
info = in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section != NULL
&& stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
/* Same for the group. */
if (stub_entry->group->stub_sec != NULL
&& stub_entry->group->stub_sec->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign group %pA target %pA to an "
"output section. Retry without "
"--enable-non-contiguous-regions.\n"),
stub_entry->group->stub_sec,
stub_entry->target_section);
abort();
}
htab = ppc_hash_table (info);
if (htab == NULL)
return FALSE;
@ -11887,6 +11912,31 @@ ppc_size_one_stub (struct bfd_hash_entry *gen_entry, void *in_arg)
if (htab == NULL)
return FALSE;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section != NULL
&& stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign %pA to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
/* Same for the group. */
if (stub_entry->group->stub_sec != NULL
&& stub_entry->group->stub_sec->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign group %pA target %pA to an "
"output section. Retry without "
"--enable-non-contiguous-regions.\n"),
stub_entry->group->stub_sec,
stub_entry->target_section);
abort();
}
/* Make a note of the offset within the stubs for this entry. */
stub_entry->stub_offset = stub_entry->group->stub_sec->size;

View File

@ -10567,6 +10567,18 @@ elf_link_input_bfd (struct elf_final_link_info *flinfo, bfd *input_bfd)
/* If this symbol is defined in a section which we are
discarding, we don't need to keep it. */
if (isym->st_shndx != SHN_UNDEF
&& isym->st_shndx < SHN_LORESERVE
&& isec->output_section == NULL
&& flinfo->info->non_contiguous_regions
&& flinfo->info->non_contiguous_regions_warnings)
{
_bfd_error_handler (_("warning: --enable-non-contiguous-regions "
"discards section `%s' from '%s'\n"),
isec->name, isec->owner->filename);
continue;
}
if (isym->st_shndx != SHN_UNDEF
&& isym->st_shndx < SHN_LORESERVE
&& bfd_section_removed_from_list (output_bfd,

View File

@ -3278,7 +3278,7 @@ _bfd_aarch64_add_stub_entry_after (const char *stub_name,
static bfd_boolean
aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
void *in_arg ATTRIBUTE_UNUSED)
void *in_arg)
{
struct elf_aarch64_stub_hash_entry *stub_entry;
asection *stub_sec;
@ -3291,10 +3291,24 @@ aarch64_build_one_stub (struct bfd_hash_entry *gen_entry,
unsigned int template_size;
const uint32_t *template;
unsigned int i;
struct bfd_link_info *info;
/* Massage our args to the form they really have. */
stub_entry = (struct elf_aarch64_stub_hash_entry *) gen_entry;
info = (struct bfd_link_info *) in_arg;
/* Fail if the target section could not be assigned to an output
section. The user should fix his linker script. */
if (stub_entry->target_section->output_section == NULL
&& info->non_contiguous_regions)
{
_bfd_error_handler (_("Could not assign '%pA' to an output section. "
"Retry without --enable-non-contiguous-regions.\n"),
stub_entry->target_section);
abort();
}
stub_sec = stub_entry->stub_sec;
/* Make a note of the offset within the stubs for this entry. */

View File

@ -551,6 +551,10 @@ CODE_FRAGMENT
. struct bfd_section *s;
. const char *linked_to_symbol_name;
. } map_head, map_tail;
. {* Points to the output section this section is already assigned to, if any.
. This is used when support for non-contiguous memory regions is enabled. *}
. struct bfd_section *already_assigned;
.
.} asection;
.
.{* Relax table contains information about instructions which can
@ -732,7 +736,10 @@ CODE_FRAGMENT
. (struct bfd_symbol *) SYM, &SEC.symbol, \
. \
. {* map_head, map_tail *} \
. { NULL }, { NULL } \
. { NULL }, { NULL }, \
. \
. {* already_assigned *} \
. NULL \
. }
.
.{* We use a macro to initialize the static asymbol structures because

View File

@ -1,3 +1,8 @@
2020-03-13 Christophe Lyon <christophe.lyon@linaro.org>
* bfdlink.h (bfd_link_info): Add non_contiguous_regions and
non_contiguous_regions_warnings fields.
2020-03-13 Christian Eggers <ceggers@gmx.de>
* bfdlink.h (struct bfd_link_order): Add unit (bytes/octets) to

View File

@ -501,6 +501,14 @@ struct bfd_link_info
/* TRUE if "-Map map" is passed to linker. */
unsigned int has_map_file : 1;
/* TRUE if "--enable-non-contiguous-regions" is passed to the
linker. */
unsigned int non_contiguous_regions : 1;
/* TRUE if "--enable-non-contiguous-regions-warnings" is passed to
the linker. */
unsigned int non_contiguous_regions_warnings : 1;
/* Char that may appear as the first char of a symbol, but should be
skipped (like symbol_leading_char) when looking up symbols in
wrap_hash. Used by PowerPC Linux for 'dot' symbols. */

View File

@ -1,3 +1,47 @@
2020-03-13 Christophe Lyon <christophe.lyon@linaro.org>
* ldlang.c (lang_add_section): Add support for
non_contiguous_regions.
(size_input_section): Likewise.
(lang_size_sections_1): Likewise.
(process_insert_statements): Likewise.
* ldlex.h (option_values): Add OPTION_NON_CONTIGUOUS_REGIONS and
OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS.
* lexsup.c (ld_options): Add entries for
--enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings.
(parse_args): Handle it.
* NEWS: Add --enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings.
* ld.texi: Add --enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings documentation.
* emultempl/armelf.em (elf32_arm_add_stub_section): Add
SEC_LINKER_CREATED flag.
* emultempl/xtensaelf.em (ld_build_required_section_dependence):
Emit an error when --enable-non-contiguous-regions is used.
* testsuite/ld-elf/non-contiguous.d: New.
* testsuite/ld-elf/non-contiguous.ld: New.
* testsuite/ld-elf/non-contiguous.s: New.
* testsuite/ld-arm/arm-elf.exp: Run the new tests.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.s: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm2.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm3.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm4.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm4.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm5.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm5.ld: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm6.d: New.
* testsuite/ld-arm/arm-elf/non-contiguous-arm6.ld: New.
* testsuite/ld-powerpc/powerpc.exp: Run new tests.
* testsuite/ld-powerpc/non-contiguous-powerpc.d: New.
* testsuite/ld-powerpc/non-contiguous-powerpc.ld: New.
* testsuite/ld-powerpc/non-contiguous-powerpc.sd: New.
* testsuite/ld-powerpc/non-contiguous-powerpc64.d: New.
2020-03-13 H.J. Lu <hongjiu.lu@intel.com>
PR ld/24920

View File

@ -1,5 +1,8 @@
-*- text -*-
* Add command-line options --enable-non-contiguous-regions and
--enable-non-contiguous-regions-warnings.
Changes in 2.34:
* The ld check for "PHDR segment not covered by LOAD segment" is more

View File

@ -227,7 +227,8 @@ elf32_arm_add_stub_section (const char * stub_sec_name,
struct hook_stub_info info;
flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_CODE
| SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP);
| SEC_HAS_CONTENTS | SEC_RELOC | SEC_IN_MEMORY | SEC_KEEP
| SEC_LINKER_CREATED);
stub_sec = bfd_make_section_anyway_with_flags (stub_file->the_bfd,
stub_sec_name, flags);
if (stub_sec == NULL)

View File

@ -1224,6 +1224,12 @@ ld_build_required_section_dependence (lang_statement_union_type *s)
{
lang_statement_union_type *l = iter_stack_current (&stack);
if (l == NULL && link_info.non_contiguous_regions)
{
einfo (_("Relaxation not supported with --enable-non-contiguous-regions.\n"));
abort();
}
if (l->header.type == lang_input_section_enum)
{
lang_input_section_type *input;

View File

@ -459,6 +459,48 @@ 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-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.*); @} > MEM2
@}
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}

View File

@ -2540,6 +2540,11 @@ lang_add_section (lang_statement_list_type *ptr,
/* This prevents future calls from assigning this section. */
section->output_section = bfd_abs_section_ptr;
}
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;
}
@ -2553,7 +2558,33 @@ lang_add_section (lang_statement_list_type *ptr,
}
if (section->output_section != NULL)
return;
{
if (!link_info.non_contiguous_regions)
return;
/* SECTION has already been handled in a special way
(eg. LINK_ONCE): skip it. */
if (bfd_is_abs_section (section->output_section))
return;
/* 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;
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. */
}
/* 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
@ -4197,6 +4228,12 @@ process_insert_statements (lang_statement_union_type **start)
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)
{
@ -5119,11 +5156,27 @@ size_input_section
(lang_statement_union_type **this_ptr,
lang_output_section_statement_type *output_section_statement,
fill_type *fill,
bfd_boolean *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;
@ -5155,6 +5208,42 @@ size_input_section
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 (_("Output section '%s' not large enough for the "
"linker-created stubs section '%s'.\n"),
i->output_section->name, i->name);
abort();
}
if (i->rawsize && i->rawsize != i->size)
{
einfo (_("Relaxation not supported with "
"--enable-non-contiguous-regions (section '%s' "
"would overflow '%s' after it changed size).\n"),
i->name, i->output_section->name);
abort();
}
*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;
@ -5162,6 +5251,14 @@ size_input_section
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;
@ -5448,10 +5545,14 @@ lang_size_sections_1
bfd_boolean check_regions)
{
lang_statement_union_type *s;
lang_statement_union_type *prev_s = NULL;
bfd_boolean removed_prev_s = FALSE;
/* Size up the sections from their constituent parts. */
for (s = *prev; s != NULL; s = s->header.next)
for (s = *prev; s != NULL; prev_s = s, s = s->header.next)
{
bfd_boolean removed=FALSE;
switch (s->header.type)
{
case lang_output_section_statement_enum:
@ -5885,7 +5986,7 @@ lang_size_sections_1
*relax = TRUE;
}
dot = size_input_section (prev, output_section_statement,
fill, dot);
fill, &removed, dot);
}
break;
@ -5990,7 +6091,43 @@ lang_size_sections_1
FAIL ();
break;
}
prev = &s->header.next;
/* 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;
}

View File

@ -150,6 +150,8 @@ enum option_values
OPTION_FORCE_GROUP_ALLOCATION,
OPTION_PRINT_MAP_DISCARDED,
OPTION_NO_PRINT_MAP_DISCARDED,
OPTION_NON_CONTIGUOUS_REGIONS,
OPTION_NON_CONTIGUOUS_REGIONS_WARNINGS,
};
/* The initial parser states. */

View File

@ -122,6 +122,10 @@ static const struct ld_option ld_options[] =
'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 },
{ {"EB", no_argument, NULL, OPTION_EB},
'\0', NULL, N_("Link big-endian objects"), ONE_DASH },
{ {"EL", no_argument, NULL, OPTION_EL},
@ -845,6 +849,12 @@ parse_args (unsigned argc, char **argv)
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 'e':
lang_add_entry (optarg, TRUE);
break;

View File

@ -1261,3 +1261,10 @@ set arm_unwind_tests {
"unwind-mix"}
}
run_ld_link_tests $arm_unwind_tests
run_dump_test "non-contiguous-arm"
run_dump_test "non-contiguous-arm2"
run_dump_test "non-contiguous-arm3"
run_dump_test "non-contiguous-arm4"
run_dump_test "non-contiguous-arm5"
run_dump_test "non-contiguous-arm6"

View File

@ -0,0 +1,4 @@
#name: non-contiguous-arm
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm.ld
# error: \A.*Could not assign '.code.4' to an output section. Retry without --enable-non-contiguous-regions.*\Z

View File

@ -0,0 +1,34 @@
/*
sections .code.1 and .code.2 fit in .raml
section .code.3 fits in .ramu
section .code.4 too large to fit
expect an error about .code.4
*/
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
}

View File

@ -0,0 +1,35 @@
.syntax unified
.section .code.1, "ax", %progbits
.arm
# Fit in RAML
.global code1
.type code1, %function
code1:
nop
nop
bl code2
.section .code.2, "ax", %progbits
# Fit in RAML
.global code2
.type code2, %function
code2:
nop
nop
bl code3
.section .code.3, "ax", %progbits
# Fit in RAMU
.global code3
.type code3, %function
code3:
nop
bl code4
.section .code.4, "ax", %progbits
# Fit in RAMZ
.global code4
.type code4, %function
code4:
$a:
.fill 20, 4, 0xe1a00000

View File

@ -0,0 +1,77 @@
#name: non-contiguous-arm2
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm2.ld
#objdump: -rdth
#xfail: [is_generic]
.*: file format elf32-(little|big)arm.*
Sections:
Idx Name Size VMA LMA File off Algn
0 \.raml 00000018 1fff0000 1fff0000 00010000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 \.ramu 00000008 20000000 1fff0018 00020000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 \.ramz 00000050 20040000 20000008 00030000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .ARM.attributes 00000012 00000000 00000000 .* 2\*\*0
CONTENTS, READONLY
SYMBOL TABLE:
1fff0000 l d .raml 00000000 .raml
20000000 l d .ramu 00000000 .ramu
20040000 l d .ramz 00000000 .ramz
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df \*ABS\* 00000000 .*/non-contiguous-arm.o
1fff0018 g .raml 00000000 _raml_end
20000000 g .ramu 00000000 _ramu_start
1fff000c g F .raml 00000000 code2
20040000 g .ramz 00000000 _ramz_start
1fff0000 g .raml 00000000 _raml_start
20000000 g F .ramu 00000000 code3
1fff0000 g F .raml 00000000 code1
20040050 g .ramz 00000000 _ramz_end
20040000 g F .ramz 00000000 code4
20000008 g .ramu 00000000 _ramu_end
Disassembly of section .raml:
1fff0000 \<code1\>:
1fff0000: e1a00000 nop ; \(mov r0, r0\)
1fff0004: e1a00000 nop ; \(mov r0, r0\)
1fff0008: ebffffff bl 1fff000c \<code2\>
1fff000c \<code2\>:
1fff000c: e1a00000 nop ; \(mov r0, r0\)
1fff0010: e1a00000 nop ; \(mov r0, r0\)
1fff0014: eb003ff9 bl 20000000 \<code3\>
Disassembly of section .ramu:
20000000 \<code3\>:
20000000: e1a00000 nop ; \(mov r0, r0\)
20000004: eb00fffd bl 20040000 \<code4\>
Disassembly of section .ramz:
20040000 \<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

View File

@ -0,0 +1,33 @@
/*
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
*/
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
}

View File

@ -0,0 +1,83 @@
#name: non-contiguous-arm3
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm3.ld
#objdump: -rdth
#xfail: [is_generic]
#skip: arm*nacl
.*: file format elf32-(little|big)arm
Sections:
Idx Name Size VMA LMA File off Algn
0 \.raml 00000018 1fff0000 1fff0000 00010000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 \.ramu 00000010 20000000 1fff0018 00020000 2\*\*3
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 \.ramz 00000050 30040000 20000010 00030000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .ARM.attributes 00000012 00000000 00000000 00030050 2\*\*0
CONTENTS, READONLY
SYMBOL TABLE:
1fff0000 l d .raml 00000000 .raml
20000000 l d .ramu 00000000 .ramu
30040000 l d .ramz 00000000 .ramz
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df \*ABS\* 00000000 .*/non-contiguous-arm.o
20000008 l F .ramu 00000008 __code4_veneer
1fff0018 g .raml 00000000 _raml_end
20000000 g .ramu 00000000 _ramu_start
1fff000c g F .raml 00000000 code2
30040000 g .ramz 00000000 _ramz_start
1fff0000 g .raml 00000000 _raml_start
20000000 g F .ramu 00000000 code3
1fff0000 g F .raml 00000000 code1
30040050 g .ramz 00000000 _ramz_end
30040000 g F .ramz 00000000 code4
20000010 g .ramu 00000000 _ramu_end
Disassembly of section .raml:
1fff0000 \<code1\>:
1fff0000: e1a00000 nop ; \(mov r0, r0\)
1fff0004: e1a00000 nop ; \(mov r0, r0\)
1fff0008: ebffffff bl 1fff000c \<code2\>
1fff000c \<code2\>:
1fff000c: e1a00000 nop ; \(mov r0, r0\)
1fff0010: e1a00000 nop ; \(mov r0, r0\)
1fff0014: eb003ff9 bl 20000000 \<code3\>
Disassembly of section .ramu:
20000000 \<code3\>:
20000000: e1a00000 nop ; \(mov r0, r0\)
20000004: ebffffff bl 20000008 \<__code4_veneer\>
20000008 \<__code4_veneer\>:
20000008: e51ff004 ldr pc, \[pc, #-4\] ; 2000000c \<__code4_veneer\+0x4\>
2000000c: 30040000 .word 0x30040000
Disassembly of section .ramz:
30040000 \<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

View File

@ -0,0 +1,33 @@
/*
sections .code.1 and .code.2 fit in .raml
section .code.3 fits in .ramu even with a farcall stub to jump to code4
section .code.4 fits in .ramz
*/
MEMORY
{
RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00010
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
}

View File

@ -0,0 +1,4 @@
#name: non-contiguous-arm4
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm4.ld
# error: \AOutput section '.ramu' not large enough for the linker-created stubs section '.code.3.__stub'.*\Z

View File

@ -0,0 +1,34 @@
/*
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
expect an error about .code.3
*/
MEMORY
{
RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x0001c
RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008
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
}

View File

@ -0,0 +1,77 @@
#name: non-contiguous-arm5
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm5.ld
#objdump: -rdth
#xfail: [is_generic]
.*: file format elf32-(little|big)arm.*
Sections:
Idx Name Size VMA LMA File off Algn
0 \.raml 0000000c 1fff0000 1fff0000 00010000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 \.ramu 00000014 20000000 1fff000c 00020000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 \.ramz 00000050 20040000 20000014 00030000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
3 .ARM.attributes 00000012 00000000 00000000 .* 2\*\*0
CONTENTS, READONLY
SYMBOL TABLE:
1fff0000 l d .raml 00000000 .raml
20000000 l d .ramu 00000000 .ramu
20040000 l d .ramz 00000000 .ramz
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df \*ABS\* 00000000 .*/non-contiguous-arm.o
1fff000c g .raml 00000000 _raml_end
20000000 g .ramu 00000000 _ramu_start
20000000 g F .ramu 00000000 code2
20040000 g .ramz 00000000 _ramz_start
1fff0000 g .raml 00000000 _raml_start
2000000c g F .ramu 00000000 code3
1fff0000 g F .raml 00000000 code1
20040050 g .ramz 00000000 _ramz_end
20040000 g F .ramz 00000000 code4
20000014 g .ramu 00000000 _ramu_end
Disassembly of section .raml:
1fff0000 \<code1\>:
1fff0000: e1a00000 nop ; \(mov r0, r0\)
1fff0004: e1a00000 nop ; \(mov r0, r0\)
1fff0008: eb003ffc bl 20000000 \<code2\>
Disassembly of section .ramu:
20000000 \<code2\>:
20000000: e1a00000 nop ; \(mov r0, r0\)
20000004: e1a00000 nop ; \(mov r0, r0\)
20000008: ebffffff bl 2000000c \<code3\>
2000000c \<code3\>:
2000000c: e1a00000 nop ; \(mov r0, r0\)
20000010: eb00fffa bl 20040000 \<code4\>
Disassembly of section .ramz:
20040000 \<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

View File

@ -0,0 +1,34 @@
/*
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
*/
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
}

View File

@ -0,0 +1,77 @@
#name: non-contiguous-arm6
#source: non-contiguous-arm.s
#ld: --enable-non-contiguous-regions -T non-contiguous-arm6.ld
#objdump: -rdth
#xfail: [is_generic]
#skip: arm*nacl
.*: file format elf32-(little|big)arm
Sections:
Idx Name Size VMA LMA File off Algn
0 \.raml 00000028 1fff0000 1fff0000 00010000 2\*\*3
CONTENTS, ALLOC, LOAD, READONLY, CODE
1 \.ramz 00000050 40040000 30000000 00020000 2\*\*2
CONTENTS, ALLOC, LOAD, READONLY, CODE
2 .ARM.attributes 00000012 00000000 00000000 00020050 2\*\*0
CONTENTS, READONLY
SYMBOL TABLE:
1fff0000 l d .raml 00000000 .raml
40040000 l d .ramz 00000000 .ramz
00000000 l d .ARM.attributes 00000000 .ARM.attributes
00000000 l df \*ABS\* 00000000 .*/non-contiguous-arm.o
1fff0020 l F .raml 00000008 __code4_veneer
1fff0028 g .raml 00000000 _raml_end
30000000 g .raml 00000000 _ramu_start
1fff000c g F .raml 00000000 code2
40040000 g .ramz 00000000 _ramz_start
1fff0000 g .raml 00000000 _raml_start
1fff0018 g F .raml 00000000 code3
1fff0000 g F .raml 00000000 code1
40040050 g .ramz 00000000 _ramz_end
40040000 g F .ramz 00000000 code4
30000000 g .raml 00000000 _ramu_end
Disassembly of section .raml:
1fff0000 \<code1\>:
1fff0000: e1a00000 nop ; \(mov r0, r0\)
1fff0004: e1a00000 nop ; \(mov r0, r0\)
1fff0008: ebffffff bl 1fff000c \<code2\>
1fff000c \<code2\>:
1fff000c: e1a00000 nop ; \(mov r0, r0\)
1fff0010: e1a00000 nop ; \(mov r0, r0\)
1fff0014: ebffffff bl 1fff0018 \<code3\>
1fff0018 \<code3\>:
1fff0018: e1a00000 nop ; \(mov r0, r0\)
1fff001c: ebffffff bl 1fff0020 \<__code4_veneer\>
1fff0020 \<__code4_veneer\>:
1fff0020: e51ff004 ldr pc, \[pc, #-4\] ; 1fff0024 \<__code4_veneer\+0x4\>
1fff0024: 40040000 .word 0x40040000
Disassembly of section .ramz:
40040000 \<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

View File

@ -0,0 +1,33 @@
/*
sections .code.1, .code.2 and .code.3 (+ farcall stub) fit in .raml
section .code.4 fits in .ramz
nothing fits in .ramu
*/
MEMORY
{
RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00030
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
}

View File

@ -0,0 +1,29 @@
#name: non-contiguous
#source: non-contiguous.s
#ld: --enable-non-contiguous-regions -T non-contiguous.ld
#objdump: -rdsh
#xfail: [is_generic]
#skip: xtensa*
.*: file format .*
Sections:
Idx Name Size VMA * LMA * File off Algn
0 \.raml 0000000c 0*1fff0000 0*1fff0000 .* 2\*\*.
CONTENTS, ALLOC, LOAD, DATA
1 \.ramu 00000014 0*20000000 0*1fff000c .* 2\*\*.
CONTENTS, ALLOC, LOAD, DATA
2 \.ramz 0000003c 0*20040000 0*20000014 .* 2\*\*.
CONTENTS, ALLOC, LOAD, DATA
Contents of section .raml:
1fff0000 (010+ 020+ 030+|0+01 0+02 0+03) ............
Contents of section .ramu:
20000000 (040+ 050+ 060+ 070+|0+04 0+05 0+06 0+07) ................
20000010 (080+|0+08) ....
Contents of section .ramz:
20040000 09090909 09090909 09090909 09090909 ................
20040010 09090909 09090909 09090909 09090909 ................
20040020 09090909 09090909 09090909 09090909 ................
20040030 09090909 09090909 09090909 ............

View File

@ -0,0 +1,47 @@
/*
section .data.1 fits in .raml
sections .data.2 .data.3 fit in .ramu
section .data.4 fits in .ramz
*/
MEMORY
{
RAML (rwx) : ORIGIN = 0x1FFF0000, LENGTH = 0x00014
RAMU (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040
RAMZ (rwx) : ORIGIN = 0x20040000, LENGTH = 0x00040
}
SECTIONS
{
/* Ignore this target specific info in output comparison. */
/DISCARD/ : {
*(.ARM.attributes)
*(.ARC.attributes)
*(.riscv.attributes)
*(.c6xabi.attributes)
*(.trampolines)
*(.reginfo)
*(.note.renesas)
*(.MIPS.abiflags)
*(.MSP430.attributes)
*(.gnu.attributes)
}
.raml : /*AT ( ADDR (.text) + SIZEOF (.text) )*/
{ _raml_start = . ;
*(.boot) ;
*(.data) *(.data.*) ;
_raml_end = . ;
} > RAML
.ramu : AT ( ADDR (.raml) + SIZEOF (.raml) )
{ _ramu_start = . ;
*(.data) *(.data.*) ;
_ramu_end = . ;
} > RAMU
.ramz : AT ( ADDR (.ramu) + SIZEOF (.ramu) )
{ _ramz_start = . ;
*(.data) *(.data.*) ;
_ramz_end = . ;
} > RAMZ
}

View File

@ -0,0 +1,21 @@
.section .data.1, "a", %progbits
# Fit in RAML
.4byte 1
.4byte 2
.4byte 3
.section .data.2, "a", %progbits
# Fit in RAMU
.4byte 4
.4byte 5
.4byte 6
.section .data.3, "a", %progbits
# Fit in RAMU
.4byte 7
.4byte 8
.section .data.4, "a", %progbits
# Fit in RAMZ
.fill 0x3c, 1, 9

View File

@ -0,0 +1,5 @@
#name: non-contiguous-powerpc
#source: non-contiguous-powerpc.s
#ld: --enable-non-contiguous-regions -T non-contiguous-powerpc.ld
#error: \ARelaxation not supported with --enable-non-contiguous-regions.*
#skip: powerpc64*-*

View File

@ -0,0 +1,22 @@
/* Distance between 'one' and 'two' means that relaxation implies that
.text.one's size increases. Even though the result would fit in
'oneandhalf', this is not supported by
--enable-non-contiguous-regions. */
MEMORY {
one (RXAI) : ORIGIN = 0x00000000, LENGTH = 0x00000010
oneandhalf (RXAI) : ORIGIN = 0x00001000, LENGTH = 0x00001010
two (RXAI) : ORIGIN = 0x20000000, LENGTH = 0x10000000
}
SECTIONS {
one : {
*(.text.one)
} > one
oneandhalf : {
*(.text.one)
} > oneandhalf
two : {
*(.text.two)
} > two
}

View File

@ -0,0 +1,8 @@
.machine "ppc"
.section .text.one
b 2f
.section .text.two
2:
nop

View File

@ -0,0 +1,5 @@
#name: non-contiguous-powerpc64
#source: non-contiguous-powerpc.s
#as: -a64
#ld: -melf64ppc --enable-non-contiguous-regions -T non-contiguous-powerpc.ld
#error: .*Could not assign group.*

View File

@ -405,6 +405,7 @@ if [ supports_ppc64 ] then {
run_dump_test "tlsgd"
run_dump_test "tlsld"
run_dump_test "tlsie"
run_dump_test "non-contiguous-powerpc64"
}
run_dump_test "localgot"
@ -443,3 +444,5 @@ run_dump_test "vle-multiseg-6"
run_dump_test "ppc476-shared"
run_dump_test "ppc476-shared2"
run_dump_test "non-contiguous-powerpc"