This is the mail archive of the binutils-cvs@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] resolve_symbol_value vs. .loc view resolution


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

commit 1903f1385bff910861942743860d8577423bcb6c
Author: Alan Modra <amodra@gmail.com>
Date:   Wed Apr 24 11:26:51 2019 +0930

    resolve_symbol_value vs. .loc view resolution
    
    In most cases we don't want expression symbols, such as that created
    for an expression like "symbol + (1f - .)", resolved down to a
    constant.  Instead we'd like to leave the expression as "symbol +
    constant" once the "1f - ." part has been resolved, and let the
    backend decide whether "symbol" can be reduced further.
    
    However, that doesn't work when trying to resolve .loc view symbols
    early.  We get expression symbols left as an O_symbol expression
    pointing at an absolute symbol, and marked as sy_flags.sy_resolved.
    That wouldn't really be a problem, but when one of those expression
    symbols is used in further .loc view expressions, its value is taken
    as zero.
    
    This patch fixes the symbol value mistake, and stops creation of
    O_symbol expression symbols pointing to absolute symbols.  Either of
    these fixes would cure the .loc view usage.
    
    	PR 24444
    	* symbols.c (resolve_symbol_value): When handling symbols
    	marked as sy_flags.resolved, return correct value for the
    	case of expression symbols left as an O_symbol expression.
    	Merge O_symbol code handling undefined and common symbols with
    	code handling special cases of expression symbols.  Use
    	seg_left to test for undefined and common symbols.  Don't
    	leave an O_symbol expression when X_add_symbol resolves to
    	the absolute_section.  Init final_val later.
    	* testsuite/gas/mmix/basep-7.d: Adjust expected output.

Diff:
---
 gas/ChangeLog                    | 13 ++++++++++++
 gas/symbols.c                    | 43 ++++++++++++++++++----------------------
 gas/testsuite/gas/mmix/basep-7.d |  8 +++-----
 3 files changed, 35 insertions(+), 29 deletions(-)

diff --git a/gas/ChangeLog b/gas/ChangeLog
index 090df4b..eeabe0c 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,16 @@
+2019-04-24  Alan Modra  <amodra@gmail.com>
+
+	PR 24444
+	* symbols.c (resolve_symbol_value): When handling symbols
+	marked as sy_flags.resolved, return correct value for the
+	case of expression symbols left as an O_symbol expression.
+	Merge O_symbol code handling undefined and common symbols with
+	code handling special cases of expression symbols.  Use
+	seg_left to test for undefined and common symbols.  Don't
+	leave an O_symbol expression when X_add_symbol resolves to
+	the absolute_section.  Init final_val later.
+	* testsuite/gas/mmix/basep-7.d: Adjust expected output.
+
 2019-04-24  John Darrington <john@darrington.wattle.id.au>
 
 	* testsuite/gas/s12z/bit-manip-invalid.s: Extend test for BSET
diff --git a/gas/symbols.c b/gas/symbols.c
index d8a9c92..9786795 100644
--- a/gas/symbols.c
+++ b/gas/symbols.c
@@ -1221,7 +1221,7 @@ valueT
 resolve_symbol_value (symbolS *symp)
 {
   int resolved;
-  valueT final_val = 0;
+  valueT final_val;
   segT final_seg;
 
   if (LOCAL_SYMBOL_CHECK (symp))
@@ -1245,10 +1245,18 @@ resolve_symbol_value (symbolS *symp)
 
   if (symp->sy_flags.sy_resolved)
     {
+      final_val = 0;
+      while (symp->sy_value.X_op == O_symbol
+	     && symp->sy_value.X_add_symbol->sy_flags.sy_resolved)
+	{
+	  final_val += symp->sy_value.X_add_number;
+	  symp = symp->sy_value.X_add_symbol;
+	}
       if (symp->sy_value.X_op == O_constant)
-	return (valueT) symp->sy_value.X_add_number;
+	final_val += symp->sy_value.X_add_number;
       else
-	return 0;
+	final_val = 0;
+      return final_val;
     }
 
   resolved = 0;
@@ -1305,6 +1313,7 @@ resolve_symbol_value (symbolS *symp)
 	  resolved = 1;
 	}
 
+      final_val = 0;
       final_seg = undefined_section;
       goto exit_dont_set_value;
     }
@@ -1392,11 +1401,16 @@ resolve_symbol_value (symbolS *symp)
 	     relocation to detect this case, and convert the
 	     relocation to be against the symbol to which this symbol
 	     is equated.  */
-	  if (! S_IS_DEFINED (add_symbol)
+	  if (seg_left == undefined_section
+	      || bfd_is_com_section (seg_left)
 #if defined (OBJ_COFF) && defined (TE_PE)
 	      || S_IS_WEAK (add_symbol)
 #endif
-	      || S_IS_COMMON (add_symbol))
+	      || (finalize_syms
+		  && ((final_seg == expr_section
+		       && seg_left != expr_section
+		       && seg_left != absolute_section)
+		      || symbol_shadow_p (symp))))
 	    {
 	      if (finalize_syms)
 		{
@@ -1407,25 +1421,6 @@ resolve_symbol_value (symbolS *symp)
 		  symp->sy_value.X_op_symbol = add_symbol;
 		}
 	      final_seg = seg_left;
-	      final_val = 0;
-	      resolved = symbol_resolved_p (add_symbol);
-	      symp->sy_flags.sy_resolving = 0;
-	      goto exit_dont_set_value;
-	    }
-	  else if (finalize_syms
-		   && ((final_seg == expr_section && seg_left != expr_section)
-		       || symbol_shadow_p (symp)))
-	    {
-	      /* If the symbol is an expression symbol, do similarly
-		 as for undefined and common syms above.  Handles
-		 "sym +/- expr" where "expr" cannot be evaluated
-		 immediately, and we want relocations to be against
-		 "sym", eg. because it is weak.  */
-	      symp->sy_value.X_op = O_symbol;
-	      symp->sy_value.X_add_symbol = add_symbol;
-	      symp->sy_value.X_add_number = final_val;
-	      symp->sy_value.X_op_symbol = add_symbol;
-	      final_seg = seg_left;
 	      final_val += symp->sy_frag->fr_address + left;
 	      resolved = symbol_resolved_p (add_symbol);
 	      symp->sy_flags.sy_resolving = 0;
diff --git a/gas/testsuite/gas/mmix/basep-7.d b/gas/testsuite/gas/mmix/basep-7.d
index 0cd0a13..8aa7d00 100644
--- a/gas/testsuite/gas/mmix/basep-7.d
+++ b/gas/testsuite/gas/mmix/basep-7.d
@@ -3,8 +3,6 @@
 #objdump: -drt
 
 # The -linker-allocated-gregs option validates omissions of GREG.
-# Note the inconsequence in relocs regarding forward and backward
-# references (not specific to this functionality); they may change.
 
 .*:     file format elf64-mmix
 
@@ -27,8 +25,8 @@ Disassembly of section \.text:
    8:	23300000 	addu \$48,\$0,0
 			a: R_MMIX_BASE_PLUS_OFFSET	\*ABS\*\+0x86
    c:	8d2b0000 	ldo \$43,\$0,0
-			e: R_MMIX_BASE_PLUS_OFFSET	c\+0x2
+			e: R_MMIX_BASE_PLUS_OFFSET	\*ABS\*\+0x4a
   10:	232f0000 	addu \$47,\$0,0
-			12: R_MMIX_BASE_PLUS_OFFSET	d\+0xd4
+			12: R_MMIX_BASE_PLUS_OFFSET	\*ABS\*\+0xd7
   14:	23300000 	addu \$48,\$0,0
-			16: R_MMIX_BASE_PLUS_OFFSET	c\+0x15
+			16: R_MMIX_BASE_PLUS_OFFSET	\*ABS\*\+0x5d


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]