This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Relative expressions and ASSERT
On Fri, Dec 17, 2010 at 11:41:40AM -0800, H.J. Lu wrote:
> The updated patch with a new testcase.
I think this is a better solution, works on current binutils testsuite,
the testcases in PR12066, and on kernel builds I tried. You can
even describe linker behaviour without too much embarassment.
I added an option to allow people to experiment with a consistent
linker expression resolver by setting
__ld_compatibility = 221 ;
somewhere in their linker scripts. This treats numbers and absolute
symbols as numbers everywhere, the most flexible arrangement since
you can force a number to be an absolute address by using ABSOLUTE(),
but you can't do the reverse.
* ld.texinfo (Expression Section): Describe treatment of numbers
and absolute symbols.
* ldemul.c (after_open_default): Look up __ld_compatibility.
* ldexp.c (fold_name): Convert absolute symbols to numbers when
inside output section definitions, or when __ld_compatibility >= 221.
(exp_fold_tree_1): Convert numbers to absolute when not in output
section definition and __ld_compatibility < 221. Don't always
convert values outside an output section definition to absolute.
* ldexp.h (uses_defined): Comment.
* ldlang.c (ld_compatibility): New variable.
* ldlang.h (ld_compatibility): Declare.
* emultempl/aix.em, * emultempl/armcoff.em, * emultempl/beos.em,
* emultempl/elf32.em, * emultempl/genelf.em, * emultempl/lnk960.em,
* emultempl/m68kcoff.em, * emultempl/mmo.em, * emultempl/pe.em,
* emultempl/pep.em, * emultempl/sunos.em, * emultempl/z80.em: Call
after_open_default from after_open function.
Index: ld/ld.texinfo
===================================================================
RCS file: /cvs/src/src/ld/ld.texinfo,v
retrieving revision 1.268
diff -u -p -r1.268 ld.texinfo
--- ld/ld.texinfo 15 Dec 2010 14:56:37 -0000 1.268
+++ ld/ld.texinfo 20 Dec 2010 06:35:30 -0000
@@ -5503,17 +5503,17 @@ section relative symbols and for builtin
address, such as @code{ADDR}, @code{LOADADDR}, @code{ORIGIN} and
@code{SEGMENT_START}. Other terms are simply numbers, or are builtin
functions that return a non-address value, such as @code{LENGTH}.
+One complication is that unless you assign @code{__ld_compatibility}
+a value of 221 or larger, numbers and absolute symbols are treated
+differently depending on their location, for compatibility with older
+versions of @code{ld}. Expressions appearing outside an output
+section definition treat all numbers as absolute addresses.
+Expressions appearing inside an output section definition treat
+absolute symbols as numbers. If @code{__ld_compatibility} is assigned
+a value larger than 221, then absolute symbols and numbers are simply
+treated as numbers everywhere.
-When the linker evaluates an expression, the result depends on where
-the expression is located in a linker script. Expressions appearing
-outside an output section definitions are evaluated with all terms
-first being converted to absolute addresses before applying operators,
-and evaluate to an absolute address result. Expressions appearing
-inside an output section definition are evaluated with more complex
-rules, but the aim is to treat terms as relative addresses and produce
-a relative address result. In particular, an assignment of a number
-to a symbol results in a symbol relative to the output section with an
-offset given by the number. So, in the following simple example,
+In the following simple example,
@smallexample
@group
@@ -5537,9 +5537,8 @@ address 0x100 in the first two assignmen
@code{__data_start} are set to 0x10 relative to the @code{.data}
section in the second two assignments.
-For expressions appearing inside an output section definition
-involving numbers, relative addresses and absolute addresses, ld
-follows these rules to evaluate terms:
+For expressions involving numbers, relative addresses and absolute
+addresses, ld follows these rules to evaluate terms:
@itemize @bullet
@item
Index: ld/ldemul.c
===================================================================
RCS file: /cvs/src/src/ld/ldemul.c,v
retrieving revision 1.34
diff -u -p -r1.34 ldemul.c
--- ld/ldemul.c 28 Oct 2010 06:45:33 -0000 1.34
+++ ld/ldemul.c 20 Dec 2010 06:35:30 -0000
@@ -226,6 +226,16 @@ after_parse_default (void)
void
after_open_default (void)
{
+ struct bfd_link_hash_entry *h;
+
+ h = bfd_wrapped_link_hash_lookup (link_info.output_bfd,
+ &link_info,
+ "__ld_compatibility",
+ FALSE, FALSE, TRUE);
+ if (h != NULL
+ && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ ld_compatibility = h->u.def.value;
}
void
Index: ld/ldexp.c
===================================================================
RCS file: /cvs/src/src/ld/ldexp.c,v
retrieving revision 1.88
diff -u -p -r1.88 ldexp.c
--- ld/ldexp.c 20 Dec 2010 06:27:10 -0000 1.88
+++ ld/ldexp.c 20 Dec 2010 06:35:31 -0000
@@ -553,7 +553,9 @@ fold_name (etree_type *tree)
" referenced in expression\n"),
tree->name.name);
}
- else if (output_section == bfd_abs_section_ptr)
+ else if (output_section == bfd_abs_section_ptr
+ && (expld.section != bfd_abs_section_ptr
+ || ld_compatibility >= 221))
new_number (h->u.def.value + h->u.def.section->output_offset);
else
new_rel (h->u.def.value + h->u.def.section->output_offset,
@@ -700,7 +702,11 @@ exp_fold_tree_1 (etree_type *tree)
switch (tree->type.node_class)
{
case etree_value:
- new_number (tree->value.value);
+ if (expld.section == bfd_abs_section_ptr
+ && ld_compatibility < 221)
+ new_abs (tree->value.value);
+ else
+ new_number (tree->value.value);
expld.result.str = tree->value.str;
break;
@@ -860,12 +866,6 @@ exp_fold_tree_1 (etree_type *tree)
memset (&expld.result, 0, sizeof (expld.result));
break;
}
-
- /* Any value not inside an output section statement is an
- absolute value. */
- if (expld.result.valid_p
- && expld.section == bfd_abs_section_ptr)
- make_abs ();
}
void
Index: ld/ldexp.h
===================================================================
RCS file: /cvs/src/src/ld/ldexp.h,v
retrieving revision 1.24
diff -u -p -r1.24 ldexp.h
--- ld/ldexp.h 20 Dec 2010 06:27:10 -0000 1.24
+++ ld/ldexp.h 20 Dec 2010 06:35:31 -0000
@@ -127,6 +127,7 @@ struct ldexp_control {
/* Working results. */
etree_value_type result;
bfd_vma dot;
+ /* Set if an expression contains DEFINED(). */
bfd_boolean uses_defined;
/* Current dot and section passed to ldexp folder. */
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.354
diff -u -p -r1.354 ldlang.c
--- ld/ldlang.c 20 Dec 2010 06:27:10 -0000 1.354
+++ ld/ldlang.c 20 Dec 2010 06:35:34 -0000
@@ -109,6 +109,7 @@ bfd_boolean delete_output_file_on_failur
struct lang_phdr *lang_phdr_list;
struct lang_nocrossrefs *nocrossref_list;
bfd_boolean missing_file = FALSE;
+int ld_compatibility;
/* Functions that traverse the linker script and might evaluate
DEFINED() need to increment this. */
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.92
diff -u -p -r1.92 ldlang.h
--- ld/ldlang.h 6 Dec 2010 00:07:06 -0000 1.92
+++ ld/ldlang.h 20 Dec 2010 06:35:34 -0000
@@ -469,6 +469,7 @@ extern bfd_boolean entry_from_cmdline;
extern lang_statement_list_type file_chain;
extern lang_statement_list_type input_file_chain;
+extern int ld_compatibility;
extern int lang_statement_iteration;
extern bfd_boolean missing_file;
Index: ld/emultempl/aix.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/aix.em,v
retrieving revision 1.56
diff -u -p -r1.56 aix.em
--- ld/emultempl/aix.em 6 Dec 2010 00:07:06 -0000 1.56
+++ ld/emultempl/aix.em 20 Dec 2010 06:35:35 -0000
@@ -608,6 +608,8 @@ gld${EMULATION_NAME}_after_open (void)
bfd_boolean r;
struct set_info *p;
+ after_open_default ();
+
/* Call ldctor_build_sets, after pretending that this is a
relocatable link. We do this because AIX requires relocation
entries for all references to symbols, even in a final
Index: ld/emultempl/armcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/armcoff.em,v
retrieving revision 1.31
diff -u -p -r1.31 armcoff.em
--- ld/emultempl/armcoff.em 2 Sep 2009 07:25:35 -0000 1.31
+++ ld/emultempl/armcoff.em 20 Dec 2010 06:35:35 -0000
@@ -133,6 +133,8 @@ gld${EMULATION_NAME}_before_allocation (
static void
gld${EMULATION_NAME}_after_open (void)
{
+ after_open_default ();
+
if (strstr (bfd_get_target (link_info.output_bfd), "arm") == NULL)
{
/* The arm backend needs special fields in the output hash structure.
Index: ld/emultempl/beos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/beos.em,v
retrieving revision 1.44
diff -u -p -r1.44 beos.em
--- ld/emultempl/beos.em 16 Feb 2009 07:25:52 -0000 1.44
+++ ld/emultempl/beos.em 20 Dec 2010 06:35:36 -0000
@@ -376,6 +376,8 @@ gld_${EMULATION_NAME}_set_symbols (void)
static void
gld_${EMULATION_NAME}_after_open (void)
{
+ after_open_default ();
+
/* Pass the wacky PE command line options into the output bfd.
FIXME: This should be done via a function, rather than by
including an internal BFD header. */
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.215
diff -u -p -r1.215 elf32.em
--- ld/emultempl/elf32.em 6 Dec 2010 00:07:06 -0000 1.215
+++ ld/emultempl/elf32.em 20 Dec 2010 06:35:37 -0000
@@ -1059,6 +1059,8 @@ gld${EMULATION_NAME}_after_open (void)
struct bfd_link_needed_list *needed, *l;
struct elf_link_hash_table *htab;
+ after_open_default ();
+
htab = elf_hash_table (&link_info);
if (!is_elf_hash_table (htab))
return;
Index: ld/emultempl/genelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/genelf.em,v
retrieving revision 1.7
diff -u -p -r1.7 genelf.em
--- ld/emultempl/genelf.em 19 Feb 2010 01:47:14 -0000 1.7
+++ ld/emultempl/genelf.em 20 Dec 2010 06:35:37 -0000
@@ -35,6 +35,8 @@ gld${EMULATION_NAME}_after_open (void)
asection *sec;
asymbol **syms;
+ after_open_default ();
+
if (link_info.relocatable)
for (ibfd = link_info.input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
if ((syms = bfd_get_outsymbols (ibfd)) != NULL
Index: ld/emultempl/lnk960.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/lnk960.em,v
retrieving revision 1.25
diff -u -p -r1.25 lnk960.em
--- ld/emultempl/lnk960.em 15 Feb 2008 03:35:53 -0000 1.25
+++ ld/emultempl/lnk960.em 20 Dec 2010 06:35:37 -0000
@@ -265,7 +265,7 @@ struct ld_emulation_xfer_struct ld_lnk96
lnk960_syslib,
lnk960_hll,
lnk960_after_parse,
- NULL, /* after_open */
+ after_open_default,
lnk960_after_allocation,
lnk960_set_output_arch,
lnk960_choose_target,
Index: ld/emultempl/m68kcoff.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/m68kcoff.em,v
retrieving revision 1.20
diff -u -p -r1.20 m68kcoff.em
--- ld/emultempl/m68kcoff.em 7 Jul 2008 00:46:51 -0000 1.20
+++ ld/emultempl/m68kcoff.em 20 Dec 2010 06:35:37 -0000
@@ -62,6 +62,8 @@ gld${EMULATION_NAME}_after_open (void)
{
bfd *abfd;
+ after_open_default ();
+
if (! command_line.embedded_relocs
|| link_info.relocatable)
return;
Index: ld/emultempl/mmo.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/mmo.em,v
retrieving revision 1.26
diff -u -p -r1.26 mmo.em
--- ld/emultempl/mmo.em 2 Sep 2009 07:25:35 -0000 1.26
+++ ld/emultempl/mmo.em 20 Dec 2010 06:35:37 -0000
@@ -151,6 +151,7 @@ mmo_after_open (void)
is->the_bfd);
}
}
+ after_open_default ();
}
EOF
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.164
diff -u -p -r1.164 pe.em
--- ld/emultempl/pe.em 6 Dec 2010 00:07:06 -0000 1.164
+++ ld/emultempl/pe.em 20 Dec 2010 06:35:38 -0000
@@ -1219,6 +1219,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNU
static void
gld_${EMULATION_NAME}_after_open (void)
{
+ after_open_default ();
+
#ifdef DLL_SUPPORT
if (pe_dll_extra_pe_debug)
{
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.40
diff -u -p -r1.40 pep.em
--- ld/emultempl/pep.em 6 Dec 2010 00:07:06 -0000 1.40
+++ ld/emultempl/pep.em 20 Dec 2010 06:35:39 -0000
@@ -1151,6 +1151,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNU
static void
gld_${EMULATION_NAME}_after_open (void)
{
+ after_open_default ();
+
is_underscoring ();
#ifdef DLL_SUPPORT
if (pep_dll_extra_pe_debug)
Index: ld/emultempl/sunos.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/sunos.em,v
retrieving revision 1.32
diff -u -p -r1.32 sunos.em
--- ld/emultempl/sunos.em 6 Dec 2010 00:07:06 -0000 1.32
+++ ld/emultempl/sunos.em 20 Dec 2010 06:35:40 -0000
@@ -366,6 +366,8 @@ gld${EMULATION_NAME}_after_open (void)
{
struct bfd_link_needed_list *needed, *l;
+ after_open_default ();
+
/* We only need to worry about this when doing a final link. */
if (link_info.relocatable || link_info.shared)
return;
Index: ld/emultempl/z80.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/z80.em,v
retrieving revision 1.5
diff -u -p -r1.5 z80.em
--- ld/emultempl/z80.em 2 Sep 2009 07:25:35 -0000 1.5
+++ ld/emultempl/z80.em 20 Dec 2010 06:35:40 -0000
@@ -79,6 +79,8 @@ gldz80_after_open (void)
{
unsigned long mach_type;
+ after_open_default ();
+
switch (result_mach_type)
{
case M_Z80STRICT:
--
Alan Modra
Australia Development Lab, IBM