* [PATCH 1/2][LD] Add new %pU vfinfo format for printing linker script name
2020-01-16 11:48 [PATCH 0/2][MSP430][LD] Fix alignment of __*_array_start symbols in default linker script Jozef Lawrynowicz
@ 2020-01-16 11:50 ` Jozef Lawrynowicz
2020-01-16 11:53 ` [PATCH 2/2][LD][MSP430] Fix alignment of __*_array_start symbols in default linker script Jozef Lawrynowicz
1 sibling, 0 replies; 4+ messages in thread
From: Jozef Lawrynowicz @ 2020-01-16 11:50 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 418 bytes --]
On Thu, 16 Jan 2020 11:48:27 +0000
Jozef Lawrynowicz <jozef.l@mittosystems.com> wrote:
>
> To support warning when the __*array_start symbols are misaligned, without
> knowing the location of the symbols within the linker script, a new format
> specifier "%pU" has been added to vfinfo. This prints the name of the linker
> script, without trying to print the line number (the "%pS" specifier will print
> both).
>
[-- Attachment #2: 0001-LD-Add-new-pU-vfinfo-format-for-printing-linker-scri.patch --]
[-- Type: text/x-patch, Size: 1756 bytes --]
From 23768021b791fa8e30a2faeb5656edf6fc0097fb Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 16 Jan 2020 10:06:05 +0000
Subject: [PATCH 1/2] LD: Add new %pU vfinfo format for printing linker script
name
ld/ChangeLog:
2020-01-16 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* ldmisc.c (vfinfo): Support new "%pU" format specifier.
---
ld/ldmisc.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/ld/ldmisc.c b/ld/ldmisc.c
index b714b97105..5f6fa767d8 100644
--- a/ld/ldmisc.c
+++ b/ld/ldmisc.c
@@ -59,6 +59,7 @@
%pR info about a relent
%pS print script file and linenumber from etree_type.
%pT symbol name
+ %pU print script file without linenumber from etree_type.
%s arbitrary string, like printf
%u integer, like printf
%v hex bfd_vma, no leading zeros
@@ -489,9 +490,9 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bfd_boolean is_warning)
relent->addend,
relent->howto->name);
}
- else if (*fmt == 'S')
+ else if (*fmt == 'S' || *fmt == 'U')
{
- /* Print script file and linenumber. */
+ /* Print script file and maybe the associated linenumber. */
etree_type node;
etree_type *tp = (etree_type *) args[arg_no].p;
@@ -503,8 +504,10 @@ vfinfo (FILE *fp, const char *fmt, va_list ap, bfd_boolean is_warning)
tp->type.filename = ldlex_filename ();
tp->type.lineno = lineno;
}
- if (tp->type.filename != NULL)
+ if (tp->type.filename != NULL && fmt[-1] == 'S')
fprintf (fp, "%s:%u", tp->type.filename, tp->type.lineno);
+ else if (tp->type.filename != NULL && fmt[-1] == 'U')
+ fprintf (fp, "%s", tp->type.filename);
}
else if (*fmt == 'T')
{
--
2.17.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 2/2][LD][MSP430] Fix alignment of __*_array_start symbols in default linker script
2020-01-16 11:48 [PATCH 0/2][MSP430][LD] Fix alignment of __*_array_start symbols in default linker script Jozef Lawrynowicz
2020-01-16 11:50 ` [PATCH 1/2][LD] Add new %pU vfinfo format for printing linker script name Jozef Lawrynowicz
@ 2020-01-16 11:53 ` Jozef Lawrynowicz
1 sibling, 0 replies; 4+ messages in thread
From: Jozef Lawrynowicz @ 2020-01-16 11:53 UTC (permalink / raw)
To: binutils
[-- Attachment #1: Type: text/plain, Size: 216 bytes --]
The attached patch adds align directives before __*_array_start symbols in
the default linker script, and also adds a warning to the MSP430 linker which
alerts the user if the __*array_start symbols are misaligned.
[-- Attachment #2: 0002-MSP430-Fix-alignment-of-__-_array_start-symbols-in-d.patch --]
[-- Type: text/x-patch, Size: 13875 bytes --]
From 9f9311222ff847e33c2ef296a07090db925c246d Mon Sep 17 00:00:00 2001
From: Jozef Lawrynowicz <jozef.l@mittosystems.com>
Date: Thu, 16 Jan 2020 10:34:21 +0000
Subject: [PATCH 2/2] MSP430: Fix alignment of __*_array_start symbols in
default linker script
ld/ChangeLog:
2020-01-16 Jozef Lawrynowicz <jozef.l@mittosystems.com>
* emultempl/msp430.em (input_section_exists): New.
(check_array_section_alignment): New.
(gld${EMULATION_NAME}_finish): New.
* scripttempl/elf32msp430.sc: Add ALIGN directives before the
definition of __*_array_start symbols.
* testsuite/ld-msp430-elf/finiarray-warn.ld: New test.
* testsuite/ld-msp430-elf/finiarray-warn.r: New test.
* testsuite/ld-msp430-elf/initarray-nowarn.ld: New test.
* testsuite/ld-msp430-elf/initarray-warn.ld: New test.
* testsuite/ld-msp430-elf/initarray-warn.r: New test.
* testsuite/ld-msp430-elf/initarray.s: New test.
* testsuite/ld-msp430-elf/msp430-elf.exp: Run new tests.
* testsuite/ld-msp430-elf/preinitarray-warn.ld: New test.
* testsuite/ld-msp430-elf/preinitarray-warn.r: New test.
---
ld/emultempl/msp430.em | 81 ++++++++++++++++++-
ld/scripttempl/elf32msp430.sc | 3 +
ld/testsuite/ld-msp430-elf/finiarray-warn.ld | 46 +++++++++++
ld/testsuite/ld-msp430-elf/finiarray-warn.r | 1 +
.../ld-msp430-elf/initarray-nowarn.ld | 45 +++++++++++
ld/testsuite/ld-msp430-elf/initarray-nowarn.r | 0
ld/testsuite/ld-msp430-elf/initarray-warn.ld | 46 +++++++++++
ld/testsuite/ld-msp430-elf/initarray-warn.r | 1 +
ld/testsuite/ld-msp430-elf/initarray.s | 22 +++++
ld/testsuite/ld-msp430-elf/msp430-elf.exp | 13 +++
.../ld-msp430-elf/preinitarray-warn.ld | 46 +++++++++++
.../ld-msp430-elf/preinitarray-warn.r | 1 +
12 files changed, 304 insertions(+), 1 deletion(-)
create mode 100644 ld/testsuite/ld-msp430-elf/finiarray-warn.ld
create mode 100644 ld/testsuite/ld-msp430-elf/finiarray-warn.r
create mode 100644 ld/testsuite/ld-msp430-elf/initarray-nowarn.ld
create mode 100644 ld/testsuite/ld-msp430-elf/initarray-nowarn.r
create mode 100644 ld/testsuite/ld-msp430-elf/initarray-warn.ld
create mode 100644 ld/testsuite/ld-msp430-elf/initarray-warn.r
create mode 100644 ld/testsuite/ld-msp430-elf/initarray.s
create mode 100644 ld/testsuite/ld-msp430-elf/preinitarray-warn.ld
create mode 100644 ld/testsuite/ld-msp430-elf/preinitarray-warn.r
diff --git a/ld/emultempl/msp430.em b/ld/emultempl/msp430.em
index df940672ba..86ae5eb39e 100644
--- a/ld/emultempl/msp430.em
+++ b/ld/emultempl/msp430.em
@@ -817,6 +817,85 @@ msp430_elf_after_allocation (void)
gld${EMULATION_NAME}_after_allocation ();
}
+/* Return TRUE if a non-debug input section in L has positive size and matches
+ the given name. */
+static int
+input_section_exists (lang_statement_union_type * l, const char * name)
+{
+ while (l != NULL)
+ {
+ switch (l->header.type)
+ {
+ case lang_input_section_enum:
+ if ((l->input_section.section->flags & SEC_ALLOC)
+ && l->input_section.section->size > 0
+ && !strcmp (l->input_section.section->name, name))
+ return TRUE;
+ break;
+
+ case lang_wild_statement_enum:
+ if (input_section_exists (l->wild_statement.children.head, name))
+ return TRUE;
+ break;
+
+ default:
+ break;
+ }
+ l = l->header.next;
+ }
+ return FALSE;
+}
+
+/* Some MSP430 linker scripts do not include ALIGN directives to ensure
+ __preinit_array_start, __init_array_start or __fini_array_start are word
+ aligned.
+ If __*_array_start symbols are not word aligned, the code in crt0 to run
+ through the array and call the functions will crash.
+ To avoid warning unnecessarily when the .*_array sections are not being
+ used for running constructors/destructors, we only emit the warning if
+ the associated section exists and has size. */
+static void
+check_array_section_alignment (void)
+{
+ int i;
+ lang_output_section_statement_type * rodata_sec;
+ lang_output_section_statement_type * rodata2_sec;
+ const char * array_names[3][2] = { { ".init_array", "__init_array_start" },
+ { ".preinit_array", "__preinit_array_start" },
+ { ".fini_array", "__fini_array_start" } };
+
+ /* .{preinit,init,fini}_array could be in either .rodata or .rodata2. */
+ rodata_sec = lang_output_section_find (".rodata");
+ rodata2_sec = lang_output_section_find (".rodata2");
+ if (rodata_sec == NULL && rodata2_sec == NULL)
+ return;
+
+ /* There are 3 .*_array sections which must be checked for alignment. */
+ for (i = 0; i < 3; i++)
+ {
+ struct bfd_link_hash_entry * sym;
+ if (((rodata_sec && input_section_exists (rodata_sec->children.head,
+ array_names[i][0]))
+ || (rodata2_sec && input_section_exists (rodata2_sec->children.head,
+ array_names[i][0])))
+ && (sym = bfd_link_hash_lookup (link_info.hash, array_names[i][1],
+ FALSE, FALSE, TRUE))
+ && sym->type == bfd_link_hash_defined
+ && sym->u.def.value % 2)
+ {
+ einfo ("%P: warning: \"%s\" symbol (%pU) is not word aligned\n",
+ array_names[i][1], NULL);
+ }
+ }
+}
+
+static void
+gld${EMULATION_NAME}_finish (void)
+{
+ finish_default ();
+ check_array_section_alignment ();
+}
+
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
{
${LDEMUL_BEFORE_PARSE-gld${EMULATION_NAME}_before_parse},
@@ -832,7 +911,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation =
${LDEMUL_GET_SCRIPT-gld${EMULATION_NAME}_get_script},
"${EMULATION_NAME}",
"${OUTPUT_FORMAT}",
- ${LDEMUL_FINISH-finish_default},
+ gld${EMULATION_NAME}_finish,
${LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS-NULL},
${LDEMUL_OPEN_DYNAMIC_ARCHIVE-NULL},
${LDEMUL_PLACE_ORPHAN-gld${EMULATION_NAME}_place_orphan},
diff --git a/ld/scripttempl/elf32msp430.sc b/ld/scripttempl/elf32msp430.sc
index 6f716c75e6..c73790ae8b 100644
--- a/ld/scripttempl/elf32msp430.sc
+++ b/ld/scripttempl/elf32msp430.sc
@@ -203,15 +203,18 @@ SECTIONS
KEEP (*(.gcc_except_table)) *(.gcc_except_table.*)
+ . = ALIGN(2);
PROVIDE (__preinit_array_start = .);
KEEP (*(.preinit_array))
PROVIDE (__preinit_array_end = .);
+ . = ALIGN(2);
PROVIDE (__init_array_start = .);
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
PROVIDE (__init_array_end = .);
+ . = ALIGN(2);
PROVIDE (__fini_array_start = .);
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
diff --git a/ld/testsuite/ld-msp430-elf/finiarray-warn.ld b/ld/testsuite/ld-msp430-elf/finiarray-warn.ld
new file mode 100644
index 0000000000..c9342934b4
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/finiarray-warn.ld
@@ -0,0 +1,46 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ . = ALIGN(2);
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(SORT(.preinit_array.*)))
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+ . = ALIGN(2);
+ . += 1;
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+}
diff --git a/ld/testsuite/ld-msp430-elf/finiarray-warn.r b/ld/testsuite/ld-msp430-elf/finiarray-warn.r
new file mode 100644
index 0000000000..ba3fa8348b
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/finiarray-warn.r
@@ -0,0 +1 @@
+.*warning: "__fini_array_start" symbol \(finiarray-warn.ld\) is not word aligned
diff --git a/ld/testsuite/ld-msp430-elf/initarray-nowarn.ld b/ld/testsuite/ld-msp430-elf/initarray-nowarn.ld
new file mode 100644
index 0000000000..866c324138
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/initarray-nowarn.ld
@@ -0,0 +1,45 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ . = ALIGN(2);
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(SORT(.preinit_array.*)))
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+}
diff --git a/ld/testsuite/ld-msp430-elf/initarray-nowarn.r b/ld/testsuite/ld-msp430-elf/initarray-nowarn.r
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/ld/testsuite/ld-msp430-elf/initarray-warn.ld b/ld/testsuite/ld-msp430-elf/initarray-warn.ld
new file mode 100644
index 0000000000..fc00d9025e
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/initarray-warn.ld
@@ -0,0 +1,46 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ . = ALIGN(2);
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(SORT(.preinit_array.*)))
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+ . = ALIGN(2);
+ . += 1;
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+}
diff --git a/ld/testsuite/ld-msp430-elf/initarray-warn.r b/ld/testsuite/ld-msp430-elf/initarray-warn.r
new file mode 100644
index 0000000000..35abd7bfe9
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/initarray-warn.r
@@ -0,0 +1 @@
+.*warning: "__init_array_start" symbol \(initarray-warn.ld\) is not word aligned
diff --git a/ld/testsuite/ld-msp430-elf/initarray.s b/ld/testsuite/ld-msp430-elf/initarray.s
new file mode 100644
index 0000000000..ecd012676c
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/initarray.s
@@ -0,0 +1,22 @@
+.text
+ .section .preinit_array,"aw"
+ .short 42
+
+ .section .init_array,"aw"
+ .short 43
+
+ .section .fini_array,"aw"
+ .short 44
+
+.text
+ .global main
+ .type main, @function
+main:
+ MOV #__preinit_array_start, R8
+ MOV #__init_array_start, R9
+ MOV #__fini_array_start, R10
+ CALL @R8
+ CALL @R9
+ CALL @R10
+ RET
+
diff --git a/ld/testsuite/ld-msp430-elf/msp430-elf.exp b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
index 777b358a74..0b68f8f72e 100644
--- a/ld/testsuite/ld-msp430-elf/msp430-elf.exp
+++ b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
@@ -163,6 +163,19 @@ set msp430warntests {
{{ld warn-no-lower-data.r}} "warn-no-lower-data"}
}
+set msp430arraytests {
+ { "Warn when __preinit_array_start is not word aligned" "-T preinitarray-warn.ld" "" ""
+ {initarray.s} {{ld preinitarray-warn.r}} "preinitarray-warn"}
+ { "Warn when __init_array_start is not word aligned" "-T initarray-warn.ld" "" ""
+ {initarray.s} {{ld initarray-warn.r}} "initarray-warn"}
+ { "Warn when __fini_array_start is not word aligned" "-T finiarray-warn.ld" "" ""
+ {initarray.s} {{ld finiarray-warn.r}} "finiarray-warn"}
+ { "Don't warn when __{preinit,init,fini}_array_start are word aligned" "-T initarray-nowarn.ld" "" ""
+ {initarray.s} {{ld initarray-nowarn.r}} "initarray-nowarn"}
+}
+
+run_ld_link_tests $msp430arraytests
+
# Don't run further tests when msp430 ISA is selected
if {[string match "*-mcpu=msp430 *" [board_info [target_info name] multilib_flags]]
|| [string match "*-mcpu=msp430" [board_info [target_info name] multilib_flags]]} {
diff --git a/ld/testsuite/ld-msp430-elf/preinitarray-warn.ld b/ld/testsuite/ld-msp430-elf/preinitarray-warn.ld
new file mode 100644
index 0000000000..acbe7f5e65
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/preinitarray-warn.ld
@@ -0,0 +1,46 @@
+/* Script for ld testsuite */
+OUTPUT_ARCH(msp430)
+ENTRY(_start)
+
+SECTIONS
+{
+ .text :
+ {
+ PROVIDE (_start = .);
+ . = ALIGN(2);
+ *(.text .stub .text.* .gnu.linkonce.t.* .text:*)
+ }
+
+ .rodata :
+ {
+ *(.rodata.* .rodata)
+ . = ALIGN(2);
+ . += 1;
+ PROVIDE (__preinit_array_start = .);
+ KEEP (*(SORT(.preinit_array.*)))
+ KEEP (*(.preinit_array))
+ PROVIDE (__preinit_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__init_array_start = .);
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ PROVIDE (__init_array_end = .);
+ . = ALIGN(2);
+ PROVIDE (__fini_array_start = .);
+ KEEP (*(SORT(.fini_array.*)))
+ KEEP (*(.fini_array))
+ PROVIDE (__fini_array_end = .);
+ }
+
+ .data :
+ {
+ . = ALIGN(2);
+ *(.data.* .data)
+ }
+
+ .bss :
+ {
+ . = ALIGN(2);
+ *(.bss.* .bss)
+ }
+}
diff --git a/ld/testsuite/ld-msp430-elf/preinitarray-warn.r b/ld/testsuite/ld-msp430-elf/preinitarray-warn.r
new file mode 100644
index 0000000000..ab12e42d46
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/preinitarray-warn.r
@@ -0,0 +1 @@
+.*warning: "__preinit_array_start" symbol \(preinitarray-warn.ld\) is not word aligned
--
2.17.1
^ permalink raw reply [flat|nested] 4+ messages in thread