public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* MIPS HI16 and LO16 reloc howtos
@ 2024-04-02  1:05 Alan Modra
  2024-04-02  1:06 ` MIPS reloc howto special_function entries Alan Modra
  2024-04-02 11:19 ` MIPS HI16 and LO16 reloc howtos Maciej W. Rozycki
  0 siblings, 2 replies; 5+ messages in thread
From: Alan Modra @ 2024-04-02  1:05 UTC (permalink / raw)
  To: binutils; +Cc: Chenghua Xu, Maciej W. Rozycki

All the HI16 reloc howtos should have a rightshift of 16, and all the
LO16 relocs shouldn't complain on overflow.  This was correct for
R_MIPS_LO16 and R_MIPS_LO16 (at least on the howto_table_rel entries),
and corresponding MIPS16, MICROMIPS and MIPS64 relocs, but not on many
other HI16 and LO16 relocs.

While we're at it, fix the HIGHER and HIGHEST rightshift too.

These changes are necessary to support addends outside the range
[0,32767] when those addends are stored in section contents.  Note
that some of the reloc howtos changed here will always have zero
addends (GOT_HI16, CALL_HI16).  Those don't really need changing, but
use what is clearly correct for hi16 relocs anyway.

	PR 19977
	* elf32-mips.c: Correct rightshift for HI16, HIGHER and HIGHEST
	reloc howtos.  Correct complain_on_overflow for LO16 relocs.
	* elf64-mips.c: Likewise.
	* elfn32-mips.c: Likewise.

OK?  This is a prerequisite to fixing PR19977.

diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index f97986cd5b9..bec7a207aa8 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -404,7 +404,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -454,7 +454,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MIPS_HIGHER,		/* type */
-	 0,			/* rightshift */
+	 32,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -469,7 +469,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* Get the highest value of a 64 bit addend.  */
   HOWTO (R_MIPS_HIGHEST,	/* type */
-	 0,			/* rightshift */
+	 48,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -484,7 +484,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -612,7 +612,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -632,7 +632,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -674,7 +674,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -694,7 +694,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -955,7 +955,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 
   /* MIPS16 TLS local dynamic offset.  */
   HOWTO (R_MIPS16_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -975,7 +975,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -1000,7 +1000,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 
   /* MIPS16 TLS thread pointer offset.  */
   HOWTO (R_MIPS16_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1020,7 +1020,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -1251,7 +1251,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1296,7 +1296,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHER,	/* type */
-	 0,			/* rightshift */
+	 32,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1311,7 +1311,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* Get the highest value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHEST,	/* type */
-	 0,			/* rightshift */
+	 48,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1326,7 +1326,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1438,7 +1438,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1458,7 +1458,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -1486,7 +1486,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MICROMIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1506,7 +1506,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index 736e5f5c36d..afd7b30f134 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -431,7 +431,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -534,7 +534,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -691,7 +691,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -711,7 +711,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -753,7 +753,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -773,7 +773,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -975,7 +975,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,		/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1191,7 +1191,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1285,7 +1285,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MIPS_HIGHER,		/* type */
-	 0,			/* rightshift */
+	 32,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1300,7 +1300,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* Get the highest value of a 64 bit addend.  */
   HOWTO (R_MIPS_HIGHEST,	/* type */
-	 0,			/* rightshift */
+	 48,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1315,7 +1315,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1472,7 +1472,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1492,7 +1492,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -1534,7 +1534,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1554,7 +1554,7 @@ static reloc_howto_type mips_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */
@@ -1799,7 +1799,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 
   /* MIPS16 TLS local dynamic offset.  */
   HOWTO (R_MIPS16_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1819,7 +1819,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -1844,7 +1844,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 
   /* MIPS16 TLS thread pointer offset.  */
   HOWTO (R_MIPS16_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1864,7 +1864,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -2015,7 +2015,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 
   /* MIPS16 TLS local dynamic offset.  */
   HOWTO (R_MIPS16_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2035,7 +2035,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -2060,7 +2060,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 
   /* MIPS16 TLS thread pointer offset.  */
   HOWTO (R_MIPS16_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2080,7 +2080,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */
@@ -2311,7 +2311,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2363,7 +2363,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2475,7 +2475,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2495,7 +2495,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -2523,7 +2523,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MICROMIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2543,7 +2543,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -2790,7 +2790,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2835,7 +2835,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHER,	/* type */
-	 0,			/* rightshift */
+	 32,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2850,7 +2850,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* Get the highest value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHEST,	/* type */
-	 0,			/* rightshift */
+	 48,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2865,7 +2865,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2977,7 +2977,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2997,7 +2997,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -3025,7 +3025,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MICROMIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -3045,7 +3045,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index c84a6ab3673..e137204aff7 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -410,7 +410,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -513,7 +513,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -670,7 +670,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -690,7 +690,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -732,7 +732,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -752,7 +752,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -954,7 +954,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 
   /* High 16 bits of symbol value.  */
   HOWTO (R_MIPS_HI16,		/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1170,7 +1170,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1452,7 +1452,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1472,7 +1472,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -1514,7 +1514,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1534,7 +1534,7 @@ static reloc_howto_type elf_mips_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */
@@ -1779,7 +1779,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 
   /* MIPS16 TLS local dynamic offset.  */
   HOWTO (R_MIPS16_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1799,7 +1799,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -1824,7 +1824,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 
   /* MIPS16 TLS thread pointer offset.  */
   HOWTO (R_MIPS16_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -1844,7 +1844,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -1995,7 +1995,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 
   /* MIPS16 TLS local dynamic offset.  */
   HOWTO (R_MIPS16_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2015,7 +2015,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -2040,7 +2040,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 
   /* MIPS16 TLS thread pointer offset.  */
   HOWTO (R_MIPS16_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2060,7 +2060,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */
@@ -2291,7 +2291,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2343,7 +2343,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2455,7 +2455,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2475,7 +2475,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
@@ -2503,7 +2503,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MICROMIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2523,7 +2523,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
@@ -2770,7 +2770,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_GOT_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2815,7 +2815,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* Get the higher value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHER,	/* type */
-	 0,			/* rightshift */
+	 32,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2830,7 +2830,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* Get the highest value of a 64 bit addend.  */
   HOWTO (R_MICROMIPS_HIGHEST,	/* type */
-	 0,			/* rightshift */
+	 48,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2845,7 +2845,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* High 16 bits of displacement in global offset table.  */
   HOWTO (R_MICROMIPS_CALL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2957,7 +2957,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* TLS local dynamic offset.  */
   HOWTO (R_MICROMIPS_TLS_DTPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -2977,7 +2977,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 false,			/* partial_inplace */
@@ -3005,7 +3005,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 
   /* TLS thread pointer offset.  */
   HOWTO (R_MICROMIPS_TLS_TPREL_HI16,	/* type */
-	 0,			/* rightshift */
+	 16,			/* rightshift */
 	 4,			/* size */
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
@@ -3025,7 +3025,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 	 16,			/* bitsize */
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
-	 complain_overflow_signed, /* complain_on_overflow */
+	 complain_overflow_dont, /* complain_on_overflow */
 	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 false,			/* partial_inplace */

-- 
Alan Modra
Australia Development Lab, IBM

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

* MIPS reloc howto special_function entries
  2024-04-02  1:05 MIPS HI16 and LO16 reloc howtos Alan Modra
@ 2024-04-02  1:06 ` Alan Modra
  2024-04-02  1:07   ` R_MIP16_GOT16 and R_MICROMIPS_GOT16 Alan Modra
  2024-04-02 11:19 ` MIPS HI16 and LO16 reloc howtos Maciej W. Rozycki
  1 sibling, 1 reply; 5+ messages in thread
From: Alan Modra @ 2024-04-02  1:06 UTC (permalink / raw)
  To: binutils; +Cc: Chenghua Xu, Maciej W. Rozycki

This corrects the DTPREL_HI16/LO16 and TPREL_HI16/LO16 howtos to use
_bfd_mips_elf_{hi,lo}16_reloc special functions, in order to support
addends outside the range [0,32767] on these relocations.

The patch also corrects the mips16 and micromips rela tables to *not*
use _bfd_mips_elf_{hi,lo}16_reloc.  These special functions are
inappropriate for RELA relocs where addends are in the reloc rather
than in the section contents.  See corresponding rela R_MIPS howtos.

R_MIPS_GOT_HI16, R_MIPS_GOT_LO16, R_MIPS_CALL_HI16 and R_MIPS_CALL_LO16
are left alone as it seems that we (quite reasonably) only support
zero addends for those relocs.

	PR 19977
bfd/
	* elf32-mips.c (elf_mips_howto_table_rel): Set special_function
	to _bfd_mips_elf_hi16_reloc for R_MIPS_TLS_DTPREL_HI16 and
	R_MIPS_TLS_TPREL_HI16.  Set special_functio to
	_bfd_mips_elf_lo16_reloc for R_MIPS_TLS_DTPREL_LO16 and
	R_MIPS_TLS_TPREL_LO16
	(elf_mips16_howto_table_rel): Likewise for
	R_MIPS16_TLS_DTPREL_HI16, R_MIPS16_TLS_DTPREL_LO16,
	R_MIPS16_TLS_TPREL_HI16 and R_MIPS16_TLS_TPREL_LO16.
	(elf_micromips_howto_table_rel): Likewise for
	R_MICROMIPS_TLS_DTPREL_HI16, R_MICROMIPS_TLS_DTPREL_LO16,
	R_MICROMIPS_TLS_TPREL_HI16 and R_MICROMIPS_TLS_TPREL_LO16.
	* elf64-mips.c (mips_elf64_howto_table_rel): Similarly.
	(mips16_elf64_howto_table_rel): Similarly.
	(micromips_elf64_howto_table_rel): Similarly.
	(mips16_elf64_howto_table_rela <R_MIPS16_HI16, R_MIPS16_LO16>):
	Use _bfd_mips_elf_generic_reloc special_function.
	(micromips_elf64_howto_table_rela): Similarly.
	* elfn32-mips.c: As for elf64-mips.c.
gas/
	* testsuite/gas/mips/pr19977.d,
	* testsuite/gas/mips/pr19977.s: New test.
	* testsuite/gas/mips/mips.exp: Run it.

OK?

diff --git a/bfd/elf32-mips.c b/bfd/elf32-mips.c
index bec7a207aa8..67bccceb6de 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -618,7 +618,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -633,7 +633,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -680,7 +680,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -695,7 +695,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -961,7 +961,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -976,7 +976,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1006,7 +1006,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1021,7 +1021,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1444,7 +1444,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1459,7 +1459,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1492,7 +1492,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1507,7 +1507,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index afd7b30f134..b4509fb13f2 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -697,7 +697,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -712,7 +712,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -759,7 +759,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -774,7 +774,7 @@ static reloc_howto_type mips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1805,7 +1805,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1820,7 +1820,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1850,7 +1850,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1865,7 +1865,7 @@ static reloc_howto_type mips16_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1961,7 +1961,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_hi16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_HI16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -1976,7 +1976,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_lo16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_LO16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2481,7 +2481,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2496,7 +2496,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2529,7 +2529,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2544,7 +2544,7 @@ static reloc_howto_type micromips_elf64_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2615,7 +2615,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_hi16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_HI16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2630,7 +2630,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_lo16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_LO16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index e137204aff7..3e9153cde14 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -676,7 +676,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -691,7 +691,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -738,7 +738,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -753,7 +753,7 @@ static reloc_howto_type elf_mips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1785,7 +1785,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1800,7 +1800,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1830,7 +1830,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1845,7 +1845,7 @@ static reloc_howto_type elf_mips16_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MIPS16_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -1941,7 +1941,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_hi16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_HI16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -1956,7 +1956,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_lo16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_LO16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2461,7 +2461,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_HI16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2476,7 +2476,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_DTPREL_LO16",	/* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2509,7 +2509,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_hi16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_HI16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2524,7 +2524,7 @@ static reloc_howto_type elf_micromips_howto_table_rel[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_generic_reloc, /* special_function */
+	 _bfd_mips_elf_lo16_reloc, /* special_function */
 	 "R_MICROMIPS_TLS_TPREL_LO16", /* name */
 	 true,			/* partial_inplace */
 	 0x0000ffff,		/* src_mask */
@@ -2595,7 +2595,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_hi16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_HI16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2610,7 +2610,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_lo16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_LO16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
diff --git a/gas/testsuite/gas/mips/mips.exp b/gas/testsuite/gas/mips/mips.exp
index 2ddbf0c768d..2977710804d 100644
--- a/gas/testsuite/gas/mips/mips.exp
+++ b/gas/testsuite/gas/mips/mips.exp
@@ -1567,6 +1567,9 @@ if { [istarget mips*-*-vxworks*] } {
     if $has_newabi { run_dump_test "cfi-n64-1" }
 
     run_dump_test "pr12915"
+
+    run_dump_test_arches pr19977 [mips_arch_list_all]
+
     run_dump_test "reginfo-1a"
     run_dump_test "reginfo-1b"
     run_dump_test "reginfo-2"
diff --git a/gas/testsuite/gas/mips/pr19977.d b/gas/testsuite/gas/mips/pr19977.d
new file mode 100644
index 00000000000..e5d990c8712
--- /dev/null
+++ b/gas/testsuite/gas/mips/pr19977.d
@@ -0,0 +1,20 @@
+#name: pr19977
+#as: -32
+#objdump: -dr
+
+.*
+
+Disassembly of section \.text:
+
+0+ <foo>:
+   0:	.*	li	v1,4387
+			0: R_(|MICRO)MIPS(|16)_TLS_TPREL_HI16	\$loc0
+   4:	.*	sll	.*
+   8:	.*	addiu	v1(|,v1),-26232
+			8: R_(|MICRO)MIPS(|16)_TLS_TPREL_LO16	\$loc0
+   c:	.*	li	v1,4387
+			c: R_(|MICRO)MIPS(|16)_TLS_DTPREL_HI16	\$loc0
+  10:	.*	sll	.*
+  14:	.*	addiu	v1(|,v1),-26232
+			14: R_(|MICRO)MIPS(|16)_TLS_DTPREL_LO16	\$loc0
+#pass
diff --git a/gas/testsuite/gas/mips/pr19977.s b/gas/testsuite/gas/mips/pr19977.s
new file mode 100644
index 00000000000..403f60937a9
--- /dev/null
+++ b/gas/testsuite/gas/mips/pr19977.s
@@ -0,0 +1,13 @@
+ .text
+foo:
+ li $3,%tprel_hi($loc0+0x11229988)
+ sll $3,16
+ addiu $3,%tprel_lo($loc0+0x11229988)
+
+ li $3,%dtprel_hi($loc0+0x11229988)
+ sll $3,16
+ addiu $3,%dtprel_lo($loc0+0x11229988)
+
+ .section .tdata,"awT",%progbits
+$loc0:
+ .word 0

-- 
Alan Modra
Australia Development Lab, IBM

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

* R_MIP16_GOT16 and R_MICROMIPS_GOT16
  2024-04-02  1:06 ` MIPS reloc howto special_function entries Alan Modra
@ 2024-04-02  1:07   ` Alan Modra
  2024-04-02  1:08     ` MIPS linker changes for TLS HI16/LO16 relocs Alan Modra
  0 siblings, 1 reply; 5+ messages in thread
From: Alan Modra @ 2024-04-02  1:07 UTC (permalink / raw)
  To: binutils; +Cc: Chenghua Xu, Maciej W. Rozycki

In rela howtos these relocations should not be using
_bfd_mips_elf_got16_reloc.  That special function is for extracting
addends from section contents, and only for that (ie. it doesn't
subtract gp).  Make these rela howtos like the corresponding
R_MIPS_GOT16 rela howto.

	* elf64-mips.c (mips16_elf64_howto_table_rela <R_MIPS16_GOT16>):
	Use _bfd_mips_elf_generic_reloc.
	(micromips_elf64_howto_table_rela <R_MICROMIPS_GOT16>): Likewise.
	* elfn32-mips.c (elf_mips16_howto_table_rela <R_MIPS16_GOT16>):
	Likewise.
	(elf_micromips_howto_table_rela <R_MICROMIPS_GOT16>): Likewise.

OK?

diff --git a/bfd/elf64-mips.c b/bfd/elf64-mips.c
index b4509fb13f2..e83230cef97 100644
--- a/bfd/elf64-mips.c
+++ b/bfd/elf64-mips.c
@@ -1931,7 +1931,7 @@ static reloc_howto_type mips16_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_got16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_GOT16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2675,7 +2675,7 @@ static reloc_howto_type micromips_elf64_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_got16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_GOT16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
diff --git a/bfd/elfn32-mips.c b/bfd/elfn32-mips.c
index 3e9153cde14..432805aeeb2 100644
--- a/bfd/elfn32-mips.c
+++ b/bfd/elfn32-mips.c
@@ -1911,7 +1911,7 @@ static reloc_howto_type elf_mips16_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 _bfd_mips_elf_got16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MIPS16_GOT16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -2655,7 +2655,7 @@ static reloc_howto_type elf_micromips_howto_table_rela[] =
 	 false,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_signed, /* complain_on_overflow */
-	 _bfd_mips_elf_got16_reloc, /* special_function */
+	 _bfd_mips_elf_generic_reloc, /* special_function */
 	 "R_MICROMIPS_GOT16",	/* name */
 	 false,			/* partial_inplace */
 	 0,			/* src_mask */

-- 
Alan Modra
Australia Development Lab, IBM

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

* MIPS linker changes for TLS HI16/LO16 relocs
  2024-04-02  1:07   ` R_MIP16_GOT16 and R_MICROMIPS_GOT16 Alan Modra
@ 2024-04-02  1:08     ` Alan Modra
  0 siblings, 0 replies; 5+ messages in thread
From: Alan Modra @ 2024-04-02  1:08 UTC (permalink / raw)
  To: binutils; +Cc: Chenghua Xu, Maciej W. Rozycki

	PR 19977
	* elfxx-mips.c (tls_hi16_reloc_p): New function.
	(mips_elf_add_lo16_rel_addend): Handle tls relocs.
	(_bfd_mips_elf_relocate_section): Likewise.

OK?

diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c
index f2a1441fdf7..d7600886a4a 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -2300,6 +2300,17 @@ lo16_reloc_p (int r_type)
 	  || r_type == R_MIPS_PCLO16);
 }
 
+static inline bool
+tls_hi16_reloc_p (int r_type)
+{
+  return (r_type == R_MIPS_TLS_DTPREL_HI16
+	  || r_type == R_MIPS_TLS_TPREL_HI16
+	  || r_type == R_MIPS16_TLS_DTPREL_HI16
+	  || r_type == R_MIPS16_TLS_TPREL_HI16
+	  || r_type == R_MICROMIPS_TLS_DTPREL_HI16
+	  || r_type == R_MICROMIPS_TLS_TPREL_HI16);
+}
+
 static inline bool
 mips16_call_reloc_p (int r_type)
 {
@@ -8278,14 +8289,44 @@ mips_elf_add_lo16_rel_addend (bfd *abfd,
   bfd_vma l;
 
   r_type = ELF_R_TYPE (abfd, rel->r_info);
-  if (mips16_reloc_p (r_type))
-    lo16_type = R_MIPS16_LO16;
-  else if (micromips_reloc_p (r_type))
-    lo16_type = R_MICROMIPS_LO16;
-  else if (r_type == R_MIPS_PCHI16)
-    lo16_type = R_MIPS_PCLO16;
-  else
-    lo16_type = R_MIPS_LO16;
+  switch (r_type)
+    {
+    case R_MIPS_HI16:
+    case R_MIPS_GOT16:
+      lo16_type = R_MIPS_LO16;
+      break;
+    case R_MIPS_PCHI16:
+      lo16_type = R_MIPS_PCLO16;
+      break;
+    case R_MIPS_TLS_DTPREL_HI16:
+      lo16_type = R_MIPS_TLS_DTPREL_LO16;
+      break;
+    case R_MIPS_TLS_TPREL_HI16:
+      lo16_type = R_MIPS_TLS_TPREL_LO16;
+      break;
+    case R_MIPS16_HI16:
+    case R_MIPS16_GOT16:
+      lo16_type = R_MIPS16_LO16;
+      break;
+    case R_MIPS16_TLS_DTPREL_HI16:
+      lo16_type = R_MIPS16_TLS_DTPREL_LO16;
+      break;
+    case R_MIPS16_TLS_TPREL_HI16:
+      lo16_type = R_MIPS16_TLS_TPREL_LO16;
+      break;
+    case R_MICROMIPS_HI16:
+    case R_MICROMIPS_GOT16:
+      lo16_type = R_MICROMIPS_LO16;
+      break;
+    case R_MICROMIPS_TLS_DTPREL_HI16:
+      lo16_type = R_MICROMIPS_TLS_DTPREL_LO16;
+      break;
+    case R_MICROMIPS_TLS_TPREL_HI16:
+      lo16_type = R_MICROMIPS_TLS_TPREL_LO16;
+      break;
+    default:
+      abort ();
+    }
 
   /* The combined value is the sum of the HI16 addend, left-shifted by
      sixteen bits, and the LO16 addend, sign extended.  (Usually, the
@@ -10507,7 +10548,8 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	      if (hi16_reloc_p (r_type)
 		  || (got16_reloc_p (r_type)
 		      && mips_elf_local_relocation_p (input_bfd, rel,
-						      local_sections)))
+						      local_sections))
+		  || tls_hi16_reloc_p (r_type))
 		{
 		  if (!mips_elf_add_lo16_rel_addend (input_bfd, input_section,
 						     rel, relend,
@@ -10545,7 +10587,9 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
 	  if (!rela_relocation_p && rel->r_addend)
 	    {
 	      addend += rel->r_addend;
-	      if (hi16_reloc_p (r_type) || got16_reloc_p (r_type))
+	      if (hi16_reloc_p (r_type)
+		  || got16_reloc_p (r_type)
+		  || tls_hi16_reloc_p (r_type))
 		addend = mips_elf_high (addend);
 	      else if (r_type == R_MIPS_HIGHER)
 		addend = mips_elf_higher (addend);

-- 
Alan Modra
Australia Development Lab, IBM

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

* Re: MIPS HI16 and LO16 reloc howtos
  2024-04-02  1:05 MIPS HI16 and LO16 reloc howtos Alan Modra
  2024-04-02  1:06 ` MIPS reloc howto special_function entries Alan Modra
@ 2024-04-02 11:19 ` Maciej W. Rozycki
  1 sibling, 0 replies; 5+ messages in thread
From: Maciej W. Rozycki @ 2024-04-02 11:19 UTC (permalink / raw)
  To: Alan Modra; +Cc: binutils, Chenghua Xu

On Tue, 2 Apr 2024, Alan Modra wrote:

> 	PR 19977
> 	* elf32-mips.c: Correct rightshift for HI16, HIGHER and HIGHEST
> 	reloc howtos.  Correct complain_on_overflow for LO16 relocs.
> 	* elf64-mips.c: Likewise.
> 	* elfn32-mips.c: Likewise.
> 
> OK?  This is a prerequisite to fixing PR19977.

 It does seem to me like a correct change to make, so OK.  Thank you for 
working on this issue.

 NB I pushed this through regression testing for additional safety and 
noticed numerous:

FAIL: gas/all/none

regressions.  As it happened there was one:

FAIL: Output file must be distinct from input

failure too and gas/testsuite/gas/all/none.s got replaced with ELF output:

$ file gas/testsuite/gas/all/none.s
gas/testsuite/gas/all/none.s: ELF 32-bit MSB relocatable, MIPS, MIPS-I version 1 (SYSV), not stripped

This comes from gas/testsuite/gas/all/gas.exp, where we have:

if { ![ishost "*-*-mingw*"] } then {
    gas_test_error "none.s" "-o $srcdir/$subdir/none.s" "Output file must be distinct from input"
}

which I think is an ill way to run a test, as it risks source corruption 
in the case of a failure, which is exactly what happened here.  I think a copy of the 
source file has to be made in the testsuite object directory and operated 
on instead.

 Why the failure happened is another matter; it seems intermittent and 
happened exactly once for a single varying target in all my test runs 
starting from Jul 29th, 2023, hmm...

  Maciej

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

end of thread, other threads:[~2024-04-02 11:19 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-04-02  1:05 MIPS HI16 and LO16 reloc howtos Alan Modra
2024-04-02  1:06 ` MIPS reloc howto special_function entries Alan Modra
2024-04-02  1:07   ` R_MIP16_GOT16 and R_MICROMIPS_GOT16 Alan Modra
2024-04-02  1:08     ` MIPS linker changes for TLS HI16/LO16 relocs Alan Modra
2024-04-02 11:19 ` MIPS HI16 and LO16 reloc howtos 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).