public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* BFD_RELOC_MIPS_16
@ 2022-06-14  0:34 Alan Modra
  2022-08-02 23:59 ` BFD_RELOC_MIPS_16 Maciej W. Rozycki
  0 siblings, 1 reply; 4+ messages in thread
From: Alan Modra @ 2022-06-14  0:34 UTC (permalink / raw)
  To: binutils

MIPS should not be using BFD_RELOC_16 for its R_MIPS_16 relocation,
since R_MIPS_16 specifies a 16-bit field in a 32-bit word.
BFD_RELOC_16, emitted by generic code to handle fixups on 16-bit data
directives, expects fixups to operate on the whole of a 16-bit word.

This patch corrects the problem by using BFD_RELOC_MIPS_16, a new bfd
reloc that is used to generate R_MIPS_16.  BFD_RELOC_16 is handled in
md_apply_fix for cases where the fixup can be applied at assembly
time.  Like BFD_RELOC_8, BFD_RELOC_16 now has no corresponding object
file relocation, and thus .half, .hword, .short and .dc.w must be
resolved at assembly time.  BFD_RELOC_MIPS_REL16 is removed by this
patch since it isn't used.

	PR 3243
	PR 26542
	* reloc.c (BFD_RELOC_MIPS_16): Rename from BFD_RELOC_MIPS_REL16.
	* elf32-mips.c (mips_reloc_map): Map BFD_RELOC_MIPS_16 to R_MIPS_16.
	* elf64-mips.c (mips_reloc_map): Likewise, delete BFD_RELOC_MIPS_REL16.
	* elfn32-mips.c (mips_reloc_map): Likewise.
	* libbfd.h: Regenerate.
	* bfd-in2.h: Regenerate.
gas/
	* config/tc-mips.c (append_insn): Handle BFD_RELOC_MIPS_16.
	(macro_build): Likewise.
	(mips_percent_op <%half>): Generate BFD_RELOC_MIPS_16.
	(md_apply_fix): Handle BFD_RELOC_16 and BFD_RELOC_MIPS_16 when fx_done.
ld/
	* testsuite/ld-mips-elf/reloc-local-overflow.d,
	* testsuite/ld-mips-elf/reloc-local-overflow.s: Rewrite.

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 64e74adff73..14d37630c79 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2611,7 +2611,7 @@ to compensate for the borrow when the low bits are added.  */
   BFD_RELOC_MICROMIPS_HIGHER,
   BFD_RELOC_MIPS_SCN_DISP,
   BFD_RELOC_MICROMIPS_SCN_DISP,
-  BFD_RELOC_MIPS_REL16,
+  BFD_RELOC_MIPS_16,
   BFD_RELOC_MIPS_RELGOT,
   BFD_RELOC_MIPS_JALR,
   BFD_RELOC_MICROMIPS_JALR,
diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index b08c27e8be0..b611515990d 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -1978,7 +1978,7 @@ struct elf_reloc_map {
 static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE },
-  { BFD_RELOC_16, R_MIPS_16 },
+  { BFD_RELOC_MIPS_16, R_MIPS_16 },
   { BFD_RELOC_32, R_MIPS_32 },
   /* There is no BFD reloc for R_MIPS_REL32.  */
   { BFD_RELOC_64, R_MIPS_64 },
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index a97f4228ce7..8097e7cd49d 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -3683,7 +3683,7 @@ struct elf_reloc_map {
 static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE },
-  { BFD_RELOC_16, R_MIPS_16 },
+  { BFD_RELOC_MIPS_16, R_MIPS_16 },
   { BFD_RELOC_32, R_MIPS_32 },
   /* There is no BFD reloc for R_MIPS_REL32.  */
   { BFD_RELOC_64, R_MIPS_64 },
@@ -3713,7 +3713,6 @@ static const struct elf_reloc_map mips_reloc_map[] =
   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
-  { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 2027230c651..7cae394bfa0 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -3513,7 +3513,7 @@ struct elf_reloc_map {
 static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE },
-  { BFD_RELOC_16, R_MIPS_16 },
+  { BFD_RELOC_MIPS_16, R_MIPS_16 },
   { BFD_RELOC_32, R_MIPS_32 },
   /* There is no BFD reloc for R_MIPS_REL32.  */
   { BFD_RELOC_CTOR, R_MIPS_32 },
@@ -3543,7 +3543,6 @@ static const struct elf_reloc_map mips_reloc_map[] =
   { BFD_RELOC_MIPS_CALL_HI16, R_MIPS_CALL_HI16 },
   { BFD_RELOC_MIPS_CALL_LO16, R_MIPS_CALL_LO16 },
   { BFD_RELOC_MIPS_SCN_DISP, R_MIPS_SCN_DISP },
-  { BFD_RELOC_MIPS_REL16, R_MIPS_REL16 },
   /* Use of R_MIPS_ADD_IMMEDIATE and R_MIPS_PJUMP is deprecated.  */
   { BFD_RELOC_MIPS_RELGOT, R_MIPS_RELGOT },
   { BFD_RELOC_MIPS_JALR, R_MIPS_JALR },
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 8c02e29eebd..4a3020cc122 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1285,7 +1285,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_MICROMIPS_HIGHER",
   "BFD_RELOC_MIPS_SCN_DISP",
   "BFD_RELOC_MICROMIPS_SCN_DISP",
-  "BFD_RELOC_MIPS_REL16",
+  "BFD_RELOC_MIPS_16",
   "BFD_RELOC_MIPS_RELGOT",
   "BFD_RELOC_MIPS_JALR",
   "BFD_RELOC_MICROMIPS_JALR",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 76c309bc903..eb8dba36a83 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2293,7 +2293,7 @@ ENUMX
 ENUMX
   BFD_RELOC_MICROMIPS_SCN_DISP
 ENUMX
-  BFD_RELOC_MIPS_REL16
+  BFD_RELOC_MIPS_16
 ENUMX
   BFD_RELOC_MIPS_RELGOT
 ENUMX
diff --git a/gas/config/tc-mips.c b/gas/config/tc-mips.c
index 9b895a65b63..406a04aeae6 100644
--- a/gas/config/tc-mips.c
+++ b/gas/config/tc-mips.c
@@ -7919,7 +7919,7 @@ append_insn (struct mips_cl_insn *ip, expressionS *address_expr,
 	      || reloc_type[0] == BFD_RELOC_MIPS_HIGHEST
 	      || reloc_type[0] == BFD_RELOC_MIPS_HIGHER
 	      || reloc_type[0] == BFD_RELOC_MIPS_SCN_DISP
-	      || reloc_type[0] == BFD_RELOC_MIPS_REL16
+	      || reloc_type[0] == BFD_RELOC_MIPS_16
 	      || reloc_type[0] == BFD_RELOC_MIPS_RELGOT
 	      || reloc_type[0] == BFD_RELOC_MIPS16_GPREL
 	      || hi16_reloc_p (reloc_type[0])
@@ -9083,7 +9083,7 @@ macro_build (expressionS *ep, const char *name, const char *fmt, ...)
 		      || *r == BFD_RELOC_LO16
 		      || *r == BFD_RELOC_MIPS_GOT_OFST
 		      || (mips_opts.micromips
-			  && (*r == BFD_RELOC_16
+			  && (*r == BFD_RELOC_MIPS_16
 			      || *r == BFD_RELOC_MIPS_GOT16
 			      || *r == BFD_RELOC_MIPS_CALL16
 			      || *r == BFD_RELOC_MIPS_GOT_HI16
@@ -14577,7 +14577,7 @@ static const struct percent_op_match mips_percent_op[] =
   {"%got", BFD_RELOC_MIPS_GOT16},
   {"%gp_rel", BFD_RELOC_GPREL16},
   {"%gprel", BFD_RELOC_GPREL16},
-  {"%half", BFD_RELOC_16},
+  {"%half", BFD_RELOC_MIPS_16},
   {"%highest", BFD_RELOC_MIPS_HIGHEST},
   {"%higher", BFD_RELOC_MIPS_HIGHER},
   {"%neg", BFD_RELOC_MIPS_SUB},
@@ -15841,9 +15841,10 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
 	break;
       }
 
-  /* Handle BFD_RELOC_8, since it's easy.  Punt on other bfd relocations
-     that have no MIPS ELF equivalent.  */
-  if (fixP->fx_r_type != BFD_RELOC_8)
+  /* Handle BFD_RELOC_8 and BFD_RELOC_16.  Punt on other bfd
+     relocations that have no MIPS ELF equivalent.  */
+  if (fixP->fx_r_type != BFD_RELOC_8
+      && fixP->fx_r_type != BFD_RELOC_16)
     {
       howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
       if (!howto)
@@ -15853,7 +15854,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
   gas_assert (fixP->fx_size == 2
 	      || fixP->fx_size == 4
 	      || fixP->fx_r_type == BFD_RELOC_8
-	      || fixP->fx_r_type == BFD_RELOC_16
 	      || fixP->fx_r_type == BFD_RELOC_64
 	      || fixP->fx_r_type == BFD_RELOC_CTOR
 	      || fixP->fx_r_type == BFD_RELOC_MIPS_SUB
@@ -15958,7 +15958,6 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_MIPS_HIGHEST:
     case BFD_RELOC_MIPS_HIGHER:
     case BFD_RELOC_MIPS_SCN_DISP:
-    case BFD_RELOC_MIPS_REL16:
     case BFD_RELOC_MIPS_RELGOT:
     case BFD_RELOC_MIPS_JALR:
     case BFD_RELOC_HI16:
@@ -16044,6 +16043,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     case BFD_RELOC_RVA:
     case BFD_RELOC_32:
     case BFD_RELOC_32_PCREL:
+    case BFD_RELOC_MIPS_16:
     case BFD_RELOC_16:
     case BFD_RELOC_8:
       /* If we are deleting this reloc entry, we must fill in the
diff --git a/ld/testsuite/ld-mips-elf/reloc-local-overflow.d b/ld/testsuite/ld-mips-elf/reloc-local-overflow.d
index 98c5ddbd7bd..1405b2def91 100644
--- a/ld/testsuite/ld-mips-elf/reloc-local-overflow.d
+++ b/ld/testsuite/ld-mips-elf/reloc-local-overflow.d
@@ -1,6 +1,6 @@
 #name: MIPS reloc against local symbol overflow
 #source: reloc-local-overflow.s
-#ld: -Tdata 0x10000 -e 0
-#error: \A[^\n]*:\(\.data\+0x1000\): relocation truncated to fit: R_MIPS_16 against `\.data'\Z
+#ld: -Tdata 0x10000000 -e 0
+#error: \A[^\n]*:\(\.text\+0x0\): relocation truncated to fit: R_MIPS_26 against `\.data'\Z
 
 # Verify that the section name (`.data') is printed rather than `no symbol'.
diff --git a/ld/testsuite/ld-mips-elf/reloc-local-overflow.s b/ld/testsuite/ld-mips-elf/reloc-local-overflow.s
index a07255c3f78..6d50c7bba56 100644
--- a/ld/testsuite/ld-mips-elf/reloc-local-overflow.s
+++ b/ld/testsuite/ld-mips-elf/reloc-local-overflow.s
@@ -1,8 +1,5 @@
-	.data
-	.space	0x1000
+	.text
+	j init
 
-	.align	2
-	.type	bar, @object
-bar:
-	.half	bar
-	.size	bar, . - bar
+	.data
+init:

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: BFD_RELOC_MIPS_16
  2022-06-14  0:34 BFD_RELOC_MIPS_16 Alan Modra
@ 2022-08-02 23:59 ` Maciej W. Rozycki
  2022-08-04  3:37   ` BFD_RELOC_MIPS_16 Alan Modra
  0 siblings, 1 reply; 4+ messages in thread
From: Maciej W. Rozycki @ 2022-08-02 23:59 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

On Tue, 14 Jun 2022, Alan Modra via Binutils wrote:

> time.  Like BFD_RELOC_8, BFD_RELOC_16 now has no corresponding object
> file relocation, and thus .half, .hword, .short and .dc.w must be
> resolved at assembly time.

 That should be R_MIPS_REL16 AFAICT, reloc #33 according to MIPS NewABI 
documentation[1]:

    Name      Value  Field   Symbol  Calculation
R_MIPS_REL16   33    V-hw16   any        S+A

and we have all the bits including a howto in place.  I wonder what 
happened that we never had it linked with BFD_RELOC_16.

References:

[1] "64-bit ELF Object File Specification", Draft Version 2.5, MIPS 
    Technologies / Silicon Graphics Computer Systems, Document Number 
    007-4658-001, Table 32 "Relocation Types", p. 46

  Maciej

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: BFD_RELOC_MIPS_16
  2022-08-02 23:59 ` BFD_RELOC_MIPS_16 Maciej W. Rozycki
@ 2022-08-04  3:37   ` Alan Modra
  2022-08-05 15:13     ` BFD_RELOC_MIPS_16 Maciej W. Rozycki
  0 siblings, 1 reply; 4+ messages in thread
From: Alan Modra @ 2022-08-04  3:37 UTC (permalink / raw)
  To: Maciej W. Rozycki; +Cc: binutils

On Wed, Aug 03, 2022 at 12:59:09AM +0100, Maciej W. Rozycki wrote:
> On Tue, 14 Jun 2022, Alan Modra via Binutils wrote:
> 
> > time.  Like BFD_RELOC_8, BFD_RELOC_16 now has no corresponding object
> > file relocation, and thus .half, .hword, .short and .dc.w must be
> > resolved at assembly time.
> 
>  That should be R_MIPS_REL16 AFAICT, reloc #33 according to MIPS NewABI 
> documentation[1]:
> 
>     Name      Value  Field   Symbol  Calculation
> R_MIPS_REL16   33    V-hw16   any        S+A

Huh.  So R_MIPS_REL16 isn't a pc-relative reloc as the name might
indicate.  I'll apply the following.

	* elf64-mips.c (mips_reloc_map): Map BFD_RELOC_16 to R_MIPS_REL16.
	* elfn32-mips.c (mips_reloc_map): Likewise.

diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index 8097e7cd49d..c2c6604ef68 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -3684,6 +3684,7 @@ static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE },
   { BFD_RELOC_MIPS_16, R_MIPS_16 },
+  { BFD_RELOC_16, R_MIPS_REL16 },
   { BFD_RELOC_32, R_MIPS_32 },
   /* There is no BFD reloc for R_MIPS_REL32.  */
   { BFD_RELOC_64, R_MIPS_64 },
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 7cae394bfa0..af984545796 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -3514,6 +3514,7 @@ static const struct elf_reloc_map mips_reloc_map[] =
 {
   { BFD_RELOC_NONE, R_MIPS_NONE },
   { BFD_RELOC_MIPS_16, R_MIPS_16 },
+  { BFD_RELOC_16, R_MIPS_REL16 },
   { BFD_RELOC_32, R_MIPS_32 },
   /* There is no BFD reloc for R_MIPS_REL32.  */
   { BFD_RELOC_CTOR, R_MIPS_32 },


-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: BFD_RELOC_MIPS_16
  2022-08-04  3:37   ` BFD_RELOC_MIPS_16 Alan Modra
@ 2022-08-05 15:13     ` Maciej W. Rozycki
  0 siblings, 0 replies; 4+ messages in thread
From: Maciej W. Rozycki @ 2022-08-05 15:13 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils

On Thu, 4 Aug 2022, Alan Modra wrote:

> > > time.  Like BFD_RELOC_8, BFD_RELOC_16 now has no corresponding object
> > > file relocation, and thus .half, .hword, .short and .dc.w must be
> > > resolved at assembly time.
> > 
> >  That should be R_MIPS_REL16 AFAICT, reloc #33 according to MIPS NewABI 
> > documentation[1]:
> > 
> >     Name      Value  Field   Symbol  Calculation
> > R_MIPS_REL16   33    V-hw16   any        S+A
> 
> Huh.  So R_MIPS_REL16 isn't a pc-relative reloc as the name might
> indicate.  I'll apply the following.

 It's not clear to me what the REL infix might imply here given how other 
relevant relocations have been defined:

    Name      Value   Field    Symbol  Calculation
R_MIPS_16       1    V-half16   any    S+sign_extend(A)
R_MIPS_REL32    3    T-word32   any    S+A-EA
R_MIPS_PC16    10    V-pc16     any    sign_extend(A)+S-P

but the calculation given is I believe unambiguous and refers neither EA 
(effective address; meaningful for dynamic loading only and referring to 
factoring the base address into the calculation) nor P (PC).

 Of course I cannot claim the document is flawless; even the definition of 
R_MIPS_16 carried over from the old ABI isn't right anymore given that 
NewABI has RELA relocations.  Maybe IRIX actually implemented R_MIPS_REL16 
in a different manner.  I have no means to verify that however, so the 
document is the best resource we have.

 Last but not least please note that NewABI makes heavy use of composed 
relocations, so R_MIPS_REL16 may have just been a way to specify a 16-bit 
relocatable field, useful for compact jump tables for example, especially 
given the relocation's straightforward calculation, and R_MIPS_16 had 
already been taken so a different name had to be come up with.  Then you 
can compose R_MIPS_PC16 with R_MIPS_REL16 to make a PC-relative 16-bit 
relocatable field, similarly to how say a 64-bit base-address-relative 
relocatable field is made by composing R_MIPS_REL32 (alias R_MIPS_REL) 
with R_MIPS_64.

 The latter operation is documented in the specification referred as are 
a couple of other ones[1]:

"The initial elf.h file defined several relocations for dealing with GOTs 
larger than 64KB which we do not include, favoring other approaches as 
described above:

" R_MIPS_REL64
                 This can be produced by composing R_MIPS_REL with
                 R_MIPS_64.

" R_MIPS_LIT_HI16, R_MIPS_LIT_LO16
                 These can be produced by composing R_MIPS_LITERAL
                 with R_MIPS_HI16 or R_MIPS_LO16.

" R_MIPS_GPOFF_HI16, R_MIPS_GPOFF_LO16
                 As described above, these can be produced by composing
                 R_MIPS_GPREL with R_MIPS_HI16 or R_MIPS_LO16."

but the list is by no means exhaustive given that relocation composition 
is a generic ELF feature (even is scarcely implemented).  So I'm now quite 
convinced the calculation is right and only the name of the relocation 
misleading.

> 	* elf64-mips.c (mips_reloc_map): Map BFD_RELOC_16 to R_MIPS_REL16.
> 	* elfn32-mips.c (mips_reloc_map): Likewise.

 LGTM, thanks!

References:

[1] "64-bit ELF Object File Specification", Draft Version 2.5, MIPS
    Technologies / Silicon Graphics Computer Systems, Document Number
    007-4658-001, Section 2.9.4 "Discarded Relocations", pp. 52-53

  Maciej

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-08-05 15:13 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-06-14  0:34 BFD_RELOC_MIPS_16 Alan Modra
2022-08-02 23:59 ` BFD_RELOC_MIPS_16 Maciej W. Rozycki
2022-08-04  3:37   ` BFD_RELOC_MIPS_16 Alan Modra
2022-08-05 15:13     ` BFD_RELOC_MIPS_16 Maciej W. Rozycki

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).