MIPS: Add o32 RELA relocations for VxWorks targets

MIPS/VxWorks targets have an unusual arrangement in that they use RELA
relocations with the o32 ABI, unlike any other MIPS target.  Due to an
inconsistency in BFD however "hybrid" relocations are produced by GAS,
where despite the relocations being of the RELA type the field to be
relocated also holds an in-place addend to be applied at link time.

For example:

$ cat vxworks-rela.s
	.text
foo:
	la	$2, bar + 0x12345678
$ mips-vxworks-as -o vxworks-rela.o vxworks-rela.s
$ mips-vxworks-objdump -dr vxworks-rela.o

vxworks-rela.o:     file format elf32-bigmips-vxworks

Disassembly of section .text:

00000000 <foo>:
   0:	3c021234 	lui	v0,0x1234
			0: R_MIPS_HI16	bar+0x12345678
   4:	24425678 	addiu	v0,v0,22136
			4: R_MIPS_LO16	bar+0x12345678
$

This is due to the BFD backend being strapped for RELA relocations:

#undef elf_backend_may_use_rel_p
#define elf_backend_may_use_rel_p		0
#undef elf_backend_may_use_rela_p
#define elf_backend_may_use_rela_p		1
#undef elf_backend_default_use_rela_p
#define elf_backend_default_use_rela_p		1

but the howtos in use requesting an in-place addend, e.g.:

  /* High 16 bits of symbol value.  */
  HOWTO (R_MIPS_HI16,		/* type */
	 16,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont, /* complain_on_overflow */
	 _bfd_mips_elf_hi16_reloc, /* special_function */
	 "R_MIPS_HI16",		/* name */
	 true,			/* partial_inplace */
	 0x0000ffff,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 false),		/* pcrel_offset */

  /* Low 16 bits of symbol value.  */
  HOWTO (R_MIPS_LO16,		/* type */
	 0,			/* rightshift */
	 4,			/* size */
	 16,			/* bitsize */
	 false,			/* pc_relative */
	 0,			/* bitpos */
	 complain_overflow_dont, /* complain_on_overflow */
	 _bfd_mips_elf_lo16_reloc, /* special_function */
	 "R_MIPS_LO16",		/* name */
	 true,			/* partial_inplace */
	 0x0000ffff,		/* src_mask */
	 0x0000ffff,		/* dst_mask */
	 false),		/* pcrel_offset */

This arrangement nevertheless happens to produce correct ELF executables
owing to the ELF linker avoiding the use of howtos and doing relocation
calculations using its own knowledge of relocation semantics embedded
directly in `mips_elf_calculate_relocation' code.

Beyond producing questionable link object files it however breaks badly
with the generic linker, such as when output is srec.

Fix the problem by providing a set of o32 RELA howtos and making VxWorks
targets use it.  Complement it with a set of test cases for GAS and LD;
we expect link object files to be essentially the same as n32 ones for
other MIPS targets sans the ABI2 ELF file header flag, and machine code
produced to be the same between SREC and ELF executables.
This commit is contained in:
Maciej W. Rozycki
2025-10-30 14:24:23 +00:00
parent 040b85bd57
commit 6b21850203
10 changed files with 1606 additions and 48 deletions

View File

@@ -492,7 +492,11 @@ static int mips_32bitmode = 0;
#define HAVE_64BIT_OBJECTS (mips_abi == N64_ABI)
/* True if relocations are stored in-place. */
#ifdef TE_VXWORKS
#define HAVE_IN_PLACE_ADDENDS 0
#else
#define HAVE_IN_PLACE_ADDENDS (!HAVE_NEWABI)
#endif
/* The ABI-derived address size. */
#define HAVE_64BIT_ADDRESSES \

View File

@@ -573,6 +573,12 @@ if { [istarget mips*-*-vxworks*] } {
"MIPS invalid PIC option in VxWorks PIC"
run_list_test "option-pic-vxworks-2" "-mvxworks-pic" \
"MIPS invalid switch to SVR4 PIC from VxWorks PIC"
run_dump_test "vxworks-mips-hilo"
run_dump_test "vxworks-mips16-hilo"
run_dump_test "vxworks-mips16e2-hilo"
run_dump_test "vxworks-micromips-hilo"
run_dump_test "vxworks-pcrel-hilo"
} elseif { [istarget mips*-*-*] } {
set addr32 [expr [istarget mipstx39*-*-*] || [istarget mips-*-linux*] || [istarget mipsel-*-linux*] \
|| [istarget mipsisa32*-*-linux*]]

View File

@@ -0,0 +1,5 @@
#objdump: -dr
#name: VxWorks microMIPS lui/addiu
#as: -mabi=32 -march=mips32r2 -mmicromips
#source: mips-hilo.s
#dump: micromips-hilo-n32.d

View File

@@ -0,0 +1,5 @@
#objdump: -dr
#name: VxWorks MIPS lui/addiu
#as: -mabi=32 -march=mips32r2
#source: mips-hilo.s
#dump: mips-hilo-n32.d

View File

@@ -0,0 +1,5 @@
#objdump: -dr
#name: VxWorks MIPS16 lui/addi
#as: -mips16 -mabi=32 -march=mips32
#source: mips16-hilo.s
#dump: mips16-hilo-n32.d

View File

@@ -0,0 +1,5 @@
#objdump: -dr
#name: VxWorks MIPS16e2 lui/addi
#as: -mips16 -mabi=32 -march=mips32r2 -mmips16e2
#source: mips-hilo.s
#dump: mips16e2-hilo-n32.d

View File

@@ -0,0 +1,5 @@
#readelf: -r
#name: VxWorks MIPSr6 PCHI16/PCLO16 relocations
#as: -mabi=32 -march=mips32r6 -mno-pdr
#source: pcrel-hilo.s
#dump: pcrel-hilo-n32.d