This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Better diagnostics for undefined symbols in assignments to dot
- From: Zack Weinberg <zack at codesourcery dot com>
- To: Binutils Mailing List <binutils at sources dot redhat dot com>
- Date: Tue, 08 Feb 2005 12:55:40 -0800
- Subject: 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"));