MSP430: Support relocations for subtract expressions in .uleb128 directives
authorJozef Lawrynowicz <jozef.l@mittosystems.com>
Tue, 8 Sep 2020 15:13:48 +0000 (16:13 +0100)
committerJozef Lawrynowicz <jozef.l@mittosystems.com>
Tue, 8 Sep 2020 15:18:38 +0000 (16:18 +0100)
commit7d81bc937cd3949fc3bed8194646d3a4563f94b2
tree6d1300169968fa3dae4c85e0c633f27ed61cb5ca
parentf1363b0fb4eb8bbe9ef08f1e78ff6ffa71e07b8b
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.
17 files changed:
bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-msp430.c
bfd/libbfd.c
bfd/libbfd.h
bfd/reloc.c
binutils/ChangeLog
binutils/readelf.c
gas/ChangeLog
gas/config/tc-msp430.c
include/ChangeLog
include/elf/msp430.h
ld/ChangeLog
ld/testsuite/ld-msp430-elf/msp430-elf.exp
ld/testsuite/ld-msp430-elf/uleb128.s [new file with mode: 0644]
ld/testsuite/ld-msp430-elf/uleb128_430.d [new file with mode: 0644]
ld/testsuite/ld-msp430-elf/uleb128_430x.d [new file with mode: 0644]