This is the mail archive of the binutils@sourceware.org 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]

[PATCH v2 1/2] LD: Export relative-from-absolute symbol marking to BFD


It is usually possible to tell absolute and ordinary symbols apart in
BFD throughout the link, by checking whether the section that owns the 
symbol is absolute or not.

That however does not work for ordinary symbols defined in a linker 
script outside an output section statement.  Initially such symbols are 
entered into to the link hash as absolute symbols, owned by the absolute 
section.  A flag is set in the internal linker expression defining such 
symbols to tell the linker to convert them to section-relative ones in 
the final phase of the link.  That flag is however not accessible to BFD 
linker code, including BFD target code in particular.

Add a flag to the link hash then to copy the information held in the 
linker expression.  Define a macro, `bfd_is_abs_symbol', for BFD code to 
use where determining whether a symbol is absolute or ordinary is 
required before the final link phase.

This macro will correctly identify the special `__ehdr_start' symbol as 
ordinary throughout link, for example, even though early on it will be 
assigned to the absolute section.  Of course this does not let BFD code 
identify what the symbol's ultimate section will be before the final 
link phase has converted this symbol (in `update_definedness').

	include/
	* bfdlink.h (bfd_link_hash_entry): Add `rel_from_abs' member.

	bfd/
	* linker.c (bfd_is_abs_symbol): New macro.
	* bfd-in2.h: Regenerate.

	ld/
	* ldexp.c (exp_fold_tree_1) <etree_assign, etree_provide>
	<etree_provided>: Copy expression's `rel_from_abs' flag to the
	link hash.
---
Hi,

 I realised we need to check for `bfd_link_hash_defweak' in the context of
`bfd_is_abs_symbol' regardless of whether `->rel_from_abs' can be set for 
defweaks or not, because the macro still needs to correctly classify such 
symbols.

 Also I have decided that the checks for the symbol type are best made in 
the macro after all.  It's not because it does or does not replace 
`bfd_is_abs_section' in some places, but because that's what the name of 
the macro and the semantics I intended to imply: to check whether a symbol 
is absolute or not.

 I think it will be most natural to implementers if this macro is 
self-contained like this and then it's up to the compiler to optimise away 
any conditional that turns out duplicate, following the principle, which I 
believe we have been following, of not making people's life harder for the 
sake of making the compiler's task easier.

 Please let me know if you disagree.

  Maciej

Changes from v1:

- also check for the symbol type being `bfd_link_hash_defweak' in 
  `bfd_is_abs_symbol'.
---
 bfd/bfd-in2.h     |   11 +++++++++++
 bfd/linker.c      |   15 ++++++++++++++-
 include/bfdlink.h |    5 +++++
 ld/ldexp.c        |    1 +
 4 files changed, 31 insertions(+), 1 deletion(-)

binutils-ld-rel-from-abs.diff
Index: binutils/bfd/bfd-in2.h
===================================================================
--- binutils.orig/bfd/bfd-in2.h	2018-07-16 20:55:31.268874684 +0100
+++ binutils/bfd/bfd-in2.h	2018-07-16 23:19:00.956418427 +0100
@@ -7802,6 +7802,17 @@ bfd_boolean bfd_set_format (bfd *abfd, b
 const char *bfd_format_string (bfd_format format);
 
 /* Extracted from linker.c.  */
+/* Return TRUE if the symbol described by a linker hash entry H
+   is going to be absolute.  Linker-script defined symbols can be
+   converted from absolute to section-relative ones late in the
+   link.  Use this macro to correctly determine whether the symbol
+   will actually end up absolute in output.  */
+#define bfd_is_abs_symbol(H) \
+  (((H)->type == bfd_link_hash_defined \
+    || (H)->type == bfd_link_hash_defweak) \
+   && bfd_is_abs_section ((H)->u.def.section) \
+   && !(H)->rel_from_abs)
+
 bfd_boolean bfd_link_split_section (bfd *abfd, asection *sec);
 
 #define bfd_link_split_section(abfd, sec) \
Index: binutils/bfd/linker.c
===================================================================
--- binutils.orig/bfd/linker.c	2018-07-16 20:55:31.280051567 +0100
+++ binutils/bfd/linker.c	2018-07-16 23:18:53.950833138 +0100
@@ -484,7 +484,20 @@ _bfd_link_hash_table_init
 
 /* Look up a symbol in a link hash table.  If follow is TRUE, we
    follow bfd_link_hash_indirect and bfd_link_hash_warning links to
-   the real symbol.  */
+   the real symbol.
+
+.{* Return TRUE if the symbol described by a linker hash entry H
+.   is going to be absolute.  Linker-script defined symbols can be
+.   converted from absolute to section-relative ones late in the
+.   link.  Use this macro to correctly determine whether the symbol
+.   will actually end up absolute in output.  *}
+.#define bfd_is_abs_symbol(H) \
+.  (((H)->type == bfd_link_hash_defined \
+.    || (H)->type == bfd_link_hash_defweak) \
+.   && bfd_is_abs_section ((H)->u.def.section) \
+.   && !(H)->rel_from_abs)
+.
+*/
 
 struct bfd_link_hash_entry *
 bfd_link_hash_lookup (struct bfd_link_hash_table *table,
Index: binutils/include/bfdlink.h
===================================================================
--- binutils.orig/include/bfdlink.h	2018-07-16 20:55:31.301561594 +0100
+++ binutils/include/bfdlink.h	2018-07-16 20:55:53.369147968 +0100
@@ -115,6 +115,11 @@ struct bfd_link_hash_entry
   /* Symbol defined in a linker script.  */
   unsigned int ldscript_def : 1;
 
+  /* Symbol will be converted from absolute to section-relative.  Set for
+     symbols defined by a script from "dot" (also SEGMENT_START or ORIGIN)
+     outside of an output section statement.  */
+  unsigned int rel_from_abs : 1;
+
   /* A union of information depending upon the type.  */
   union
     {
Index: binutils/ld/ldexp.c
===================================================================
--- binutils.orig/ld/ldexp.c	2018-07-16 20:55:31.330052651 +0100
+++ binutils/ld/ldexp.c	2018-07-16 20:55:53.409391670 +0100
@@ -1200,6 +1200,7 @@ exp_fold_tree_1 (etree_type *tree)
 		  h->u.def.section = expld.result.section;
 		  h->linker_def = ! tree->assign.type.lineno;
 		  h->ldscript_def = 1;
+		  h->rel_from_abs = expld.rel_from_abs;
 		  if (tree->assign.hidden)
 		    bfd_link_hide_symbol (link_info.output_bfd,
 					  &link_info, h);


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