This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH 2/2] AVR/ld: Propagate link-relax elf header flag correctly.
- From: Andrew Burgess <andrew dot burgess at embecosm dot com>
- To: binutils at sourceware dot org
- Cc: Andrew Burgess <andrew dot burgess at embecosm dot com>
- Date: Fri, 5 Dec 2014 22:20:43 +0000
- Subject: [PATCH 2/2] AVR/ld: Propagate link-relax elf header flag correctly.
- Authentication-results: sourceware.org; auth=none
- References: <cover dot 1417817326 dot git dot andrew dot burgess at embecosm dot com>
- References: <cover dot 1417817326 dot git dot andrew dot burgess at embecosm dot com>
The AVR target has an elf header flag to indicate if an object was
assembler ready for linker relaxation. If a partial link is performed
then it is important that the link-relax flag in the output object is
set correctly, otherwise, during the final link, we might try to perform
linker relaxation on sections that were not suitably assembled.
As the link-relax elf header covers the entire object file we must be
conservative when setting the flag in the output object, so, for a
partial link, any input object that does not have the link-relax flag
set will cause the output object to also not have the link-relax flag
set.
This conservative approach could be softened in future, we only need to
clear the link relax flag if an input file is not marked link-relax
ready, and the input file contains a relaxable section. I've left this
optimisation for now thought.
For the final link I've overloaded the use of the link-relax elf header
flag, in a final executable, the flag now indicates if the executable
was built with linker relaxation on or not.
ld/ChangeLog:
* emultempl/avrelf.em: Add include of elf/avr.h.
(avr_finish): New function.
(LDEMUL_FINISH): Added.
ld/testsuite/ChangeLog:
* ld-avr/relax-elf-flags-01.d: New file.
* ld-avr/relax-elf-flags-02.d: New file.
* ld-avr/relax-elf-flags-03.d: New file.
* ld-avr/relax-elf-flags-04.d: New file.
* ld-avr/relax-elf-flags-05.d: New file.
* ld-avr/relax-elf-flags-06.d: New file.
* ld-avr/relax-elf-flags-07.d: New file.
* ld-avr/relax-elf-flags-08.d: New file.
* ld-avr/relax-elf-flags-a.s: New file.
* ld-avr/relax-elf-flags-b.s: New file.
---
ld/ChangeLog | 6 ++++++
ld/emultempl/avrelf.em | 37 ++++++++++++++++++++++++++++++++
ld/testsuite/ChangeLog | 13 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-01.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-02.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-03.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-04.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-05.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-06.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-07.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-08.d | 12 +++++++++++
ld/testsuite/ld-avr/relax-elf-flags-a.s | 4 ++++
ld/testsuite/ld-avr/relax-elf-flags-b.s | 4 ++++
13 files changed, 160 insertions(+)
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-01.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-02.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-03.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-04.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-05.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-06.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-07.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-08.d
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-a.s
create mode 100644 ld/testsuite/ld-avr/relax-elf-flags-b.s
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 9ec721f..b34b227 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,9 @@
+2014-12-05 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * emultempl/avrelf.em: Add include of elf/avr.h.
+ (avr_finish): New function.
+ (LDEMUL_FINISH): Added.
+
2014-11-25 H.J. Lu <hongjiu.lu@intel.com>
* emulparams/elf_i386.sh (TINY_READONLY_SECTION): New.
diff --git a/ld/emultempl/avrelf.em b/ld/emultempl/avrelf.em
index 170dc3e..f4e2654 100644
--- a/ld/emultempl/avrelf.em
+++ b/ld/emultempl/avrelf.em
@@ -28,6 +28,7 @@ fragment <<EOF
#include "elf32-avr.h"
#include "ldctor.h"
+#include "elf/avr.h"
/* The fake file and it's corresponding section meant to hold
the linker stubs if needed. */
@@ -175,6 +176,41 @@ avr_elf_before_parse (void)
gld${EMULATION_NAME}_before_parse ();
}
+static void
+avr_finish (void)
+{
+ bfd *abfd;
+ bfd_boolean avr_link_relax;
+
+ if (link_info.relocatable)
+ {
+ avr_link_relax = TRUE;
+ for (abfd = link_info.input_bfds; abfd != NULL; abfd = abfd->link.next)
+ {
+ /* Don't let the linker stubs prevent the final object being
+ marked as link-relax ready. */
+ if ((elf_elfheader (abfd)->e_flags
+ & EF_AVR_LINKRELAX_PREPARED) == 0
+ && abfd != stub_file->the_bfd)
+ {
+ avr_link_relax = FALSE;
+ break;
+ }
+ }
+ }
+ else
+ {
+ avr_link_relax = RELAXATION_ENABLED;
+ }
+
+ abfd = link_info.output_bfd;
+ if (avr_link_relax)
+ elf_elfheader (abfd)->e_flags |= EF_AVR_LINKRELAX_PREPARED;
+ else
+ elf_elfheader (abfd)->e_flags &= ~EF_AVR_LINKRELAX_PREPARED;
+
+ finish_default ();
+}
EOF
@@ -274,3 +310,4 @@ LDEMUL_BEFORE_PARSE=avr_elf_before_parse
LDEMUL_BEFORE_ALLOCATION=avr_elf_${EMULATION_NAME}_before_allocation
LDEMUL_AFTER_ALLOCATION=avr_elf_after_allocation
LDEMUL_CREATE_OUTPUT_SECTION_STATEMENTS=avr_elf_create_output_section_statements
+LDEMUL_FINISH=avr_finish
diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog
index 8ebe2fb..5c53ed2 100644
--- a/ld/testsuite/ChangeLog
+++ b/ld/testsuite/ChangeLog
@@ -1,3 +1,16 @@
+2014-12-05 Andrew Burgess <andrew.burgess@embecosm.com>
+
+ * testsuite/ld-avr/relax-elf-flags-01.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-02.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-03.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-04.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-05.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-06.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-07.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-08.d: New file.
+ * testsuite/ld-avr/relax-elf-flags-a.s: New file.
+ * testsuite/ld-avr/relax-elf-flags-b.s: New file.
+
2014-12-04 Alan Modra <amodra@gmail.com>
* ld-powerpc/vxworks-relax.rd: Update for reloc sorting.
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-01.d b/ld/testsuite/ld-avr/relax-elf-flags-01.d
new file mode 100644
index 0000000..6cf4920
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-01.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is set on partial link
+#as: -mmcu=avrxmega2
+#ld: -r -mavrxmega2
+#source: relax-elf-flags-a.s -mlink-relax
+#source: relax-elf-flags-b.s -mlink-relax
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0xe6, avr:102, link-relax
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-02.d b/ld/testsuite/ld-avr/relax-elf-flags-02.d
new file mode 100644
index 0000000..6a008bd
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-02.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is clear on partial link (first file)
+#as: -mmcu=avrxmega2
+#ld: -r -mavrxmega2
+#source: relax-elf-flags-a.s
+#source: relax-elf-flags-b.s -mlink-relax
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0x66, avr:102
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-03.d b/ld/testsuite/ld-avr/relax-elf-flags-03.d
new file mode 100644
index 0000000..3d2a70d
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-03.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is clear on partial link, second file.
+#as: -mmcu=avrxmega2
+#ld: -r -mavrxmega2
+#source: relax-elf-flags-a.s -mlink-relax
+#source: relax-elf-flags-b.s
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0x66, avr:102
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-04.d b/ld/testsuite/ld-avr/relax-elf-flags-04.d
new file mode 100644
index 0000000..e2a9bb6
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-04.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is clear on partial link (both files)
+#as: -mmcu=avrxmega2
+#ld: -r -mavrxmega2
+#source: relax-elf-flags-a.s
+#source: relax-elf-flags-b.s
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0x66, avr:102
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-05.d b/ld/testsuite/ld-avr/relax-elf-flags-05.d
new file mode 100644
index 0000000..8c41e8d
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-05.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is set final link (no inputs relaxable)
+#as: -mmcu=avrxmega2
+#ld: -relax -mavrxmega2
+#source: relax-elf-flags-a.s
+#source: relax-elf-flags-b.s
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0xe6, avr:102, link-relax
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-06.d b/ld/testsuite/ld-avr/relax-elf-flags-06.d
new file mode 100644
index 0000000..5d8e3c1
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-06.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is set final link (first input relaxable)
+#as: -mmcu=avrxmega2
+#ld: -relax -mavrxmega2
+#source: relax-elf-flags-a.s -mlink-relax
+#source: relax-elf-flags-b.s
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0xe6, avr:102, link-relax
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-07.d b/ld/testsuite/ld-avr/relax-elf-flags-07.d
new file mode 100644
index 0000000..25b70e7
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-07.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is set final link (both inputs relaxable)
+#as: -mmcu=avrxmega2
+#ld: -relax -mavrxmega2
+#source: relax-elf-flags-a.s -mlink-relax
+#source: relax-elf-flags-b.s -mlink-relax
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0xe6, avr:102, link-relax
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-08.d b/ld/testsuite/ld-avr/relax-elf-flags-08.d
new file mode 100644
index 0000000..0b2152a
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-08.d
@@ -0,0 +1,12 @@
+#name: AVR, check link-relax flag is clear final link (both inputs relaxable)
+#as: -mmcu=avrxmega2
+#ld: -mavrxmega2
+#source: relax-elf-flags-a.s -mlink-relax
+#source: relax-elf-flags-b.s -mlink-relax
+#readelf: -h
+#target: avr-*-*
+
+ELF Header:
+#...
+ Flags: 0x66, avr:102
+#...
\ No newline at end of file
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-a.s b/ld/testsuite/ld-avr/relax-elf-flags-a.s
new file mode 100644
index 0000000..af543e1
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-a.s
@@ -0,0 +1,4 @@
+ .text
+ .global _start
+_start:
+ nop
diff --git a/ld/testsuite/ld-avr/relax-elf-flags-b.s b/ld/testsuite/ld-avr/relax-elf-flags-b.s
new file mode 100644
index 0000000..59ca0cc
--- /dev/null
+++ b/ld/testsuite/ld-avr/relax-elf-flags-b.s
@@ -0,0 +1,4 @@
+ .text
+ .global func
+func:
+ nop
--
1.9.3