aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2005-05-04 13:19:02 +0000
committerH.J. Lu <hjl.tools@gmail.com>2005-05-04 13:19:02 +0000
commitf652615e8c2bba008e66f8eaf11a42650b714086 (patch)
treeb10e04752515f4bafd6ced0dba1df6c81c6c876c /bfd
parentc5e2ceadb7216936dcc3d9dec73de31075460765 (diff)
downloadgdb-f652615e8c2bba008e66f8eaf11a42650b714086.zip
gdb-f652615e8c2bba008e66f8eaf11a42650b714086.tar.gz
gdb-f652615e8c2bba008e66f8eaf11a42650b714086.tar.bz2
bfd/
2005-05-04 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-04 H.J. Lu <hongjiu.lu@intel.com> * emultempl/elf32.em (gld${EMULATION_NAME}_provide_bound_symbols): Call _bfd_elf_provide_section_bound_symbols.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog9
-rw-r--r--bfd/bfd-in.h3
-rw-r--r--bfd/bfd-in2.h3
-rw-r--r--bfd/elflink.c74
4 files changed, 82 insertions, 7 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 2b010e8..a05a025 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,14 @@
2005-05-04 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.
+
+2005-05-04 H.J. Lu <hongjiu.lu@intel.com>
+
* elflink.c (_bfd_elf_merge_symbol): Only skip weak definitions
at the end, if a strong definition has already been seen.
diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 2aa6bbb..101930f 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -700,6 +700,9 @@ extern struct bfd_section *_bfd_elf_tls_setup
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 **);
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 45060f8..45b09146 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -707,6 +707,9 @@ extern struct bfd_section *_bfd_elf_tls_setup
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 **);
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 370a9b7..9e76d06 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -9824,6 +9824,18 @@ _bfd_elf_section_already_linked (bfd *abfd, struct bfd_section * sec)
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
@@ -9836,13 +9848,61 @@ _bfd_elf_provide_symbol (struct bfd_link_info *info, const char *name,
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);
+ if (h != NULL && h->root.type == bfd_link_hash_defined)
+ start_val = h->root.u.def.value;
+ else
+ start_val = 0;
+ end_val = start_val;
+ }
+
+ if (do_start)
+ bfd_elf_set_symbol (hs, start_val);
+
+ if (do_end)
+ bfd_elf_set_symbol (he, end_val);
}