From 24376d1b58f62660beb3e5f9c2a7c135513ce27d Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 12 Oct 2000 03:44:51 +0000 Subject: [PATCH] Another try at correcting relocations against discarded link-once section symbols. --- bfd/ChangeLog | 12 ++++++++++++ bfd/bfd-in2.h | 8 ++++---- bfd/elflink.h | 39 ++++++++++++++++++++++++++++++++------- bfd/section.c | 17 +++++++++-------- ld/ChangeLog | 5 +++++ ld/ldlang.c | 3 +-- 6 files changed, 63 insertions(+), 21 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 95d885cdcbe..a3ca28a6c1c 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,17 @@ 2000-10-12 Alan Modra + * section.c (struct sec): Add kept_section. + (struct bfd_comdat_info): Remove sec, we can use above. + (STD_SECTION): Add initializer. + (bfd_make_section_anyway): Init here too. + + * bfd-in2.h: Regenerate. + + * elflink.h (elf_link_add_object_symbols): Remove unnecessary + zeroing of `flags'. + (elf_link_input_bfd): Set all asection->symbol->value's here, and + fudge values for discarded link-once section symbols. + * elf64-hppa.c: Include alloca-conf.h 2000-10-11 Alan Modra diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 51c7043229c..64238aca9f8 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -913,10 +913,6 @@ struct bfd_comdat_info specific code; it is not an index into the list returned by bfd_canonicalize_symtab. */ long symbol; - - /* If this section is being discarded, the linker uses this field - to point to the input section which is being kept. */ - struct sec *sec; }; typedef struct sec @@ -1219,6 +1215,10 @@ typedef struct sec 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. */ diff --git a/bfd/elflink.h b/bfd/elflink.h index 9e543a7c8d0..9a0f49a182d 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -1371,8 +1371,6 @@ elf_link_add_object_symbols (abfd, info) if (sym.st_shndx != SHN_UNDEF && sym.st_shndx != SHN_COMMON) flags = BSF_GLOBAL; - else - flags = 0; } else if (bind == STB_WEAK) flags = BSF_WEAK; @@ -5536,16 +5534,43 @@ elf_link_input_bfd (finfo, input_bfd) if (esym == external_syms) continue; + if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) + { + asection *ksec; + + /* Save away all section symbol values. */ + if (isec != NULL) + isec->symbol->value = isym->st_value; + + /* If this is a discarded link-once section symbol, update + it's value to that of the kept section symbol. The + linker will keep the first of any matching link-once + sections, so we should have already seen it's section + symbol. I trust no-one will have the bright idea of + re-ordering the bfd list... */ + if (isec != NULL + && (bfd_get_section_flags (input_bfd, isec) & SEC_LINK_ONCE) != 0 + && (ksec = isec->kept_section) != NULL) + { + isym->st_value = ksec->symbol->value; + + /* That put the value right, but the section info is all + wrong. I hope this works. */ + isec->output_offset = ksec->output_offset; + isec->output_section = ksec->output_section; + } + + /* We never output section symbols. Instead, we use the + section symbol of the corresponding section in the output + file. */ + continue; + } + /* If we are stripping all symbols, we don't want to output this one. */ if (finfo->info->strip == strip_all) continue; - /* We never output section symbols. Instead, we use the section - symbol of the corresponding section in the output file. */ - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - continue; - /* If we are discarding all local symbols, we don't want to output this one. If we are generating a relocateable output file, then some of the local symbols may be required by diff --git a/bfd/section.c b/bfd/section.c index fc64b2019fb..ef7a7e6fe2a 100644 --- a/bfd/section.c +++ b/bfd/section.c @@ -165,10 +165,6 @@ CODE_FRAGMENT . specific code; it is not an index into the list returned by . bfd_canonicalize_symtab. *} . long symbol; -. -. {* If this section is being discarded, the linker uses this field -. to point to the input section which is being kept. *} -. struct sec *sec; .}; . .typedef struct sec @@ -471,6 +467,10 @@ CODE_FRAGMENT . . 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. *} . @@ -578,11 +578,11 @@ static const asymbol global_syms[] = /* line_filepos, userdata, contents, lineno, lineno_count, */ \ 0, NULL, NULL, NULL, 0, \ \ - /* comdat, moving_line_filepos, target_index, used_by_bfd, */ \ - NULL, 0, 0, NULL, \ + /* comdat, kept_section, moving_line_filepos, target_index, */ \ + NULL, NULL, 0, 0, \ \ - /* constructor_chain, owner, */ \ - NULL, NULL, \ + /* used_by_bfd, constructor_chain, owner, */ \ + NULL, NULL, NULL, \ \ /* symbol, */ \ (struct symbol_cache_entry *) &global_syms[IDX], \ @@ -789,6 +789,7 @@ bfd_make_section_anyway (abfd, name) newsect->line_filepos = 0; newsect->owner = abfd; newsect->comdat = NULL; + newsect->kept_section = NULL; /* Create a symbol whos only job is to point to this section. This is useful for things like relocs which are relative to the base of a diff --git a/ld/ChangeLog b/ld/ChangeLog index 0300d6564ac..14fe197e88a 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,8 @@ +2000-10-12 Alan Modra + + * ldlang.c (section_already_linked): Set kept_section instead of + sec->comdat->sec. + 2000-10-10 Kazu Hirata * deffile.h: Fix formatting. diff --git a/ld/ldlang.c b/ld/ldlang.c index c57dd6d87f2..d92ebbfd847 100644 --- a/ld/ldlang.c +++ b/ld/ldlang.c @@ -995,8 +995,7 @@ section_already_linked (abfd, sec, data) discarded, we must retain a pointer to the section which we are really going to use. */ sec->output_section = bfd_abs_section_ptr; - if (sec->comdat != NULL) - sec->comdat->sec = l->sec; + sec->kept_section = l->sec; return; } -- 2.30.2