This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: Fix alpha relocation overflow (Re: PATCH: Add _bfd_elf_provide_symbol)
- From: "H. J. Lu" <hjl at lucon dot org>
- To: Michael Matz <matz at suse dot de>, binutils at sources dot redhat dot com
- Date: Tue, 3 May 2005 14:24:50 -0700
- Subject: Re: PATCH: Fix alpha relocation overflow (Re: PATCH: Add _bfd_elf_provide_symbol)
- References: <20050425145458.GA32362@lucon.org> <Pine.LNX.4.58.0504251703020.20714@wotan.suse.de> <20050425172736.GA2235@lucon.org> <20050425174359.GA2592@lucon.org> <Pine.LNX.4.58.0504261359040.20714@wotan.suse.de> <20050426134659.GB20029@lucon.org> <20050427181840.GA12815@lucon.org> <20050503012716.GN9133@bubble.grove.modra.org> <20050503013528.GA1671@lucon.org> <20050503053107.GP9133@bubble.grove.modra.org>
On Tue, May 03, 2005 at 03:01:08PM +0930, Alan Modra wrote:
> On Mon, May 02, 2005 at 06:35:28PM -0700, H. J. Lu wrote:
> > > I think this is a rather horrible hack. Can't you do this some way that
> > > avoids the potentially slow section list traversal? How about defining
> > > __init_fini_array in the linker script, and using its value instead?
> > > (Default to zero if __init_fini_array isn't defined.)
> >
> > That function is used to avoid __init_fini_array in the linker script.
>
> No, it's to avoid a symbol defined inside an output section. I'm
> suggesting a symbol defined like
>
> __init_fini_array = .;
> .preinit_array ${RELOCATING-0} : { KEEP (*(.preinit_array)) }
> .init_array ${RELOCATING-0} : { KEEP (*(.init_array)) }
> .fini_array ${RELOCATING-0} : { KEEP (*(.fini_array)) }
>
How about this patch?
H.J.
----
bfd/
2005-05-03 H.J. Lu <hongjiu.lu@intel.com>
* bfd-in.h (_bfd_elf_provide_section_bound_symbols): New.
* bfd-in2.h: Regenerated.
* elflink.c (bfd_elf_set_symbol): New.
(_bfd_elf_provide_symbol): Call it.
(_bfd_elf_provide_section_bound_symbols): New.
ld/
2005-05-03 H.J. Lu <hongjiu.lu@intel.com>
* emultempl/elf32.em (gld${EMULATION_NAME}_provide_bound_symbols):
Call _bfd_elf_provide_section_bound_symbols.
--- binutils/bfd/bfd-in.h.pp 2005-05-03 14:10:31.000000000 -0700
+++ binutils/bfd/bfd-in.h 2005-05-03 14:16:21.000000000 -0700
@@ -697,6 +697,9 @@ extern struct bfd_section *_bfd_elf_tls_
extern void _bfd_elf_provide_symbol
(struct bfd_link_info *, const char *, bfd_vma);
+extern void _bfd_elf_provide_section_bound_symbols
+ (struct bfd_link_info *, struct bfd_section *sec, const char *, const char *);
+
extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
(bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
--- binutils/bfd/elflink.c.pp 2005-05-03 14:19:55.000000000 -0700
+++ binutils/bfd/elflink.c 2005-05-03 14:15:40.000000000 -0700
@@ -9913,6 +9913,18 @@ _bfd_elf_section_already_linked (bfd *ab
bfd_section_already_linked_table_insert (already_linked_list, sec);
}
+static void
+bfd_elf_set_symbol (struct elf_link_hash_entry *h, bfd_vma val)
+{
+ h->root.type = bfd_link_hash_defined;
+ h->root.u.def.section = bfd_abs_section_ptr;
+ h->root.u.def.value = val;
+ h->def_regular = 1;
+ h->type = STT_OBJECT;
+ h->other = STV_HIDDEN | (h->other & ~ ELF_ST_VISIBILITY (-1));
+ h->forced_local = 1;
+}
+
/* Set NAME to VAL if the symbol exists and is undefined. */
void
@@ -9925,13 +9937,58 @@ _bfd_elf_provide_symbol (struct bfd_link
FALSE);
if (h != NULL && (h->root.type == bfd_link_hash_undefined
|| h->root.type == bfd_link_hash_undefweak))
+ bfd_elf_set_symbol (h, val);
+}
+
+/* Set START and END to boundaries of SEC if they exist and are
+ undefined. */
+
+void
+_bfd_elf_provide_section_bound_symbols (struct bfd_link_info *info,
+ asection *sec,
+ const char *start,
+ const char *end)
+{
+ struct elf_link_hash_entry *hs, *he;
+ bfd_vma start_val, end_val;
+ bfd_boolean do_start, do_end;
+
+ /* Check if we need them or not first. */
+ hs = elf_link_hash_lookup (elf_hash_table (info), start, FALSE,
+ FALSE, FALSE);
+ do_start = (hs != NULL
+ && (hs->root.type == bfd_link_hash_undefined
+ || hs->root.type == bfd_link_hash_undefweak));
+
+ he = elf_link_hash_lookup (elf_hash_table (info), end, FALSE,
+ FALSE, FALSE);
+ do_end = (he != NULL
+ && (he->root.type == bfd_link_hash_undefined
+ || he->root.type == bfd_link_hash_undefweak));
+
+ if (!do_start && !do_end)
+ return;
+
+ if (sec != NULL)
{
- h->root.type = bfd_link_hash_defined;
- h->root.u.def.section = bfd_abs_section_ptr;
- h->root.u.def.value = val;
- h->def_regular = 1;
- h->type = STT_OBJECT;
- h->other = STV_HIDDEN | (h->other & ~ ELF_ST_VISIBILITY (-1));
- h->forced_local = 1;
+ start_val = sec->vma;
+ end_val = start_val + sec->size;
}
+ else
+ {
+ /* We have to choose those values very carefully. Some targets,
+ like alpha, may have relocation overflow with 0. "_edata"
+ should be defined in all cases. */
+ struct elf_link_hash_entry *h
+ = elf_link_hash_lookup (elf_hash_table (info), "_edata",
+ FALSE, FALSE, FALSE);
+ BFD_ASSERT (h != NULL && h->root.type == bfd_link_hash_defined);
+ start_val = end_val = h->root.u.def.value;
+ }
+
+ if (do_start)
+ bfd_elf_set_symbol (hs, start_val);
+
+ if (do_end)
+ bfd_elf_set_symbol (he, end_val);
}
--- binutils/ld/emultempl/elf32.em.pp 2005-05-03 12:51:22.000000000 -0700
+++ binutils/ld/emultempl/elf32.em 2005-05-03 14:07:20.000000000 -0700
@@ -1452,35 +1452,8 @@ gld${EMULATION_NAME}_provide_bound_symbo
const char *start,
const char *end)
{
- asection *s;
- bfd_vma start_val, end_val;
-
- s = bfd_get_section_by_name (output_bfd, sec);
- if (s != NULL)
- {
- start_val = s->vma;
- end_val = start_val + s->size;
- }
- else
- {
- /* We have to choose those values very carefully. Some targets,
- like alpha, may have relocation overflow with 0. We use the
- first SEC_ALLOC section which isn't SEC_READONLY or the last
- SEC_ALLOC section. */
- start_val = 0;
- for (s = output_bfd->sections; s != NULL; s = s->next)
- {
- if ((s->flags & SEC_ALLOC) != 0)
- {
- start_val = s->vma;
- if ((s->flags & SEC_READONLY) == 0)
- break;
- }
- }
- end_val = start_val;
- }
- _bfd_elf_provide_symbol (&link_info, start, start_val);
- _bfd_elf_provide_symbol (&link_info, end, end_val);
+ asection *s = bfd_get_section_by_name (output_bfd, sec);
+ _bfd_elf_provide_section_bound_symbols (&link_info, s, start, end);
}
/* If not building a shared library, provide