This is the mail archive of the binutils@sources.redhat.com 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]

Better diagnostics for undefined symbols in assignments to dot


Currently, if you write a linker script which assigns dot to an
expression involving a symbol, and that symbol is undefined, you get
the not-terribly-helpful diagnostic "invalid assignment to location
counter".  For instance:

$ cat test.ld
SECTIONS
{
  .text : { *(.text) }
  . = ALIGN(__data_align);
  .data : { *(.data) }
}
$ cat test.c
int x = 23;
int foo(void) { return x; }
$ gcc -c test.c

# intended use
$ ./ld-new --defsym __data_align=32 --script test.ld test.o -o test.x; echo $?
0

# mistaken use
$ ./ld-new --script test.ld test.o -o test.x; echo $?
test.ld:7: invalid assignment to location counter
1

The problem appears to be that fold_name only issues a diagnostic for
an undefined symbol if allocation_done is lang_final_phase_enum, but
the assignment to dot happens earlier than that.

Experimentally, I tried forcing allocation_done to
lang_final_phase_enum for the recursive call to exp_fold_tree to
process the right-hand side of the assignment expression.  This gets
me a nicer diagnostic:

$ ./ld-new --script test.ld test.o -o test.x; echo $?
test.ld:7: undefined symbol `__data_align' referenced in expression
1

but it also seems to break the i386 TLS tests.  Would anyone have any
ideas?  My patch is appended below for reference.

zw

        * ldexp.c (exp_fold_tree <case etree_assign>): For assignments
        to the location counter, force allocation_done to
        lang_final_phase_enum for better diagnostics.

===================================================================
Index: ld/ldexp.c
--- ld/ldexp.c	21 Jan 2005 04:15:58 -0000	1.42
+++ ld/ldexp.c	8 Feb 2005 20:53:14 -0000
@@ -754,9 +754,13 @@ exp_fold_tree (etree_type *tree,
 	      || (allocation_done == lang_final_phase_enum
 		  && current_section == abs_output_section))
 	    {
+	      /* Fold the source expression with allocation_done
+		 forced to lang_final_phase_enum in order to get a
+		 better diagnostic if the expression involves an
+		 undefined symbol.  */
 	      result = exp_fold_tree (tree->assign.src,
 				      current_section,
-				      allocation_done, dot,
+				      lang_final_phase_enum, dot,
 				      dotp);
 	      if (! result.valid_p)
 		einfo (_("%F%S invalid assignment to location counter\n"));


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