diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 1523660..fae3bfd 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -1392,6 +1392,9 @@ typedef struct bfd_section /* Nonzero if this section uses RELA relocations, rather than REL. */ unsigned int use_rela_p:1; + /* Nonzero if there are global symbols associated with this section. */ + unsigned int global_syms_p:1; + /* Bits used by various backends. The generic code doesn't touch these fields. */ @@ -1674,8 +1677,8 @@ extern asection bfd_ind_section; /* linker_mark, linker_has_input, gc_mark, decompress_status, */ \ 0, 0, 1, 0, \ \ - /* segment_mark, sec_info_type, use_rela_p, */ \ - 0, 0, 0, \ + /* segment_mark, sec_info_type, use_rela_p, global_syms_p, */ \ + 0, 0, 0, 0, \ \ /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ \ 0, 0, 0, 0, 0, 0, \ diff --git a/bfd/ecoff.c b/bfd/ecoff.c index b76266d..50c7890 100644 --- a/bfd/ecoff.c +++ b/bfd/ecoff.c @@ -57,8 +57,8 @@ static asection bfd_debug_section = "*DEBUG*", 0, 0, NULL, NULL, 0, 0, /* linker_mark, linker_has_input, gc_mark, compress_status, */ 0, 0, 1, 0, - /* segment_mark, sec_info_type, use_rela_p, */ - 0, 0, 0, + /* segment_mark, sec_info_type, use_rela_p, global_syms_p, */ + 0, 0, 0, 0, /* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, */ 0, 0, 0, 0, 0, 0, /* vma, lma, size, rawsize, compressed_size, relax, relax_count, */ diff --git a/bfd/elf.c b/bfd/elf.c index 9c9ba75..8f4e595 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -6320,6 +6320,7 @@ _bfd_elf_init_private_section_data (bfd *ibfd, } osec->use_rela_p = isec->use_rela_p; + osec->global_syms_p = isec->global_syms_p; return TRUE; } diff --git a/bfd/elflink.c b/bfd/elflink.c index 1d1ca0b..47191cf 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -3903,8 +3903,20 @@ error_free_dyn: sec = bfd_und_section_ptr; isym->st_shndx = SHN_UNDEF; } - else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) - value -= sec->vma; + else + { + /* If we have a global symbol for a section, then we need + to keep it around, even if the section ends up empty. + Except for .gnu.warning sections which are "special" + (see above). */ + if (flags == BSF_GLOBAL + && ! CONST_STRNEQ (bfd_get_section_name (abfd, sec), + ".gnu.warning")) + sec->global_syms_p = 1; + + if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0) + value -= sec->vma; + } } name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link, diff --git a/bfd/section.c b/bfd/section.c index 7c1f750..803de74 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -391,6 +391,9 @@ CODE_FRAGMENT . {* Nonzero if this section uses RELA relocations, rather than REL. *} . unsigned int use_rela_p:1; . +. {* Nonzero if there are global symbols associated with this section. *} +. unsigned int global_syms_p:1; +. . {* Bits used by various backends. The generic code doesn't touch . these fields. *} . @@ -673,8 +676,8 @@ CODE_FRAGMENT . {* linker_mark, linker_has_input, gc_mark, decompress_status, *} \ . 0, 0, 1, 0, \ . \ -. {* segment_mark, sec_info_type, use_rela_p, *} \ -. 0, 0, 0, \ +. {* segment_mark, sec_info_type, use_rela_p, global_syms_p, *} \ +. 0, 0, 0, 0, \ . \ . {* sec_flg0, sec_flg1, sec_flg2, sec_flg3, sec_flg4, sec_flg5, *} \ . 0, 0, 0, 0, 0, 0, \ diff --git a/ld/ldlang.c b/ld/ldlang.c index 5e01fc0..c7b24a2 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -3903,6 +3903,7 @@ strip_excluded_output_sections (void) continue; exclude = (output_section->rawsize == 0 + && output_section->global_syms_p == 0 && (output_section->flags & SEC_KEEP) == 0 && !bfd_section_removed_from_list (link_info.output_bfd, output_section));