* ld.texinfo (Expression Section): Describe treatment of numbers
authorAlan Modra <amodra@gmail.com>
Mon, 20 Dec 2010 13:00:14 +0000 (13:00 +0000)
committerAlan Modra <amodra@gmail.com>
Mon, 20 Dec 2010 13:00:14 +0000 (13:00 +0000)
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.

19 files changed:
ld/ChangeLog
ld/emultempl/aix.em
ld/emultempl/armcoff.em
ld/emultempl/beos.em
ld/emultempl/elf32.em
ld/emultempl/genelf.em
ld/emultempl/lnk960.em
ld/emultempl/m68kcoff.em
ld/emultempl/mmo.em
ld/emultempl/pe.em
ld/emultempl/pep.em
ld/emultempl/sunos.em
ld/emultempl/z80.em
ld/ld.texinfo
ld/ldemul.c
ld/ldexp.c
ld/ldexp.h
ld/ldlang.c
ld/ldlang.h

index 13aa681c42e1204e587dd570661f7c440e2fa5c9..4e6f974659349e851f1f58c388113afb606be97d 100644 (file)
@@ -1,3 +1,22 @@
+2010-12-20  Alan Modra  <amodra@gmail.com>
+
+       * 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.
+
 2010-12-20  Alan Modra  <amodra@gmail.com>
 
        PR ld/12001
index 5ccb25cba542c7709cdf9cd0e53a5435fec7a03d..60c4fc651d3c0a2faee98845eebcf2c4aa50faf6 100644 (file)
@@ -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 b3cdde90acde4edb22977379a66af42cdf737a2e..20bff145c5e62a5648b4acbb24a4b38dfefc501c 100644 (file)
@@ -133,6 +133,8 @@ gld${EMULATION_NAME}_before_allocation (void)
 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 370dbacd0b3273d2180bd25c055ea17f30fbeba3..abd3979b38140654028485d3856efb1bbc5e75b1 100644 (file)
@@ -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 34cc82c72e9005216b01fbb567e865739dc9c865..9120f85b17cc90f6be3b0fa808292a2b64152d18 100644 (file)
@@ -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 62af4de8f80c40b74aaedfc330c6b8a2e4622b78..ce416eb66557517c825cdaeb4227a016dd07f451 100644 (file)
@@ -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 e13233c716eaf9363f3374a7b38b5448406367bd..7120329edae44a58b16cdd2d5c62b983af0ba4f0 100644 (file)
@@ -265,7 +265,7 @@ struct ld_emulation_xfer_struct ld_lnk960_emulation =
   lnk960_syslib,
   lnk960_hll,
   lnk960_after_parse,
-  NULL,                        /* after_open */
+  after_open_default,
   lnk960_after_allocation,
   lnk960_set_output_arch,
   lnk960_choose_target,
index 276c3b258aa0d6bf429d585fcaae900faf9c2753..b09a22320d07cf1ef9cb36e491ecde486a0f7c16 100644 (file)
@@ -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 d1a6f14617da37647c2c692203436b12d5c60671..9b18186aa7bc3ba505360a18ddafae2aa318ecbd 100644 (file)
@@ -151,6 +151,7 @@ mmo_after_open (void)
                   is->the_bfd);
        }
     }
+  after_open_default ();
 }
 EOF
 
index df0678ddf7323f48a5421d9ea7cebb966982dad5..b4d7a63671f5ebf5ab3533200d8d8f628105790c 100644 (file)
@@ -1219,6 +1219,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
 static void
 gld_${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
 #ifdef DLL_SUPPORT
   if (pe_dll_extra_pe_debug)
     {
index 4ab748993d22bb2cd78106810e77b298e03bf6a4..e4072962978508d109179972074fc3105c6720a5 100644 (file)
@@ -1151,6 +1151,8 @@ debug_section_p (bfd *abfd ATTRIBUTE_UNUSED, asection *sect, void *obj)
 static void
 gld_${EMULATION_NAME}_after_open (void)
 {
+  after_open_default ();
+
   is_underscoring ();
 #ifdef DLL_SUPPORT
   if (pep_dll_extra_pe_debug)
index 5c6c0a6a7ccd38b141a2160e619cd7b67e5c09ee..567b8e245052abe990db19863744b6d4711c2313 100644 (file)
@@ -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 100ebd0eb958dc0b2a11e412c0f6d59fa484cb95..eeb32138f35d1aeeba5b16240f92f7947cdb0647 100644 (file)
@@ -79,6 +79,8 @@ gldz80_after_open (void)
 {
   unsigned long mach_type;
 
+  after_open_default ();
+
   switch (result_mach_type)
     {
     case M_Z80STRICT:
index 6d36dfb63ddb60a8fd22779b2af028b9ba22b403..d4419aa5b503c1a42af2a43e68e237e779233aa9 100644 (file)
@@ -5503,17 +5503,17 @@ section relative symbols and for builtin functions that return an
 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}.
-
-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,
+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.
+
+In the following simple example,
 
 @smallexample
 @group
@@ -5537,9 +5537,8 @@ address 0x100 in the first two assignments, then both @code{.} and
 @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 f1f3979578a81bf4418219011b0221615cdbc0a5..3c07ceb364de46cfc22bed34c069e0d74aa777eb 100644 (file)
@@ -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 71b957c4a7211239341a1bab3bb174dc7e4623bd..326188424efeb60ebbb5d535c409325cef19453f 100644 (file)
@@ -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 ac73bd116794a3431a86424469d0c89412e468e7..31a06ac86b774d582b750382be05dea1e19bf69b 100644 (file)
@@ -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 6f4e200eb241789c252e647b0e3b52bc10a27594..097c39097b4c4a65077cd8ef0d74804cc367b97b 100644 (file)
@@ -109,6 +109,7 @@ bfd_boolean delete_output_file_on_failure = FALSE;
 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 15e558758e8125c82ec8ca74ebda31cb7f6f3a20..5850fcb31e64417961a0673d422ddba25c7e6338 100644 (file)
@@ -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;