diff options
author | Jozef Lawrynowicz <jozef.l@mittosystems.com> | 2020-09-08 16:13:48 +0100 |
---|---|---|
committer | Jozef Lawrynowicz <jozef.l@mittosystems.com> | 2020-09-08 16:18:38 +0100 |
commit | 7d81bc937cd3949fc3bed8194646d3a4563f94b2 (patch) | |
tree | 6d1300169968fa3dae4c85e0c633f27ed61cb5ca /ld | |
parent | f1363b0fb4eb8bbe9ef08f1e78ff6ffa71e07b8b (diff) | |
download | gdb-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/ChangeLog | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-msp430-elf/msp430-elf.exp | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-msp430-elf/uleb128.s | 34 | ||||
-rw-r--r-- | ld/testsuite/ld-msp430-elf/uleb128_430.d | 10 | ||||
-rw-r--r-- | ld/testsuite/ld-msp430-elf/uleb128_430x.d | 10 |
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 |