From 62d08682f8d256777a0ef00733dac08f68016c8f Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Thu, 1 Nov 2007 11:45:20 +0000 Subject: bfd: * merge.c (sec_merge_hash_lookup): Add parameter sec_end. Check for unterminated strings. All callers changed. (record_section): Add parameter abfd. Give error message for unterminated strings. (_bfd_merge_sections): Update call to record_section. (_bfd_write_merged_section, _bfd_merged_section_offset): Handle NULL secinfo from merge failures. ld/testsuite: * ld-elf/merge3.d, ld-elf/merge3.s: New. --- bfd/ChangeLog | 10 ++++++++++ bfd/merge.c | 28 +++++++++++++++++++++++----- ld/testsuite/ChangeLog | 4 ++++ ld/testsuite/ld-elf/merge3.d | 3 +++ ld/testsuite/ld-elf/merge3.s | 7 +++++++ 5 files changed, 47 insertions(+), 5 deletions(-) create mode 100644 ld/testsuite/ld-elf/merge3.d create mode 100644 ld/testsuite/ld-elf/merge3.s diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 7543f62e26..6c84726251 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2007-11-01 Joseph Myers + + * merge.c (sec_merge_hash_lookup): Add parameter sec_end. Check + for unterminated strings. All callers changed. + (record_section): Add parameter abfd. Give error message for + unterminated strings. + (_bfd_merge_sections): Update call to record_section. + (_bfd_write_merged_section, _bfd_merged_section_offset): Handle + NULL secinfo from merge failures. + 2007-10-31 Nick Clifton * elf-m10300.c (mn10300_elf_relax_delete_bytes): Do not look for diff --git a/bfd/merge.c b/bfd/merge.c index 32994c3cba..309152e357 100644 --- a/bfd/merge.c +++ b/bfd/merge.c @@ -133,6 +133,7 @@ sec_merge_hash_newfunc (struct bfd_hash_entry *entry, static struct sec_merge_hash_entry * sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, + const unsigned char *sec_end, unsigned int alignment, bfd_boolean create) { register const unsigned char *s; @@ -154,6 +155,8 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, hash += c + (c << 17); hash ^= hash >> 2; ++len; + if (sec_end && s >= sec_end) + return NULL; } hash += len + (len << 17); } @@ -161,6 +164,8 @@ sec_merge_hash_lookup (struct sec_merge_hash *table, const char *string, { for (;;) { + if (sec_end && s + table->entsize > sec_end) + return NULL; for (i = 0; i < table->entsize; ++i) if (s[i] != '\0') break; @@ -264,7 +269,9 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str, { register struct sec_merge_hash_entry *entry; - entry = sec_merge_hash_lookup (tab, str, alignment, TRUE); + entry = sec_merge_hash_lookup (tab, str, + secinfo->contents + secinfo->sec->size, + alignment, TRUE); if (entry == NULL) return NULL; @@ -436,7 +443,8 @@ _bfd_add_merge_section (bfd *abfd, void **psinfo, asection *sec, /* Record one section into the hash table. */ static bfd_boolean -record_section (struct sec_merge_info *sinfo, +record_section (bfd *abfd, + struct sec_merge_info *sinfo, struct sec_merge_sec_info *secinfo) { asection *sec = secinfo->sec; @@ -513,6 +521,10 @@ record_section (struct sec_merge_info *sinfo, return TRUE; error_return: + if (bfd_get_error () != bfd_error_no_memory) + (*_bfd_error_handler) + (_("%B: unterminated string in section `%A' marked for merging"), + abfd, sec); for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next) *secinfo->psecinfo = NULL; return FALSE; @@ -695,7 +707,7 @@ alloc_failure: with _bfd_merge_section. */ bfd_boolean -_bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, +_bfd_merge_sections (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED, void *xsinfo, void (*remove_hook) (bfd *, asection *)) @@ -722,7 +734,7 @@ _bfd_merge_sections (bfd *abfd ATTRIBUTE_UNUSED, if (remove_hook) (*remove_hook) (abfd, secinfo->sec); } - else if (! record_section (sinfo, secinfo)) + else if (! record_section (abfd, sinfo, secinfo)) break; if (secinfo) @@ -779,6 +791,9 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo) secinfo = (struct sec_merge_sec_info *) psecinfo; + if (!secinfo) + return FALSE; + if (secinfo->first_str == NULL) return TRUE; @@ -807,6 +822,9 @@ _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec, secinfo = (struct sec_merge_sec_info *) psecinfo; + if (!secinfo) + return 0; + if (offset >= sec->rawsize) { if (offset > sec->rawsize) @@ -849,7 +867,7 @@ _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec, { p = secinfo->contents + (offset / sec->entsize) * sec->entsize; } - entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, 0, FALSE); + entry = sec_merge_hash_lookup (secinfo->htab, (char *) p, NULL, 0, FALSE); if (!entry) { if (! secinfo->htab->strings) diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 49e55ad9a1..b8b5b2b3e5 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2007-11-01 Joseph Myers + + * ld-elf/merge3.d, ld-elf/merge3.s: New. + 2007-10-30 Nick Clifton * ld-mn10300/mn10300.exp: Run new tests. Skip i126256 test if diff --git a/ld/testsuite/ld-elf/merge3.d b/ld/testsuite/ld-elf/merge3.d new file mode 100644 index 0000000000..20d30ca846 --- /dev/null +++ b/ld/testsuite/ld-elf/merge3.d @@ -0,0 +1,3 @@ +#source: merge3.s +#ld: -T merge.ld +#error: unterminated string in section `.rodata.str' marked for merging diff --git a/ld/testsuite/ld-elf/merge3.s b/ld/testsuite/ld-elf/merge3.s new file mode 100644 index 0000000000..25709bec66 --- /dev/null +++ b/ld/testsuite/ld-elf/merge3.s @@ -0,0 +1,7 @@ + .section .rodata.str,"aMS","progbits",1 +.LC0: + .ascii "abcd" + .text + .global _start +_start: + .long .LC0 -- cgit v1.2.1