This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
DEFINED in link scripts
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sourceware dot org
- Date: Thu, 8 May 2008 00:02:01 +0930
- Subject: DEFINED in link scripts
A couple of weeks ago I happened to try an expression like
DEFINED (some_symbol) || . != 0
in a linker script, inside an output section. It failed to work as
expected, due to the curious way ld evaluates expressions. "." and
"0" are section relative values when inside an output section, and
". != 0" gives a section relative 0 or 1. However, DEFINED() always
gives an absolute value, and when evaluating the "||" ld first
converts the rhs to an absolute value. The section didn't start at
zero, so this effectively meant the rhs was always true. Converting
to absolute probably doesn't make that much sense for "||", but
changing that would require quite a lot of extra logic in
fold_binary. It's much simpler to just fix DEFINED() to return a
section relative value inside output sections.
I noticed that SEGMENT_START sets expld.result.section to NULL, which
could result in segfaults. Fixed by using expld.section instead.
Also, a number of tokens were missing from the expression print dump.
* ldexp.c (exp_print_token): Add ABSOLUTE, MIN_K, ASSERT_K. Correct
MAX_K.
(fold_binary <SEGMENT_START>): Set expld.result.section to
current section. Expand comment. Formatting.
(fold_name <DEFINED>): Set expld.result.section to current section.
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.73
diff -u -p -r1.73 ldexp.c
--- ld/ldexp.c 16 Feb 2008 00:06:02 -0000 1.73
+++ ld/ldexp.c 7 May 2008 04:41:38 -0000
@@ -103,7 +103,10 @@ exp_print_token (token_code_type code, i
{ ADDR, "ADDR" },
{ LOADADDR, "LOADADDR" },
{ CONSTANT, "CONSTANT" },
- { MAX_K, "MAX_K" },
+ { ABSOLUTE, "ABSOLUTE" },
+ { MAX_K, "MAX" },
+ { MIN_K, "MIN" },
+ { ASSERT_K, "ASSERT" },
{ REL, "relocatable" },
{ DATA_SEGMENT_ALIGN, "DATA_SEGMENT_ALIGN" },
{ DATA_SEGMENT_RELRO_END, "DATA_SEGMENT_RELRO_END" },
@@ -296,7 +299,7 @@ fold_binary (etree_type *tree)
seg->used = TRUE;
expld.result.value = seg->value;
expld.result.str = NULL;
- expld.result.section = NULL;
+ expld.result.section = expld.section;
break;
}
}
@@ -321,9 +324,9 @@ fold_binary (etree_type *tree)
return;
}
else if (expld.section != bfd_abs_section_ptr
- && expld.result.section == bfd_abs_section_ptr
- && (tree->type.node_code == '+'
- || tree->type.node_code == '-'))
+ && expld.result.section == bfd_abs_section_ptr
+ && (tree->type.node_code == '+'
+ || tree->type.node_code == '-'))
{
/* Keep the section of the lhs term. */
expld.result.section = lhs.section;
@@ -513,7 +516,7 @@ fold_name (etree_type *tree)
|| h->type == bfd_link_hash_common)
&& (def_iteration == lang_statement_iteration
|| def_iteration == -1));
- expld.result.section = bfd_abs_section_ptr;
+ expld.result.section = expld.section;
expld.result.valid_p = TRUE;
}
break;
--
Alan Modra
Australia Development Lab, IBM