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.
This commit is contained in:
parent
f1363b0fb4
commit
7d81bc937c
17 changed files with 362 additions and 10 deletions
|
@ -1,3 +1,19 @@
|
|||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2020-09-08 Alex Coplan <alex.coplan@arm.com>
|
||||
|
||||
* archures.c (bfd_mach_aarch64_8R): New.
|
||||
|
|
|
@ -5114,6 +5114,8 @@ then it may be truncated to 8 bits. */
|
|||
BFD_RELOC_MSP430_ABS_HI16,
|
||||
BFD_RELOC_MSP430_PREL31,
|
||||
BFD_RELOC_MSP430_SYM_DIFF,
|
||||
BFD_RELOC_MSP430_SET_ULEB128,
|
||||
BFD_RELOC_MSP430_SUB_ULEB128,
|
||||
|
||||
/* Relocations used by the Altera Nios II core. */
|
||||
BFD_RELOC_NIOS2_S16,
|
||||
|
|
|
@ -56,6 +56,20 @@ rl78_sym_diff_handler (bfd * abfd,
|
|||
return bfd_reloc_continue;
|
||||
}
|
||||
|
||||
/* Special handler for relocations which don't have to be relocated.
|
||||
This function just simply returns bfd_reloc_ok. */
|
||||
static bfd_reloc_status_type
|
||||
msp430_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED, arelent *reloc_entry,
|
||||
asymbol *symbol ATTRIBUTE_UNUSED,
|
||||
void *data ATTRIBUTE_UNUSED, asection *input_section,
|
||||
bfd *output_bfd, char **error_message ATTRIBUTE_UNUSED)
|
||||
{
|
||||
if (output_bfd != NULL)
|
||||
reloc_entry->address += input_section->output_offset;
|
||||
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
|
||||
static reloc_howto_type elf_msp430_howto_table[] =
|
||||
{
|
||||
HOWTO (R_MSP430_NONE, /* type */
|
||||
|
@ -220,7 +234,40 @@ static reloc_howto_type elf_msp430_howto_table[] =
|
|||
FALSE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE) /* pcrel_offset */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* The length of unsigned-leb128 is variable, just assume the
|
||||
size is one byte here. */
|
||||
HOWTO (R_MSP430_GNU_SET_ULEB128, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
msp430_elf_ignore_reloc, /* special handler. */
|
||||
"R_MSP430_GNU_SET_ULEB128", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* The length of unsigned-leb128 is variable, just assume the
|
||||
size is one byte here. */
|
||||
HOWTO (R_MSP430_GNU_SUB_ULEB128, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
msp430_elf_ignore_reloc, /* special handler. */
|
||||
"R_MSP430_GNU_SUB_ULEB128", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
};
|
||||
|
||||
static reloc_howto_type elf_msp430x_howto_table[] =
|
||||
|
@ -523,7 +570,40 @@ static reloc_howto_type elf_msp430x_howto_table[] =
|
|||
FALSE, /* partial_inplace */
|
||||
0xffffffff, /* src_mask */
|
||||
0xffffffff, /* dst_mask */
|
||||
FALSE) /* pcrel_offset */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* The length of unsigned-leb128 is variable, just assume the
|
||||
size is one byte here. */
|
||||
HOWTO (R_MSP430X_GNU_SET_ULEB128, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
msp430_elf_ignore_reloc, /* special handler. */
|
||||
"R_MSP430X_GNU_SET_ULEB128", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
/* The length of unsigned-leb128 is variable, just assume the
|
||||
size is one byte here. */
|
||||
HOWTO (R_MSP430X_GNU_SUB_ULEB128, /* type */
|
||||
0, /* rightshift */
|
||||
0, /* size */
|
||||
0, /* bitsize */
|
||||
FALSE, /* pc_relative */
|
||||
0, /* bitpos */
|
||||
complain_overflow_dont, /* complain_on_overflow */
|
||||
msp430_elf_ignore_reloc, /* special handler. */
|
||||
"R_MSP430X_GNU_SUB_ULEB128", /* name */
|
||||
FALSE, /* partial_inplace */
|
||||
0, /* src_mask */
|
||||
0, /* dst_mask */
|
||||
FALSE), /* pcrel_offset */
|
||||
|
||||
};
|
||||
|
||||
/* Map BFD reloc types to MSP430 ELF reloc types. */
|
||||
|
@ -547,7 +627,9 @@ static const struct msp430_reloc_map msp430_reloc_map[] =
|
|||
{BFD_RELOC_MSP430_2X_PCREL, R_MSP430_2X_PCREL},
|
||||
{BFD_RELOC_MSP430_RL_PCREL, R_MSP430_RL_PCREL},
|
||||
{BFD_RELOC_8, R_MSP430_8},
|
||||
{BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF}
|
||||
{BFD_RELOC_MSP430_SYM_DIFF, R_MSP430_SYM_DIFF},
|
||||
{BFD_RELOC_MSP430_SET_ULEB128, R_MSP430_GNU_SET_ULEB128 },
|
||||
{BFD_RELOC_MSP430_SUB_ULEB128, R_MSP430_GNU_SUB_ULEB128 }
|
||||
};
|
||||
|
||||
static const struct msp430_reloc_map msp430x_reloc_map[] =
|
||||
|
@ -573,7 +655,9 @@ static const struct msp430_reloc_map msp430x_reloc_map[] =
|
|||
{BFD_RELOC_MSP430_10_PCREL, R_MSP430X_10_PCREL},
|
||||
{BFD_RELOC_MSP430_2X_PCREL, R_MSP430X_2X_PCREL},
|
||||
{BFD_RELOC_MSP430_RL_PCREL, R_MSP430X_PCR16},
|
||||
{BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF}
|
||||
{BFD_RELOC_MSP430_SYM_DIFF, R_MSP430X_SYM_DIFF},
|
||||
{BFD_RELOC_MSP430_SET_ULEB128, R_MSP430X_GNU_SET_ULEB128 },
|
||||
{BFD_RELOC_MSP430_SUB_ULEB128, R_MSP430X_GNU_SUB_ULEB128 }
|
||||
};
|
||||
|
||||
static inline bfd_boolean
|
||||
|
@ -755,6 +839,9 @@ msp430_final_link_relocate (reloc_howto_type * howto,
|
|||
if (uses_msp430x_relocs (input_bfd))
|
||||
switch (howto->type)
|
||||
{
|
||||
case R_MSP430X_GNU_SET_ULEB128:
|
||||
relocation += (!is_rel_reloc ? rel->r_addend : 0);
|
||||
/* Fall through. */
|
||||
case R_MSP430_ABS32:
|
||||
/* If we are computing a 32-bit value for the location lists
|
||||
and the result is 0 then we add one to the value. A zero
|
||||
|
@ -780,6 +867,9 @@ msp430_final_link_relocate (reloc_howto_type * howto,
|
|||
else
|
||||
switch (howto->type)
|
||||
{
|
||||
case R_MSP430_GNU_SET_ULEB128:
|
||||
relocation += (!is_rel_reloc ? rel->r_addend : 0);
|
||||
/* Fall through. */
|
||||
case R_MSP430_32:
|
||||
case R_MSP430_16:
|
||||
case R_MSP430_16_BYTE:
|
||||
|
@ -794,16 +884,63 @@ msp430_final_link_relocate (reloc_howto_type * howto,
|
|||
sym_diff_section = NULL;
|
||||
}
|
||||
|
||||
if (uses_msp430x_relocs (input_bfd))
|
||||
if ((uses_msp430x_relocs (input_bfd)
|
||||
&& howto->type == R_MSP430X_GNU_SET_ULEB128)
|
||||
|| (!uses_msp430x_relocs (input_bfd)
|
||||
&& howto->type == R_MSP430_GNU_SET_ULEB128))
|
||||
{
|
||||
unsigned int len, new_len = 0;
|
||||
bfd_byte *endp, *p;
|
||||
unsigned int val = relocation;
|
||||
|
||||
_bfd_read_unsigned_leb128 (input_bfd, contents + rel->r_offset, &len);
|
||||
|
||||
/* Clean the contents value to zero. Do not reduce the length. */
|
||||
p = contents + rel->r_offset;
|
||||
endp = (p + len) - 1;
|
||||
memset (p, 0x80, len - 1);
|
||||
*(endp) = 0;
|
||||
|
||||
/* Get the length of the new uleb128 value. */
|
||||
do
|
||||
{
|
||||
new_len++;
|
||||
val >>= 7;
|
||||
} while (val);
|
||||
|
||||
if (new_len > len)
|
||||
{
|
||||
_bfd_error_handler
|
||||
(_("error: final size of uleb128 value at offset 0x%lx in %pA "
|
||||
"from %pB exceeds available space"),
|
||||
(long) rel->r_offset, input_section, input_bfd);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the number of bytes required to store the new value has
|
||||
decreased, "right align" the new value within the available space,
|
||||
so the MSB side is padded with uleb128 zeros (0x80). */
|
||||
p = _bfd_write_unsigned_leb128 (p + (len - new_len), endp,
|
||||
relocation);
|
||||
/* We checked there is enough space for the new value above, so this
|
||||
should never be NULL. */
|
||||
BFD_ASSERT (p);
|
||||
}
|
||||
|
||||
return bfd_reloc_ok;
|
||||
}
|
||||
else if (uses_msp430x_relocs (input_bfd))
|
||||
switch (howto->type)
|
||||
{
|
||||
case R_MSP430X_SYM_DIFF:
|
||||
case R_MSP430X_GNU_SUB_ULEB128:
|
||||
/* Cache the input section and value.
|
||||
The offset is unreliable, since relaxation may
|
||||
have reduced the following reloc's offset. */
|
||||
BFD_ASSERT (! is_rel_reloc);
|
||||
sym_diff_section = input_section;
|
||||
sym_diff_value = relocation;
|
||||
sym_diff_value = relocation + (howto->type == R_MSP430X_GNU_SUB_ULEB128
|
||||
? rel->r_addend : 0);
|
||||
return bfd_reloc_ok;
|
||||
|
||||
case R_MSP430_ABS16:
|
||||
|
@ -1254,11 +1391,13 @@ msp430_final_link_relocate (reloc_howto_type * howto,
|
|||
break;
|
||||
|
||||
case R_MSP430_SYM_DIFF:
|
||||
case R_MSP430_GNU_SUB_ULEB128:
|
||||
/* Cache the input section and value.
|
||||
The offset is unreliable, since relaxation may
|
||||
have reduced the following reloc's offset. */
|
||||
sym_diff_section = input_section;
|
||||
sym_diff_value = relocation;
|
||||
sym_diff_value = relocation + (howto->type == R_MSP430_GNU_SUB_ULEB128
|
||||
? rel->r_addend : 0);
|
||||
return bfd_reloc_ok;
|
||||
|
||||
default:
|
||||
|
|
24
bfd/libbfd.c
24
bfd/libbfd.c
|
@ -1151,6 +1151,30 @@ _bfd_read_signed_leb128 (bfd *abfd ATTRIBUTE_UNUSED,
|
|||
return result;
|
||||
}
|
||||
|
||||
/* Write VAL in uleb128 format to P.
|
||||
END indicates the last byte of allocated space for the uleb128 value to fit
|
||||
in.
|
||||
Return a pointer to the byte following the last byte that was written, or
|
||||
NULL if the uleb128 value does not fit in the allocated space between P and
|
||||
END. */
|
||||
bfd_byte *
|
||||
_bfd_write_unsigned_leb128 (bfd_byte *p, bfd_byte *end, bfd_vma val)
|
||||
{
|
||||
bfd_byte c;
|
||||
do
|
||||
{
|
||||
if (p > end)
|
||||
return NULL;
|
||||
c = val & 0x7f;
|
||||
val >>= 7;
|
||||
if (val)
|
||||
c |= 0x80;
|
||||
*(p++) = c;
|
||||
}
|
||||
while (val);
|
||||
return p;
|
||||
}
|
||||
|
||||
bfd_boolean
|
||||
_bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
|
||||
asection *isec ATTRIBUTE_UNUSED,
|
||||
|
|
|
@ -901,6 +901,8 @@ extern bfd_signed_vma _bfd_read_signed_leb128
|
|||
extern bfd_vma _bfd_safe_read_leb128
|
||||
(bfd *, bfd_byte *, unsigned int *, bfd_boolean, const bfd_byte * const)
|
||||
ATTRIBUTE_HIDDEN;
|
||||
extern bfd_byte * _bfd_write_unsigned_leb128
|
||||
(bfd_byte *p, bfd_byte *end, bfd_vma val) ATTRIBUTE_HIDDEN;
|
||||
|
||||
#if GCC_VERSION >= 7000
|
||||
#define _bfd_mul_overflow(a, b, res) __builtin_mul_overflow (a, b, res)
|
||||
|
@ -2802,6 +2804,8 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
|
|||
"BFD_RELOC_MSP430_ABS_HI16",
|
||||
"BFD_RELOC_MSP430_PREL31",
|
||||
"BFD_RELOC_MSP430_SYM_DIFF",
|
||||
"BFD_RELOC_MSP430_SET_ULEB128",
|
||||
"BFD_RELOC_MSP430_SUB_ULEB128",
|
||||
"BFD_RELOC_NIOS2_S16",
|
||||
"BFD_RELOC_NIOS2_U16",
|
||||
"BFD_RELOC_NIOS2_CALL26",
|
||||
|
|
|
@ -6367,6 +6367,11 @@ ENUMX
|
|||
BFD_RELOC_MSP430_PREL31
|
||||
ENUMX
|
||||
BFD_RELOC_MSP430_SYM_DIFF
|
||||
ENUMX
|
||||
BFD_RELOC_MSP430_SET_ULEB128
|
||||
ENUMX
|
||||
BFD_RELOC_MSP430_SUB_ULEB128
|
||||
|
||||
ENUMDOC
|
||||
msp430 specific relocation codes
|
||||
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
* readelf.c (target_specific_reloc_handling): Handle
|
||||
R_MSP430{,X}_GNU_{SET,SUB}_ULEB128.
|
||||
|
||||
2020-09-02 Alan Modra <amodra@gmail.com>
|
||||
|
||||
* objdump.c (disassemble_bytes): Use an unsigned type for "addend".
|
||||
|
|
|
@ -12586,10 +12586,12 @@ target_specific_reloc_handling (Filedata * filedata,
|
|||
switch (reloc_type)
|
||||
{
|
||||
case 10: /* R_MSP430_SYM_DIFF */
|
||||
case 12: /* R_MSP430_GNU_SUB_ULEB128 */
|
||||
if (uses_msp430x_relocs (filedata))
|
||||
break;
|
||||
/* Fall through. */
|
||||
case 21: /* R_MSP430X_SYM_DIFF */
|
||||
case 23: /* R_MSP430X_GNU_SUB_ULEB128 */
|
||||
/* PR 21139. */
|
||||
if (sym_index >= num_syms)
|
||||
error (_("MSP430 SYM_DIFF reloc contains invalid symbol index %lu\n"),
|
||||
|
@ -12604,12 +12606,14 @@ target_specific_reloc_handling (Filedata * filedata,
|
|||
|
||||
case 5: /* R_MSP430_16_BYTE */
|
||||
case 9: /* R_MSP430_8 */
|
||||
case 11: /* R_MSP430_GNU_SET_ULEB128 */
|
||||
if (uses_msp430x_relocs (filedata))
|
||||
break;
|
||||
goto handle_sym_diff;
|
||||
|
||||
case 2: /* R_MSP430_ABS16 */
|
||||
case 15: /* R_MSP430X_ABS16 */
|
||||
case 22: /* R_MSP430X_GNU_SET_ULEB128 */
|
||||
if (! uses_msp430x_relocs (filedata))
|
||||
break;
|
||||
goto handle_sym_diff;
|
||||
|
@ -12617,10 +12621,29 @@ target_specific_reloc_handling (Filedata * filedata,
|
|||
handle_sym_diff:
|
||||
if (saved_sym != NULL)
|
||||
{
|
||||
int reloc_size = reloc_type == 1 ? 4 : 2;
|
||||
bfd_vma value;
|
||||
unsigned int reloc_size;
|
||||
int leb_ret = 0;
|
||||
switch (reloc_type)
|
||||
{
|
||||
case 1: /* R_MSP430_32 or R_MSP430_ABS32 */
|
||||
reloc_size = 4;
|
||||
break;
|
||||
case 11: /* R_MSP430_GNU_SET_ULEB128 */
|
||||
case 22: /* R_MSP430X_GNU_SET_ULEB128 */
|
||||
read_leb128 (start + reloc->r_offset, end, FALSE,
|
||||
&reloc_size, &leb_ret);
|
||||
break;
|
||||
default:
|
||||
reloc_size = 2;
|
||||
break;
|
||||
}
|
||||
|
||||
if (sym_index >= num_syms)
|
||||
if (leb_ret != 0)
|
||||
error (_("MSP430 ULEB128 field at 0x%lx contains invalid "
|
||||
"ULEB128 value\n"),
|
||||
(long) reloc->r_offset);
|
||||
else if (sym_index >= num_syms)
|
||||
error (_("MSP430 reloc contains invalid symbol index %lu\n"),
|
||||
sym_index);
|
||||
else
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
* config/tc-msp430.c (msp430_insert_uleb128_fixes): New.
|
||||
(msp430_md_end): Call msp430_insert_uleb128_fixes.
|
||||
|
||||
2020-09-08 Alex Coplan <alex.coplan@arm.com>
|
||||
|
||||
* config/tc-aarch64.c (aarch64_cpus): Add Cortex-R82.
|
||||
|
|
|
@ -5048,8 +5048,56 @@ msp430_fix_adjustable (struct fix *fixp ATTRIBUTE_UNUSED)
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
/* Set the contents of the .MSP430.attributes and .GNU.attributes sections. */
|
||||
/* Scan uleb128 subtraction expressions and insert fixups for them.
|
||||
e.g., .uleb128 .L1 - .L0
|
||||
Because relaxation may change the value of the subtraction, we
|
||||
must resolve them at link-time. */
|
||||
|
||||
static void
|
||||
msp430_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
|
||||
asection *sec, void *xxx ATTRIBUTE_UNUSED)
|
||||
{
|
||||
segment_info_type *seginfo = seg_info (sec);
|
||||
struct frag *fragP;
|
||||
|
||||
subseg_set (sec, 0);
|
||||
|
||||
for (fragP = seginfo->frchainP->frch_root;
|
||||
fragP; fragP = fragP->fr_next)
|
||||
{
|
||||
expressionS *exp, *exp_dup;
|
||||
|
||||
if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL)
|
||||
continue;
|
||||
|
||||
exp = symbol_get_value_expression (fragP->fr_symbol);
|
||||
|
||||
if (exp->X_op != O_subtract)
|
||||
continue;
|
||||
|
||||
/* FIXME: Skip for .sleb128. */
|
||||
if (fragP->fr_subtype != 0)
|
||||
continue;
|
||||
|
||||
exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
|
||||
exp_dup->X_op = O_symbol;
|
||||
exp_dup->X_op_symbol = NULL;
|
||||
|
||||
/* Emit the SUB relocation first, since the SET relocation will write out
|
||||
the final value. */
|
||||
exp_dup->X_add_symbol = exp->X_op_symbol;
|
||||
fix_new_exp (fragP, fragP->fr_fix, 0,
|
||||
exp_dup, 0, BFD_RELOC_MSP430_SUB_ULEB128);
|
||||
|
||||
exp_dup->X_add_symbol = exp->X_add_symbol;
|
||||
/* Insert relocations to resolve the subtraction at link-time. */
|
||||
fix_new_exp (fragP, fragP->fr_fix, 0,
|
||||
exp_dup, 0, BFD_RELOC_MSP430_SET_ULEB128);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* Called after all assembly has been done. */
|
||||
void
|
||||
msp430_md_end (void)
|
||||
{
|
||||
|
@ -5065,6 +5113,10 @@ msp430_md_end (void)
|
|||
as_warn (_(WARN_NOP_AT_EOF));
|
||||
}
|
||||
|
||||
/* Insert relocations for uleb128 directives, so the values can be recomputed
|
||||
at link time. */
|
||||
bfd_map_over_sections (stdoutput, msp430_insert_uleb128_fixes, NULL);
|
||||
|
||||
/* We have already emitted an error if any of the following attributes
|
||||
disagree with the attributes in the input assembly file. See
|
||||
msp430_object_attribute. */
|
||||
|
|
|
@ -1,3 +1,10 @@
|
|||
2020-09-08 Jozef Lawrynowicz <jozef.l@mittosystems.com>
|
||||
Kuan-Lin Chen <kuanlinchentw@gmail.com>
|
||||
|
||||
* 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.
|
||||
|
||||
2020-09-08 Alex Coplan <alex.coplan@arm.com>
|
||||
|
||||
* opcode/aarch64.h (aarch64_sys_ins_reg_supported_p): Also take
|
||||
|
|
|
@ -113,6 +113,8 @@ START_RELOC_NUMBERS (elf_msp430_reloc_type)
|
|||
RELOC_NUMBER (R_MSP430_RL_PCREL, 8)
|
||||
RELOC_NUMBER (R_MSP430_8, 9)
|
||||
RELOC_NUMBER (R_MSP430_SYM_DIFF, 10)
|
||||
RELOC_NUMBER (R_MSP430_GNU_SET_ULEB128, 11) /* GNU only. */
|
||||
RELOC_NUMBER (R_MSP430_GNU_SUB_ULEB128, 12) /* GNU only. */
|
||||
END_RELOC_NUMBERS (R_MSP430_max)
|
||||
|
||||
START_RELOC_NUMBERS (elf_msp430x_reloc_type)
|
||||
|
@ -137,6 +139,8 @@ START_RELOC_NUMBERS (elf_msp430x_reloc_type)
|
|||
RELOC_NUMBER (R_MSP430X_10_PCREL, 19) /* Red Hat invention. Used for Jump instructions. */
|
||||
RELOC_NUMBER (R_MSP430X_2X_PCREL, 20) /* Red Hat invention. Used for relaxing jumps. */
|
||||
RELOC_NUMBER (R_MSP430X_SYM_DIFF, 21) /* Red Hat invention. Used for relaxing debug info. */
|
||||
RELOC_NUMBER (R_MSP430X_GNU_SET_ULEB128, 22) /* GNU only. */
|
||||
RELOC_NUMBER (R_MSP430X_GNU_SUB_ULEB128, 23) /* GNU only. */
|
||||
END_RELOC_NUMBERS (R_MSP430x_max)
|
||||
|
||||
#endif /* _ELF_MSP430_H */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]]} {
|
||||
|
|
34
ld/testsuite/ld-msp430-elf/uleb128.s
Normal file
34
ld/testsuite/ld-msp430-elf/uleb128.s
Normal file
|
@ -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
|
10
ld/testsuite/ld-msp430-elf/uleb128_430.d
Normal file
10
ld/testsuite/ld-msp430-elf/uleb128_430.d
Normal file
|
@ -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
|
10
ld/testsuite/ld-msp430-elf/uleb128_430x.d
Normal file
10
ld/testsuite/ld-msp430-elf/uleb128_430x.d
Normal file
|
@ -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
|
Loading…
Add table
Add a link
Reference in a new issue