aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
authorJozef Lawrynowicz <jozef.l@mittosystems.com>2020-09-08 16:13:48 +0100
committerJozef Lawrynowicz <jozef.l@mittosystems.com>2020-09-08 16:18:38 +0100
commit7d81bc937cd3949fc3bed8194646d3a4563f94b2 (patch)
tree6d1300169968fa3dae4c85e0c633f27ed61cb5ca /ld
parentf1363b0fb4eb8bbe9ef08f1e78ff6ffa71e07b8b (diff)
downloadgdb-7d81bc937cd3949fc3bed8194646d3a4563f94b2.zip
gdb-7d81bc937cd3949fc3bed8194646d3a4563f94b2.tar.gz
gdb-7d81bc937cd3949fc3bed8194646d3a4563f94b2.tar.bz2
MSP430: Support relocations for subtract expressions in .uleb128 directives
Link-time relaxations of branches are common for MSP430, given that GCC can generate pessimal branch instructions, and the -mcode-region=either/-mdata-region=either options to shuffle sections can further change the type of branch instruction required. These relaxations can result in invalid code when .uleb128 directives, used in the .gcc_except_table section, are used to calculate the distance between two labels. A value for the .uleb128 directive is calculated at assembly-time, and can't be updated at link-time, even if relaxation causes the distance between the labels to change. This patch adds relocations for subtract expressions in .uleb128 directives, to allow the linker to re-calculate the value of these expressions after relaxation has been performed. bfd/ChangeLog: * bfd-in2.h (bfd_reloc_code_real): Add BFD_RELOC_MSP430_{SET,SUB}_ULEB128. * elf32-msp430.c (msp430_elf_ignore_reloc): New. (elf_msp430_howto_table): Add R_MSP430{,X}_GNU_{SET,SUB}_ULEB128. (msp430_reloc_map): Add R_MSP430_GNU_{SET,SUB}_ULEB128. (msp430x_reloc_map): Add R_MSP430X_GNU_{SET,SUB}_ULEB128. (write_uleb128): New. (msp430_final_link_relocate): Handle R_MSP430{,X}_GNU_{SET,SUB}_ULEB128. * libbfd.c (_bfd_write_unsigned_leb128): New. * libbfd.h (_bfd_write_unsigned_leb128): New prototype. Add BFD_RELOC_MSP430_{SET,SUB}_ULEB128. * reloc.c: Document BFD_RELOC_MSP430_{SET,SUB}_ULEB128. binutils/ChangeLog: * readelf.c (target_specific_reloc_handling): Handle R_MSP430{,X}_GNU_{SET,SUB}_ULEB128. gas/ChangeLog: * config/tc-msp430.c (msp430_insert_uleb128_fixes): New. (msp430_md_end): Call msp430_insert_uleb128_fixes. include/ChangeLog: * elf/msp430.h (elf_msp430_reloc_type): Add R_MSP430_GNU_{SET,SUB}_ULEB128. (elf_msp430x_reloc_type): Add R_MSP430X_GNU_{SET,SUB}_ULEB128. ld/ChangeLog: * testsuite/ld-msp430-elf/msp430-elf.exp: Run new tests. * testsuite/ld-msp430-elf/uleb128.s: New test. * testsuite/ld-msp430-elf/uleb128_430.d: New test. * testsuite/ld-msp430-elf/uleb128_430x.d: New test.
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/testsuite/ld-msp430-elf/msp430-elf.exp3
-rw-r--r--ld/testsuite/ld-msp430-elf/uleb128.s34
-rw-r--r--ld/testsuite/ld-msp430-elf/uleb128_430.d10
-rw-r--r--ld/testsuite/ld-msp430-elf/uleb128_430x.d10
5 files changed, 64 insertions, 0 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4b42f05..1f80479 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
+
+ * testsuite/ld-msp430-elf/msp430-elf.exp: Run new tests.
+ * testsuite/ld-msp430-elf/uleb128.s: New test.
+ * testsuite/ld-msp430-elf/uleb128_430.d: New test.
+ * testsuite/ld-msp430-elf/uleb128_430x.d: New test.
+
2020-09-08 Alan Modra <amodra@gmail.com>
* testsuite/ld-elf/pr26580-a.s,
diff --git a/ld/testsuite/ld-msp430-elf/msp430-elf.exp b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
index a2fa4db..875b413 100644
--- a/ld/testsuite/ld-msp430-elf/msp430-elf.exp
+++ b/ld/testsuite/ld-msp430-elf/msp430-elf.exp
@@ -176,6 +176,9 @@ set msp430arraytests {
run_ld_link_tests $msp430arraytests
+run_dump_test uleb128_430
+run_dump_test uleb128_430x
+
# 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/uleb128.s b/ld/testsuite/ld-msp430-elf/uleb128.s
new file mode 100644
index 0000000..598ee0c
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/uleb128.s
@@ -0,0 +1,34 @@
+.data
+ .global bar
+ .balign 2
+bar:
+ .short 42
+ .short 43
+
+ .global foo
+foo:
+.skip 0xff
+
+ .global foo2
+ .balign 2
+foo2:
+ .short 4
+
+.text
+
+ .balign 2
+ .global byte
+byte:
+ .word foo-bar
+ .word foo2-bar
+
+ .global uleb
+ .balign 2
+uleb:
+ .uleb128 foo-bar ; this value can be stored in one byte
+ .uleb128 foo2-bar ; this value requires 2 bytes
+
+ .balign 2
+ .global _start
+ _start:
+ nop
diff --git a/ld/testsuite/ld-msp430-elf/uleb128_430.d b/ld/testsuite/ld-msp430-elf/uleb128_430.d
new file mode 100644
index 0000000..5104552
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/uleb128_430.d
@@ -0,0 +1,10 @@
+#source: uleb128.s
+#as: -mcpu=msp430
+#ld:
+#objdump: -sj.text
+
+.*:[ ]+file format .*
+
+Contents of section .text:
+ [0-9a-f]+ 04000401 04840200.*
+#pass
diff --git a/ld/testsuite/ld-msp430-elf/uleb128_430x.d b/ld/testsuite/ld-msp430-elf/uleb128_430x.d
new file mode 100644
index 0000000..e808a53
--- /dev/null
+++ b/ld/testsuite/ld-msp430-elf/uleb128_430x.d
@@ -0,0 +1,10 @@
+#source: uleb128.s
+#as: -mcpu=msp430x
+#ld:
+#objdump: -sj.text
+
+.*:[ ]+file format .*
+
+Contents of section .text:
+ [0-9a-f]+ 04000401 04840200.*
+#pass