aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2000-10-12 03:44:51 +0000
committerAlan Modra <amodra@gmail.com>2000-10-12 03:44:51 +0000
commit24376d1b58f62660beb3e5f9c2a7c135513ce27d (patch)
tree684628a3f6e7b7ffe80bfb966007ad2179aeee00
parent74bcd5294fa6894905a705d18c229cbe5ea42b59 (diff)
downloadfsf-binutils-gdb-24376d1b58f62660beb3e5f9c2a7c135513ce27d.zip
fsf-binutils-gdb-24376d1b58f62660beb3e5f9c2a7c135513ce27d.tar.gz
fsf-binutils-gdb-24376d1b58f62660beb3e5f9c2a7c135513ce27d.tar.bz2
Another try at correcting relocations against discarded
link-once section symbols.
-rw-r--r--bfd/ChangeLog12
-rw-r--r--bfd/bfd-in2.h8
-rw-r--r--bfd/elflink.h39
-rw-r--r--bfd/section.c17
-rw-r--r--ld/ChangeLog5
-rw-r--r--ld/ldlang.c3
6 files changed, 63 insertions, 21 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 95d885c..a3ca28a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,17 @@
2000-10-12 Alan Modra <alan@linuxcare.com.au>
+ * 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 <alan@linuxcare.com.au>
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 51c7043..64238ac 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 9e543a7..9a0f49a 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 fc64b20..ef7a7e6 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 0300d65..14fe197 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,8 @@
+2000-10-12 Alan Modra <alan@linuxcare.com.au>
+
+ * ldlang.c (section_already_linked): Set kept_section instead of
+ sec->comdat->sec.
+
2000-10-10 Kazu Hirata <kazu@hxi.com>
* deffile.h: Fix formatting.
diff --git a/ld/ldlang.c b/ld/ldlang.c
index c57dd6d..d92ebbf 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;
}