[binutils-gdb] RISC-V: Fixed missed GOT relocation against a symbol that has a defined value

Nelson Chu nelsonc1225@sourceware.org
Thu Sep 4 08:42:55 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=cea397848b868c62993864dbef684877bceef1fc

commit cea397848b868c62993864dbef684877bceef1fc
Author: Nelson Chu <nelson@rivosinc.com>
Date:   Thu Aug 14 12:01:38 2025 +0800

    RISC-V: Fixed missed GOT relocation against a symbol that has a defined value
    
    SImilar to aarch64, commit eac4eb8ecb26
    
    There are two problems when GOT relocation against a symbol that has a defined
    value,
    1. Pesudo la with pic and pseudo lga lost the relocations.
    2. %got_pcrel_hi generates R_RISCV_GOT_HI20 with addend, which is wrong since
       commit 50331d64f108.
    
    The solution is to use deferred_expression for GOT relocation.  Maybe other
    relocations also have same problem and need the deferred_expression, but we can
    add in the future patches.

Diff:
---
 gas/config/tc-riscv.c                 | 85 ++++++++++++++++++++---------------
 gas/testsuite/gas/riscv/force_reloc.d | 47 +++++++++++++++++++
 gas/testsuite/gas/riscv/force_reloc.s | 22 +++++++++
 3 files changed, 117 insertions(+), 37 deletions(-)

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index 8a3356888d2..df60c206b82 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -2518,13 +2518,16 @@ parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
 }
 
 static void
-my_getExpression (expressionS *ep, char *str)
+my_getExpression (expressionS *ep, char *str, bool defer)
 {
   char *save_in;
 
   save_in = input_line_pointer;
   input_line_pointer = str;
-  expression (ep);
+  if (defer)
+    deferred_expression (ep);
+  else
+    expression (ep);
   expr_parse_end = input_line_pointer;
   input_line_pointer = save_in;
 }
@@ -2543,6 +2546,7 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
   size_t reloc_index;
   unsigned crux_depth, str_depth;
   bool orig_probing = probing_insn_operands;
+  bool force_reloc = false;
   char *crux;
 
   /* Search for the start of the main expression.
@@ -2582,7 +2586,10 @@ my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
   if (str_depth || reloc_index)
     probing_insn_operands = false;
 
-  my_getExpression (ep, crux);
+  if (*reloc == BFD_RELOC_RISCV_GOT_HI20)
+    force_reloc = true;
+
+  my_getExpression (ep, crux, force_reloc);
   str = expr_parse_end;
 
   probing_insn_operands = orig_probing;
@@ -2674,7 +2681,7 @@ my_getVsetvliExpression (expressionS *ep, char *str)
     }
   else
     {
-      my_getExpression (ep, str);
+      my_getExpression (ep, str, false/* defer */);
       str = expr_parse_end;
     }
 }
@@ -2727,7 +2734,7 @@ my_getThVsetvliExpression (expressionS *ep, char *str)
     }
   else
     {
-      my_getExpression (ep, str);
+      my_getExpression (ep, str, false/* defer */);
       str = expr_parse_end;
     }
 }
@@ -2851,6 +2858,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
   error.missing_ext = NULL;
   /* Indicate we are assembling instruction with CSR.  */
   bool insn_with_csr = false;
+  bool force_reloc = false;
 
   /* Parse the name of the instruction.  Terminate the string if whitespace
      is found so that str_hash_find only sees the name part of the string.  */
@@ -3353,7 +3361,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  continue;
 
 		case 'i': /* vector arith signed immediate */
-		  my_getExpression (imm_expr, asarg);
+		  my_getExpression (imm_expr, asarg, force_reloc);
 		  check_absolute_expr (ip, imm_expr, FALSE);
 		  if (imm_expr->X_add_number > 15
 		      || imm_expr->X_add_number < -16)
@@ -3365,7 +3373,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  continue;
 
 		case 'j': /* vector arith unsigned immediate */
-		  my_getExpression (imm_expr, asarg);
+		  my_getExpression (imm_expr, asarg, force_reloc);
 		  check_absolute_expr (ip, imm_expr, FALSE);
 		  if (imm_expr->X_add_number < 0
 		      || imm_expr->X_add_number >= 32)
@@ -3377,7 +3385,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  continue;
 
 		case 'k': /* vector arith signed immediate, minus 1 */
-		  my_getExpression (imm_expr, asarg);
+		  my_getExpression (imm_expr, asarg, force_reloc);
 		  check_absolute_expr (ip, imm_expr, FALSE);
 		  if (imm_expr->X_add_number > 16
 		      || imm_expr->X_add_number < -15)
@@ -3389,7 +3397,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  continue;
 
 		case 'l': /* 6-bit vector arith unsigned immediate */
-		  my_getExpression (imm_expr, asarg);
+		  my_getExpression (imm_expr, asarg, force_reloc);
 		  check_absolute_expr (ip, imm_expr, FALSE);
 		  if (imm_expr->X_add_number < 0
 		      || imm_expr->X_add_number >= 64)
@@ -3453,7 +3461,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      break;
 
 	    case '<': /* Shift amount, 0 - 31.  */
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      check_absolute_expr (ip, imm_expr, false);
 	      if ((unsigned long) imm_expr->X_add_number > 31)
 		as_bad (_("improper shift amount (%"PRIu64")"),
@@ -3464,7 +3472,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      continue;
 
 	    case '>': /* Shift amount, 0 - (XLEN-1).  */
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      check_absolute_expr (ip, imm_expr, false);
 	      if ((unsigned long) imm_expr->X_add_number >= xlen)
 		as_bad (_("improper shift amount (%"PRIu64")"),
@@ -3475,7 +3483,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      continue;
 
 	    case 'Z': /* CSRRxI immediate.  */
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      check_absolute_expr (ip, imm_expr, false);
 	      if ((unsigned long) imm_expr->X_add_number > 31)
 		as_bad (_("improper CSRxI immediate (%"PRIu64")"),
@@ -3492,7 +3500,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		INSERT_OPERAND (CSR, *ip, regno);
 	      else
 		{
-		  my_getExpression (imm_expr, asarg);
+		  my_getExpression (imm_expr, asarg, force_reloc);
 		  check_absolute_expr (ip, imm_expr, true);
 		  if ((unsigned long) imm_expr->X_add_number > 0xfff)
 		    as_bad (_("improper CSR address (%"PRIu64")"),
@@ -3591,7 +3599,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      break;
 
 	    case 'I':
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      if (imm_expr->X_op != O_big
 		  && imm_expr->X_op != O_constant)
 		break;
@@ -3600,7 +3608,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      continue;
 
 	    case 'A':
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      normalize_constant_expr (imm_expr);
 	      /* The 'A' format specifier must be a symbol.  */
 	      if (imm_expr->X_op != O_symbol)
@@ -3610,7 +3618,10 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      continue;
 
 	    case 'B':
-	      my_getExpression (imm_expr, asarg);
+	      if (ip->insn_mo->mask == M_LGA
+		  || (riscv_opts.pic && ip->insn_mo->mask == M_LA))
+		force_reloc = true;
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      normalize_constant_expr (imm_expr);
 	      /* The 'B' format specifier must be a symbol or a constant.  */
 	      if (imm_expr->X_op != O_symbol && imm_expr->X_op != O_constant)
@@ -3662,7 +3673,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	    case 'p': /* PC-relative offset.  */
 	    branch:
 	      *imm_reloc = BFD_RELOC_12_PCREL;
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      asarg = expr_parse_end;
 	      continue;
 
@@ -3685,13 +3696,13 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 
 	    case 'a': /* 20-bit PC-relative offset.  */
 	    jump:
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      asarg = expr_parse_end;
 	      *imm_reloc = BFD_RELOC_RISCV_JMP;
 	      continue;
 
 	    case 'c':
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      asarg = expr_parse_end;
 	      if (strcmp (asarg, "@plt") == 0)
 		asarg += 4;
@@ -3792,7 +3803,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      break;
 
 	    case 'y': /* bs immediate */
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      check_absolute_expr (ip, imm_expr, FALSE);
 	      if ((unsigned long)imm_expr->X_add_number > 3)
 		as_bad(_("Improper bs immediate (%lu)"),
@@ -3803,7 +3814,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 	      continue;
 
 	    case 'Y': /* rnum immediate */
-	      my_getExpression (imm_expr, asarg);
+	      my_getExpression (imm_expr, asarg, force_reloc);
 	      check_absolute_expr (ip, imm_expr, FALSE);
 	      if ((unsigned long)imm_expr->X_add_number > 10)
 		as_bad(_("Improper rnum immediate (%lu)"),
@@ -3833,7 +3844,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			 pseudo S-type but lower 5-bits zero.  */
 		      if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
 			continue;
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, false);
 		      if (((unsigned) (imm_expr->X_add_number) & 0x1fU)
 			  || imm_expr->X_add_number >= RISCV_IMM_REACH / 2
@@ -4025,7 +4036,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			s = strtol (oparg + 1, (char **)&oparg, 10);
 			oparg--;
 
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, false);
 			if (!sign)
 			  {
@@ -4053,7 +4064,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  switch (*++oparg)
 		    {
 		      case '2':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number<0
@@ -4063,7 +4074,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_IS2_UIMM5 (imm_expr->X_add_number);
 			  continue;
 		      case '3':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number < 0
@@ -4073,7 +4084,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_IS3_UIMM5 (imm_expr->X_add_number);
 			continue;
 		      case '4':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number < -16
@@ -4083,7 +4094,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_IS2_UIMM5 (imm_expr->X_add_number);
 			continue;
 		      case '5':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number < -32
@@ -4093,7 +4104,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_SIMD_IMM6 (imm_expr->X_add_number);
 			continue;
 		      case '6':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number < 0
@@ -4103,7 +4114,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_BITMANIP_UIMM5 (imm_expr->X_add_number);
 			continue;
 		      case '7':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			if (imm_expr->X_add_number < 0
@@ -4113,7 +4124,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 			    |= ENCODE_CV_BITMANIP_UIMM2 (imm_expr->X_add_number);
 			continue;
 		      case '8':
-			my_getExpression (imm_expr, asarg);
+			my_getExpression (imm_expr, asarg, force_reloc);
 			check_absolute_expr (ip, imm_expr, FALSE);
 			asarg = expr_parse_end;
 			++oparg;
@@ -4194,7 +4205,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		  switch (*++oparg)
 		    {
 		    case '@': /* hint 0 - 31.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number > 31)
 			as_bad(_("Improper hint amount (%lu)"),
@@ -4205,7 +4216,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      continue;
 
 		    case '#': /* immediate 0 - 511.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number > 511)
 			as_bad(_("Improper immediate amount (%lu)"),
@@ -4216,7 +4227,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      continue;
 
 		    case '$': /* LDP offset 0 to (1<<7)-8.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
 			  || ((unsigned long)imm_expr->X_add_number & 0x7) != 0)
@@ -4229,7 +4240,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      continue;
 
 		    case '%': /* LWP offset 0 to (1<<7)-4.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
 			  || ((unsigned long)imm_expr->X_add_number & 0x3) != 0)
@@ -4242,7 +4253,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      continue;
 
 		    case '^': /* SDP offset 0 to (1<<7)-8.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
 			  || ((unsigned long)imm_expr->X_add_number & 0x7) != 0)
@@ -4257,7 +4268,7 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
 		      continue;
 
 		    case '&': /* SWP offset 0 to (1<<7)-4.  */
-		      my_getExpression (imm_expr, asarg);
+		      my_getExpression (imm_expr, asarg, force_reloc);
 		      check_absolute_expr (ip, imm_expr, FALSE);
 		      if ((unsigned long)imm_expr->X_add_number >= (1 << 7)
 			  || ((unsigned long)imm_expr->X_add_number & 0x3) != 0)
@@ -4613,7 +4624,7 @@ bool riscv_parse_name (const char *name, struct expressionS *ep,
   if (!probing_insn_operands)
     return false;
 
-  gas_assert (mode == expr_normal);
+  gas_assert (mode == expr_normal || expr_defer_p (mode));
 
   regno = reg_lookup_internal (name, RCLASS_GPR);
   if (regno == -1u)
diff --git a/gas/testsuite/gas/riscv/force_reloc.d b/gas/testsuite/gas/riscv/force_reloc.d
new file mode 100644
index 00000000000..df37a60d203
--- /dev/null
+++ b/gas/testsuite/gas/riscv/force_reloc.d
@@ -0,0 +1,47 @@
+#as:
+#objdump: -dr -Mnumeric,no-aliases
+
+.*:[ 	]+file format .*
+
+
+Disassembly of section .text:
+
+0+ <_start>:
+[ 	]+0:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x1,0x0
+[ 	]+0:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_before
+[ 	]+0:[ 	]+R_RISCV_RELAX.*
+[ 	]+4:[ 	]+[0-9a-f]+[ 	]+(lw|ld)[ 	]+x1,0\(x1\) # 0 .*
+[ 	]+4:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L0.*
+[ 	]+4:[ 	]+R_RISCV_RELAX.*
+[ 	]+8:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x2,0x0
+[ 	]+8:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_before
+[ 	]+8:[ 	]+R_RISCV_RELAX.*
+[ 	]+c:[ 	]+[0-9a-f]+[ 	]+(lw|ld)[ 	]+x2,0\(x2\) # 8 .*
+[ 	]+c:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L0.*
+[ 	]+c:[ 	]+R_RISCV_RELAX.*
+
+0+10 <.L1>:
+[ 	]+10:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x3,0x0
+[ 	]+10:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_before
+[ 	]+14:[ 	]+[0-9a-f]+[ 	]+addi[ 	]+x3,x3,0 # 10 .*
+[ 	]+14:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L1.*
+[ 	]+14:[ 	]+R_RISCV_RELAX.*
+[ 	]+18:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x4,0x0
+[ 	]+18:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_after
+[ 	]+18:[ 	]+R_RISCV_RELAX.*
+[ 	]+1c:[ 	]+[0-9a-f]+[ 	]+(lw|ld)[ 	]+x4,0\(x4\) # 18 .*
+[ 	]+1c:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L0.*
+[ 	]+1c:[ 	]+R_RISCV_RELAX.*
+[ 	]+20:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x5,0x0
+[ 	]+20:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_after
+[ 	]+20:[ 	]+R_RISCV_RELAX.*
+[ 	]+24:[ 	]+[0-9a-f]+[ 	]+(lw|ld)[ 	]+x5,0\(x5\) # 20 .*
+[ 	]+24:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L0.*
+[ 	]+24:[ 	]+R_RISCV_RELAX.*
+
+0+28 <.L2>:
+[ 	]+28:[ 	]+[0-9a-f]+[ 	]+auipc[ 	]+x6,0x0
+[ 	]+28:[ 	]+R_RISCV_GOT_HI20[ 	]+sym_abs_after
+[ 	]+2c:[ 	]+[0-9a-f]+[ 	]+addi[ 	]+x6,x6,0 # 28 .*
+[ 	]+2c:[ 	]+R_RISCV_PCREL_LO12_I[ 	]+.L2.*
+[ 	]+2c:[ 	]+R_RISCV_RELAX.*
diff --git a/gas/testsuite/gas/riscv/force_reloc.s b/gas/testsuite/gas/riscv/force_reloc.s
new file mode 100644
index 00000000000..787c419c182
--- /dev/null
+++ b/gas/testsuite/gas/riscv/force_reloc.s
@@ -0,0 +1,22 @@
+.option pic
+.option norvc
+
+.global sym_abs_before
+.set sym_abs_before, 42
+
+.text
+.global _start
+_start:
+# Need defer expression
+la  x1, sym_abs_before
+lga x2, sym_abs_before
+.L1: auipc x3, %got_pcrel_hi (sym_abs_before)
+     addi  x3, x3, %pcrel_lo (.L1)
+# This is fine
+la  x4, sym_abs_after
+lga x5, sym_abs_after
+.L2: auipc x6, %got_pcrel_hi (sym_abs_after)
+     addi  x6, x6, %pcrel_lo (.L2)
+
+.global sym_abs_after
+.set sym_abs_after, 42


More information about the Binutils-cvs mailing list