diff options
-rw-r--r-- | bfd/ChangeLog | 10 | ||||
-rw-r--r-- | bfd/bfd-in2.h | 4 | ||||
-rw-r--r-- | bfd/elflink.h | 36 | ||||
-rw-r--r-- | bfd/section.c | 8 | ||||
-rw-r--r-- | ld/ChangeLog | 5 | ||||
-rw-r--r-- | ld/ldlang.c | 5 |
6 files changed, 56 insertions, 12 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index f799d2e..f0570bb 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,13 @@ +2003-06-17 H.J. Lu <hongjiu.lu@intel.com> + + * section.c (struct sec): Put back kept_section. + (STD_SECTION): Put back kept_section initialization. + * bfd-in2.h: Regenerate. + + * elflink.h (elf_link_input_bfd): Also check discarded linkonce + sections for relocateable output. Use kept_section to preserve + debug information discarded by linkonce. + 2003-06-17 Roland McGrath <roland@redhat.com> * elfxx-ia64.c (elfNN_ia64_relocate_section): Support diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 072812e..71346c1 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1408,6 +1408,10 @@ typedef struct sec /* Optional information about a COMDAT entry; NULL if not COMDAT. */ struct bfd_comdat_info *comdat; + /* Points to the kept section if this section is a link-once section, + and is discarded. */ + struct sec *kept_section; + /* When a section is being output, this value changes as more linenumbers are written out. */ file_ptr moving_line_filepos; diff --git a/bfd/elflink.h b/bfd/elflink.h index b960c73..64554e7 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -5005,9 +5005,9 @@ elf_link_input_bfd (finfo, input_bfd) from discarded sections and section symbols from removed link-once sections. Complain about relocs against discarded sections. Zero relocs against removed - link-once sections. */ - if (!finfo->info->relocateable - && !elf_section_ignore_discarded_relocs (o)) + link-once sections. Preserve debug information as much + as we can. */ + if (!elf_section_ignore_discarded_relocs (o)) { Elf_Internal_Rela *rel, *relend; @@ -5016,6 +5016,7 @@ elf_link_input_bfd (finfo, input_bfd) for ( ; rel < relend; rel++) { unsigned long r_symndx = ELF_R_SYM (rel->r_info); + asection *sec; if (r_symndx >= locsymcount || (elf_bad_symtab (input_bfd) @@ -5030,14 +5031,22 @@ elf_link_input_bfd (finfo, input_bfd) /* Complain if the definition comes from a discarded section. */ + sec = h->root.u.def.section; if ((h->root.type == bfd_link_hash_defined || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (h->root.u.def.section)) + && elf_discarded_section (sec)) { if ((o->flags & SEC_DEBUGGING) != 0) { BFD_ASSERT (r_symndx != 0); - memset (rel, 0, sizeof (*rel)); + /* Try to preserve debug information. */ + if ((o->flags & SEC_DEBUGGING) != 0 + && sec->kept_section != NULL + && sec->_cooked_size == sec->kept_section->_cooked_size) + h->root.u.def.section + = sec->kept_section; + else + memset (rel, 0, sizeof (*rel)); } else finfo->info->callbacks->error_handler @@ -5051,7 +5060,7 @@ elf_link_input_bfd (finfo, input_bfd) } else { - asection *sec = finfo->sections[r_symndx]; + sec = finfo->sections[r_symndx]; if (sec != NULL && elf_discarded_section (sec)) { @@ -5059,9 +5068,18 @@ elf_link_input_bfd (finfo, input_bfd) || (sec->flags & SEC_LINK_ONCE) != 0) { BFD_ASSERT (r_symndx != 0); - rel->r_info - = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info)); - rel->r_addend = 0; + /* Try to preserve debug information. */ + if ((o->flags & SEC_DEBUGGING) != 0 + && sec->kept_section != NULL + && sec->_cooked_size == sec->kept_section->_cooked_size) + finfo->sections[r_symndx] + = sec->kept_section; + else + { + rel->r_info + = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info)); + rel->r_addend = 0; + } } else { diff --git a/bfd/section.c b/bfd/section.c index 6facfe2..44edb07 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -493,6 +493,10 @@ CODE_FRAGMENT . {* Optional information about a COMDAT entry; NULL if not COMDAT. *} . struct bfd_comdat_info *comdat; . +. {* Points to the kept section if this section is a link-once section, +. and is discarded. *} +. struct sec *kept_section; +. . {* When a section is being output, this value changes as more . linenumbers are written out. *} . file_ptr moving_line_filepos; @@ -640,8 +644,8 @@ static const asymbol global_syms[] = /* line_filepos, userdata, contents, lineno, lineno_count, */ \ 0, NULL, NULL, NULL, 0, \ \ - /* entsize, comdat, moving_line_filepos, */ \ - 0, NULL, 0, \ + /* entsize, comdat, kept_section, moving_line_filepos, */ \ + 0, NULL, NULL, 0, \ \ /* target_index, used_by_bfd, constructor_chain, owner, */ \ 0, NULL, NULL, NULL, \ diff --git a/ld/ChangeLog b/ld/ChangeLog index 11811de..dcc5a56 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2003-06-17 H.J. Lu <hongjiu.lu@intel.com> + + * ldlang.c (section_already_linked): Put back assignment of + kept_section. + 2003-06-17 Rainer Keuchel <rkeuchel@allgeier.com> * pe-dll.c (generate_reloc): Catch and ignore an ARM_26D diff --git a/ld/ldlang.c b/ld/ldlang.c index fccab0d..83d43b8 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -1089,8 +1089,11 @@ section_already_linked (abfd, sec, data) /* Set the output_section field so that lang_add_section does not create a lang_input_section structure for this - section. */ + section. Since there might be a symbol in the section + being discarded, we must retain a pointer to the section + which we are really going to use. */ sec->output_section = bfd_abs_section_ptr; + sec->kept_section = l->sec; if (flags & SEC_GROUP) bfd_discard_group (abfd, sec); |