aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/aout-target.h4
-rw-r--r--bfd/aoutx.h9
-rw-r--r--bfd/bfd-in2.h12
-rw-r--r--bfd/coff-alpha.c2
-rw-r--r--bfd/coff-arm.c12
-rw-r--r--bfd/coff-mips.c2
-rw-r--r--bfd/coff-rs6000.c2
-rw-r--r--bfd/coff-sh.c2
-rw-r--r--bfd/coff64-rs6000.c2
-rw-r--r--bfd/coffcode.h21
-rw-r--r--bfd/coffgen.c18
-rw-r--r--bfd/cofflink.c49
-rw-r--r--bfd/elf32-nds32.c18
-rw-r--r--bfd/elflink.c49
-rw-r--r--bfd/elfxx-x86.c20
-rw-r--r--bfd/format.c25
-rw-r--r--bfd/i386aout.c1
-rw-r--r--bfd/libaout.h7
-rw-r--r--bfd/libbfd-in.h6
-rw-r--r--bfd/libbfd.h6
-rw-r--r--bfd/libcoff.h9
-rw-r--r--bfd/linker.c20
-rw-r--r--bfd/pdp11.c9
-rw-r--r--bfd/peXXigen.c111
-rw-r--r--bfd/version.h2
-rw-r--r--bfd/xcofflink.c97
26 files changed, 351 insertions, 164 deletions
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
index f513e1b..1b71104 100644
--- a/bfd/aout-target.h
+++ b/bfd/aout-target.h
@@ -286,9 +286,6 @@ MY (set_sizes) (bfd *abfd)
#ifndef MY_add_dynamic_symbols
#define MY_add_dynamic_symbols 0
#endif
-#ifndef MY_add_one_symbol
-#define MY_add_one_symbol 0
-#endif
#ifndef MY_link_dynamic_object
#define MY_link_dynamic_object 0
#endif
@@ -312,7 +309,6 @@ static const struct aout_backend_data MY (backend_data) =
MY_set_sizes,
MY_exec_header_not_counted,
MY_add_dynamic_symbols,
- MY_add_one_symbol,
MY_link_dynamic_object,
MY_write_dynamic_symbol,
MY_check_dynamic_reloc,
diff --git a/bfd/aoutx.h b/bfd/aoutx.h
index 63c654f..81e0804 100644
--- a/bfd/aoutx.h
+++ b/bfd/aoutx.h
@@ -2973,9 +2973,6 @@ NAME (aout, link_hash_table_create) (bfd *abfd)
static bool
aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
- bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
struct external_nlist *syms;
bfd_size_type sym_count;
char *strings;
@@ -3013,10 +3010,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
return false;
obj_aout_sym_hashes (abfd) = sym_hash;
- add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
- if (add_one_symbol == NULL)
- add_one_symbol = _bfd_generic_link_add_one_symbol;
-
p = syms;
pend = p + sym_count;
for (; p < pend; p++, sym_hash++)
@@ -3167,7 +3160,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
break;
}
- if (! ((*add_one_symbol)
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value, string, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
return false;
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 7a8318e..ec60f23 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2913,6 +2913,18 @@ const char *bfd_format_string (bfd_format format);
&& bfd_is_abs_section ((H)->u.def.section) \
&& !(H)->rel_from_abs)
+bool _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bool copy,
+ bool collect,
+ struct bfd_link_hash_entry **hashp);
+
bool bfd_link_align_section (asection *, unsigned int);
bool bfd_link_split_section (bfd *abfd, asection *sec);
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index 2798efd..e2f1a4d 100644
--- a/bfd/coff-alpha.c
+++ b/bfd/coff-alpha.c
@@ -2359,7 +2359,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
alpha_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL, NULL
+ NULL, NULL, NULL,
},
/* Supported architecture. */
bfd_arch_alpha,
diff --git a/bfd/coff-arm.c b/bfd/coff-arm.c
index ab5f7b0..ee57451 100644
--- a/bfd/coff-arm.c
+++ b/bfd/coff-arm.c
@@ -1876,8 +1876,8 @@ record_arm_to_thumb_glue (struct bfd_link_info * info,
it. */
bh = NULL;
val = globals->arm_glue_size + 1;
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
free (tmp_name);
@@ -1929,8 +1929,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info,
bh = NULL;
val = globals->thumb_glue_size + 1;
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_GLOBAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_GLOBAL, s, val, NULL, true, false, &bh);
/* If we mark it 'thumb', the disassembler will do a better job. */
myh = (struct coff_link_hash_entry *) bh;
@@ -1952,8 +1952,8 @@ record_thumb_to_arm_glue (struct bfd_link_info * info,
bh = NULL;
val = globals->thumb_glue_size + (globals->support_old_code ? 8 : 4);
- bfd_coff_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
- BSF_LOCAL, s, val, NULL, true, false, &bh);
+ _bfd_generic_link_add_one_symbol (info, globals->bfd_of_glue_owner, tmp_name,
+ BSF_LOCAL, s, val, NULL, true, false, &bh);
free (tmp_name);
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index e2c632c..8c4d4f7 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -1316,7 +1316,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
_bfd_ecoff_mkobject_hook, _bfd_ecoff_styp_to_sec_flags,
_bfd_ecoff_set_alignment_hook, _bfd_ecoff_slurp_symbol_table,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
- NULL, NULL, NULL
+ NULL, NULL,
},
/* Supported architecture. */
bfd_arch_mips,
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 7a20dba..ae9a0f6 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -4584,7 +4584,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
xcoff_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
@@ -4774,7 +4773,6 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data =
xcoff_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
diff --git a/bfd/coff-sh.c b/bfd/coff-sh.c
index 275c4f5..c3e0e42 100644
--- a/bfd/coff-sh.c
+++ b/bfd/coff-sh.c
@@ -3108,7 +3108,7 @@ static const bfd_coff_backend_data bfd_coff_small_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index 5a4bcbf..ec7ed08 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -2495,7 +2495,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data =
xcoff64_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
@@ -2768,7 +2767,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_aix5_backend_data =
xcoff64_ppc_relocate_section,
coff_rtype_to_howto,
NULL, /* _bfd_coff_adjust_symndx */
- _bfd_generic_link_add_one_symbol,
coff_link_output_has_begun,
coff_final_link_postscript,
NULL /* print_pdata. */
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 325a8ab..bd0374f 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1516,11 +1516,6 @@ CODE_FRAGMENT
. (bfd *, struct bfd_link_info *, bfd *, asection *,
. struct internal_reloc *, bool *);
.
-. bool (*_bfd_coff_link_add_one_symbol)
-. (struct bfd_link_info *, bfd *, const char *, flagword,
-. asection *, bfd_vma, const char *, bool, bool,
-. struct bfd_link_hash_entry **);
-.
. bool (*_bfd_coff_link_output_has_begun)
. (bfd *, struct coff_final_link_info *);
.
@@ -1659,10 +1654,6 @@ INTERNAL
.#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
. ((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
. (obfd, info, ibfd, sec, rel, adjustedp))
-.#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
-. value, string, cp, coll, hashp)\
-. ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
-. (info, abfd, name, flags, section, value, string, cp, coll, hashp))
.
.#define bfd_coff_link_output_has_begun(a,p) \
. ((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p))
@@ -5513,10 +5504,6 @@ dummy_reloc16_extra_cases (bfd *abfd ATTRIBUTE_UNUSED,
#define coff_adjust_symndx NULL
#endif
-#ifndef coff_link_add_one_symbol
-#define coff_link_add_one_symbol _bfd_generic_link_add_one_symbol
-#endif
-
#ifndef coff_link_output_has_begun
static bool
@@ -5615,7 +5602,7 @@ static const bfd_coff_backend_data bfd_coff_std_swap_table ATTRIBUTE_UNUSED =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
@@ -5656,7 +5643,7 @@ static const bfd_coff_backend_data ticoff0_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata
};
@@ -5698,7 +5685,7 @@ static const bfd_coff_backend_data ticoff1_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata /* huh */
};
@@ -5941,7 +5928,7 @@ static const bfd_coff_backend_data bigobj_swap_table =
coff_print_aux, coff_reloc16_extra_cases, coff_reloc16_estimate,
coff_classify_symbol, coff_compute_section_file_positions,
coff_start_final_link, coff_relocate_section, coff_rtype_to_howto,
- coff_adjust_symndx, coff_link_add_one_symbol,
+ coff_adjust_symndx,
coff_link_output_has_begun, coff_final_link_postscript,
bfd_pe_print_pdata /* huh */
};
diff --git a/bfd/coffgen.c b/bfd/coffgen.c
index f87e54f..ab4d790 100644
--- a/bfd/coffgen.c
+++ b/bfd/coffgen.c
@@ -42,6 +42,7 @@
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "elf-bfd.h"
#include "hashtab.h"
/* Extract a long section name at STRINDEX and copy it to the bfd objstack.
@@ -1270,9 +1271,24 @@ coff_write_alien_symbol (bfd *abfd,
if (c != (coff_symbol_type *) NULL)
native->u.syment.n_flags = bfd_asymbol_bfd (&c->symbol)->flags;
}
+
+ const elf_symbol_type *elfsym = elf_symbol_from (symbol);
+ if (elfsym
+ && (symbol->flags & BSF_FUNCTION)
+ && elfsym->internal_elf_sym.st_size)
+ {
+ /* coff_data (abfd)->local_n_btshft is what ought to be used here,
+ just that it's set only when reading in COFF objects. */
+ native->u.syment.n_type = DT_FCN << 4;
+ native->u.syment.n_numaux = 1;
+ native[1].u.auxent.x_sym.x_misc.x_fsize
+ = elfsym->internal_elf_sym.st_size;
+ /* FIXME .u.auxent.x_sym.x_fcnary.x_fcn.x_endndx would better also
+ be set, which would require updating the field once the next
+ function is seen. */
+ }
}
- native->u.syment.n_type = 0;
if (symbol->flags & BSF_FILE)
native->u.syment.n_sclass = C_FILE;
else if (symbol->flags & BSF_LOCAL)
diff --git a/bfd/cofflink.c b/bfd/cofflink.c
index 876aed7..38278e2 100644
--- a/bfd/cofflink.c
+++ b/bfd/cofflink.c
@@ -27,6 +27,7 @@
#include "libbfd.h"
#include "coff/internal.h"
#include "libcoff.h"
+#include "elf-bfd.h"
#include "safe-ctype.h"
static bool coff_link_add_object_symbols (bfd *, struct bfd_link_info *);
@@ -445,7 +446,7 @@ coff_link_add_symbols (bfd *abfd,
if (addit)
{
- if (! (bfd_coff_link_add_one_symbol
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value,
(const char *) NULL, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
@@ -931,14 +932,52 @@ _bfd_coff_final_link (bfd *abfd,
bfd_vma written = 0;
bool rewrite = false;
- if (! (sym->flags & BSF_LOCAL)
- || (sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
- | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
- | BSF_SYNTHETIC))
+ if ((sym->flags & (BSF_SECTION_SYM | BSF_DEBUGGING_RELOC
+ | BSF_THREAD_LOCAL | BSF_RELC | BSF_SRELC
+ | BSF_SYNTHETIC))
|| ((sym->flags & BSF_DEBUGGING)
&& ! (sym->flags & BSF_FILE)))
continue;
+ if (! (sym->flags & BSF_LOCAL))
+ {
+ /* For ELF symbols try to represent their function-ness and
+ size, if available. */
+ if (! (sym->flags & BSF_FUNCTION))
+ continue;
+
+ const elf_symbol_type *elfsym = elf_symbol_from (sym);
+ if (!elfsym)
+ continue;
+
+ struct coff_link_hash_entry *hent
+ = (struct coff_link_hash_entry *) bfd_hash_lookup
+ (&info->hash->table, bfd_asymbol_name (sym),
+ false, false);
+ if (!hent)
+ continue;
+
+ /* coff_data (abfd)->local_n_btshft is what ought to be used
+ here, just that it's set only when reading in COFF
+ objects. */
+ hent->type = DT_FCN << 4;
+ if (!elfsym->internal_elf_sym.st_size)
+ continue;
+
+ hent->aux = bfd_zalloc (abfd, sizeof (*hent->aux));
+ if (!hent->aux)
+ continue;
+
+ hent->numaux = 1;
+ hent->aux->x_sym.x_misc.x_fsize
+ = elfsym->internal_elf_sym.st_size;
+ /* FIXME ->x_sym.x_fcnary.x_fcn.x_endndx would better
+ also be set, yet that would likely need to happen
+ elsewhere anyway. */
+
+ continue;
+ }
+
/* See if we are discarding symbols with this name. */
if ((flaginfo.info->strip == strip_some
&& (bfd_hash_lookup (flaginfo.info->keep_hash,
diff --git a/bfd/elf32-nds32.c b/bfd/elf32-nds32.c
index 1aff60a..3627b30 100644
--- a/bfd/elf32-nds32.c
+++ b/bfd/elf32-nds32.c
@@ -2697,7 +2697,8 @@ nds32_elf_do_9_pcrel_reloc (bfd * abfd,
bfd_reloc_status_type status;
/* Sanity check the address (offset in section). */
- if (offset > bfd_get_section_limit (abfd, input_section))
+ bfd_vma octet = offset * bfd_octets_per_byte (abfd, input_section);
+ if (!bfd_reloc_offset_in_range (howto, abfd, input_section, octet))
return bfd_reloc_outofrange;
relocation = symbol_value + addend;
@@ -2751,7 +2752,7 @@ struct nds32_hi20
static struct nds32_hi20 *nds32_hi20_list;
static bfd_reloc_status_type
-nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+nds32_elf_hi20_reloc (bfd *abfd,
arelent *reloc_entry,
asymbol *symbol,
void *data,
@@ -2774,7 +2775,10 @@ nds32_elf_hi20_reloc (bfd *abfd ATTRIBUTE_UNUSED,
}
/* Sanity check the address (offset in section). */
- if (reloc_entry->address > bfd_get_section_limit (abfd, input_section))
+ bfd_vma octet = (reloc_entry->address
+ * bfd_octets_per_byte (abfd, input_section));
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto,
+ abfd, input_section, octet))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
@@ -2938,7 +2942,10 @@ nds32_elf_generic_reloc (bfd *input_bfd, arelent *reloc_entry,
a section relative addend which is wrong. */
/* Sanity check the address (offset in section). */
- if (reloc_entry->address > bfd_get_section_limit (input_bfd, input_section))
+ bfd_vma octet = (reloc_entry->address
+ * bfd_octets_per_byte (input_bfd, input_section));
+ if (!bfd_reloc_offset_in_range (reloc_entry->howto, input_bfd, input_section,
+ octet))
return bfd_reloc_outofrange;
ret = bfd_reloc_ok;
@@ -4698,7 +4705,8 @@ nds32_elf_final_link_relocate (reloc_howto_type *howto, bfd *input_bfd,
bfd_vma relocation;
/* Sanity check the address. */
- if (address > bfd_get_section_limit (input_bfd, input_section))
+ bfd_vma octet = address * bfd_octets_per_byte (input_bfd, input_section);
+ if (!bfd_reloc_offset_in_range (howto, input_bfd, input_section, octet))
return bfd_reloc_outofrange;
/* This function assumes that we are dealing with a basic relocation
diff --git a/bfd/elflink.c b/bfd/elflink.c
index 1399352..919f2a7 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -4965,6 +4965,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
asection *sec, *new_sec;
flagword flags;
const char *name;
+ const char *defvername;
bool must_copy_name = false;
struct elf_link_hash_entry *h;
struct elf_link_hash_entry *hi;
@@ -5141,6 +5142,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
old_alignment = 0;
old_bfd = NULL;
new_sec = sec;
+ defvername = NULL;
if (is_elf_hash_table (&htab->root))
{
@@ -5259,7 +5261,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
default version of the symbol. */
if ((iver.vs_vers & VERSYM_HIDDEN) == 0
&& isym->st_shndx != SHN_UNDEF)
- *p++ = ELF_VER_CHR;
+ *p++ = ELF_VER_CHR, defvername = name;
memcpy (p, verstr, verlen + 1);
name = newname;
@@ -5709,9 +5711,15 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
}
else if (dynamic
&& h->root.u.def.section->owner == abfd)
- /* Add this symbol to first hash if this shared
- object has the first definition. */
- elf_link_add_to_first_hash (abfd, info, name, must_copy_name);
+ {
+ /* Add this symbol to first hash if this shared
+ object has the first definition. */
+ elf_link_add_to_first_hash (abfd, info, name, must_copy_name);
+ /* And if it was the default symbol version definition,
+ also add the short name. */
+ if (defvername)
+ elf_link_add_to_first_hash (abfd, info, defvername, false);
+ }
}
}
}
@@ -6273,12 +6281,30 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
if (h->type == bfd_link_hash_undefined)
{
- /* If the archive element has already been loaded then one
- of the symbols defined by that element might have been
- made undefined due to being in a discarded section. */
- if (is_elf_hash_table (info->hash)
- && ((struct elf_link_hash_entry *) h)->indx == -3)
- continue;
+ if (is_elf_hash_table (info->hash))
+ {
+ /* If the archive element has already been loaded then one
+ of the symbols defined by that element might have been
+ made undefined due to being in a discarded section. */
+ if (((struct elf_link_hash_entry *) h)->indx == -3)
+ continue;
+
+ /* In the pre-LTO-plugin pass we must not mistakenly
+ include this archive member if an earlier shared
+ library defined this symbol. */
+ struct elf_link_hash_table *htab = elf_hash_table (info);
+ if (htab->first_hash)
+ {
+ struct elf_link_first_hash_entry *e
+ = ((struct elf_link_first_hash_entry *)
+ bfd_hash_lookup (htab->first_hash, symdef->name,
+ false, false));
+ if (e
+ && (e->abfd->flags & DYNAMIC) != 0
+ && e->abfd != abfd)
+ continue;
+ }
+ }
}
else if (h->type == bfd_link_hash_common)
{
@@ -14384,7 +14410,8 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info)
if (o->flags & SEC_GROUP)
{
asection *first = elf_next_in_group (o);
- o->gc_mark = first->gc_mark;
+ if (first != NULL)
+ o->gc_mark = first->gc_mark;
}
if (o->gc_mark)
diff --git a/bfd/elfxx-x86.c b/bfd/elfxx-x86.c
index 6ea41f2..bc9bb70 100644
--- a/bfd/elfxx-x86.c
+++ b/bfd/elfxx-x86.c
@@ -609,8 +609,7 @@ _bfd_elf_x86_get_local_sym_hash (struct elf_x86_link_hash_table *htab,
return &ret->elf;
}
-/* Create an entry in a x86 ELF linker hash table. NB: THIS MUST BE IN
- SYNC WITH _bfd_elf_link_hash_newfunc. */
+/* Create an entry in an x86 ELF linker hash table. */
struct bfd_hash_entry *
_bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
@@ -629,27 +628,14 @@ _bfd_x86_elf_link_hash_newfunc (struct bfd_hash_entry *entry,
}
/* Call the allocation method of the superclass. */
- entry = _bfd_link_hash_newfunc (entry, table, string);
+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
if (entry != NULL)
{
struct elf_x86_link_hash_entry *eh
= (struct elf_x86_link_hash_entry *) entry;
- struct elf_link_hash_table *htab
- = (struct elf_link_hash_table *) table;
- memset (&eh->elf.size, 0,
- (sizeof (struct elf_x86_link_hash_entry)
- - offsetof (struct elf_link_hash_entry, size)));
+ memset (&eh->elf + 1, 0, sizeof (*eh) - sizeof (eh->elf));
/* Set local fields. */
- eh->elf.indx = -1;
- eh->elf.dynindx = -1;
- eh->elf.got = htab->init_got_refcount;
- eh->elf.plt = htab->init_plt_refcount;
- /* Assume that we have been called by a non-ELF symbol reader.
- This flag is then reset by the code which reads an ELF input
- file. This ensures that a symbol created by a non-ELF symbol
- reader will have the flag set correctly. */
- eh->elf.non_elf = 1;
eh->plt_second.offset = (bfd_vma) -1;
eh->plt_got.offset = (bfd_vma) -1;
eh->tlsdesc_got = (bfd_vma) -1;
diff --git a/bfd/format.c b/bfd/format.c
index 7769ad0..3db0792 100644
--- a/bfd/format.c
+++ b/bfd/format.c
@@ -331,6 +331,25 @@ print_and_clear_messages (struct per_xvec_messages *list,
free (iter);
iter = next;
}
+
+ /* Don't retain a pointer to free'd memory. */
+ list->next = NULL;
+}
+
+/* Discard all messages associated with TARG in LIST. Unlike
+ print_and_clear_messages, PER_XVEC_NO_TARGET is not valid for TARG. */
+
+static void
+clear_messages (struct per_xvec_messages *list,
+ const bfd_target *targ)
+{
+ struct per_xvec_messages *iter;
+
+ for (iter = list; iter != NULL; iter = iter->next)
+ {
+ if (iter->targ == targ)
+ clear_warnmsg (&iter->messages);
+ }
}
/* This a copy of lto_section defined in GCC (lto-streamer.h). */
@@ -545,6 +564,12 @@ bfd_check_format_matches (bfd *abfd, bfd_format format, char ***matching)
/* Change BFD's target temporarily. */
abfd->xvec = *target;
+ /* It is possible that targets appear multiple times in
+ bfd_target_vector. If this is the case, then we want to avoid
+ accumulating duplicate messages for a target in MESSAGES, so
+ discard any previous messages associated with this target. */
+ clear_messages (&messages, abfd->xvec);
+
if (bfd_seek (abfd, 0, SEEK_SET) != 0)
goto err_ret;
diff --git a/bfd/i386aout.c b/bfd/i386aout.c
index fb09597..082ebfb 100644
--- a/bfd/i386aout.c
+++ b/bfd/i386aout.c
@@ -79,7 +79,6 @@ static const struct aout_backend_data MY (backend_data) =
MY (set_sizes),
1, /* Exec header not counted. */
0, /* Add_dynamic_symbols. */
- 0, /* Add_one_symbol. */
0, /* Link_dynamic_object. */
0, /* Write_dynamic_symbol. */
0, /* Check_dynamic_reloc. */
diff --git a/bfd/libaout.h b/bfd/libaout.h
index ca4faec..7628d6a 100644
--- a/bfd/libaout.h
+++ b/bfd/libaout.h
@@ -177,13 +177,6 @@ struct aout_backend_data
(bfd *, struct bfd_link_info *, struct external_nlist **,
bfd_size_type *, char **);
- /* Callback from the add symbols phase of the linker code to handle
- adding a single symbol to the global linker hash table. */
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword,
- asection *, bfd_vma, const char *, bool, bool,
- struct bfd_link_hash_entry **);
-
/* Called to handle linking a dynamic object. */
bool (*link_dynamic_object)
(struct bfd_link_info *, bfd *);
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index b2f70fb..ae6d303 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -645,12 +645,6 @@ extern bool _bfd_generic_link_add_archive_symbols
/* Forward declaration to avoid prototype errors. */
typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
-/* Generic routine to add a single symbol. */
-extern bool _bfd_generic_link_add_one_symbol
- (struct bfd_link_info *, bfd *, const char *name, flagword,
- asection *, bfd_vma, const char *, bool copy,
- bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN;
-
/* Generic routine to mark section as supplying symbols only. */
extern void _bfd_generic_link_just_syms
(asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 4f6f5ea..d367fea 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -651,12 +651,6 @@ extern bool _bfd_generic_link_add_archive_symbols
/* Forward declaration to avoid prototype errors. */
typedef struct bfd_link_hash_entry _bfd_link_hash_entry;
-/* Generic routine to add a single symbol. */
-extern bool _bfd_generic_link_add_one_symbol
- (struct bfd_link_info *, bfd *, const char *name, flagword,
- asection *, bfd_vma, const char *, bool copy,
- bool constructor, struct bfd_link_hash_entry **) ATTRIBUTE_HIDDEN;
-
/* Generic routine to mark section as supplying symbols only. */
extern void _bfd_generic_link_just_syms
(asection *, struct bfd_link_info *) ATTRIBUTE_HIDDEN;
diff --git a/bfd/libcoff.h b/bfd/libcoff.h
index d0cfd09..05ebe35 100644
--- a/bfd/libcoff.h
+++ b/bfd/libcoff.h
@@ -864,11 +864,6 @@ typedef struct
(bfd *, struct bfd_link_info *, bfd *, asection *,
struct internal_reloc *, bool *);
- bool (*_bfd_coff_link_add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword,
- asection *, bfd_vma, const char *, bool, bool,
- struct bfd_link_hash_entry **);
-
bool (*_bfd_coff_link_output_has_begun)
(bfd *, struct coff_final_link_info *);
@@ -1005,10 +1000,6 @@ typedef struct
#define bfd_coff_adjust_symndx(obfd, info, ibfd, sec, rel, adjustedp)\
((coff_backend_info (abfd)->_bfd_coff_adjust_symndx)\
(obfd, info, ibfd, sec, rel, adjustedp))
-#define bfd_coff_link_add_one_symbol(info, abfd, name, flags, section,\
- value, string, cp, coll, hashp)\
- ((coff_backend_info (abfd)->_bfd_coff_link_add_one_symbol)\
- (info, abfd, name, flags, section, value, string, cp, coll, hashp))
#define bfd_coff_link_output_has_begun(a,p) \
((coff_backend_info (a)->_bfd_coff_link_output_has_begun) (a, p))
diff --git a/bfd/linker.c b/bfd/linker.c
index 2a4b8f0..a9a23e5 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1378,7 +1378,25 @@ hash_entry_bfd (struct bfd_link_hash_entry *h)
/*NOTREACHED*/
}
-/* Add a symbol to the global hash table.
+/*
+FUNCTION
+ _bfd_generic_link_add_one_symbol
+
+SYNOPSIS
+ bool _bfd_generic_link_add_one_symbol
+ (struct bfd_link_info *info,
+ bfd *abfd,
+ const char *name,
+ flagword flags,
+ asection *section,
+ bfd_vma value,
+ const char *string,
+ bool copy,
+ bool collect,
+ struct bfd_link_hash_entry **hashp);
+
+DESCRIPTION
+ Add a symbol to the global hash table.
ABFD is the BFD the symbol comes from.
NAME is the name of the symbol.
FLAGS is the BSF_* bits associated with the symbol.
diff --git a/bfd/pdp11.c b/bfd/pdp11.c
index bdd9fc2..2d12033 100644
--- a/bfd/pdp11.c
+++ b/bfd/pdp11.c
@@ -2839,9 +2839,6 @@ aout_link_check_archive_element (bfd *abfd,
static bool
aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
{
- bool (*add_one_symbol)
- (struct bfd_link_info *, bfd *, const char *, flagword, asection *,
- bfd_vma, const char *, bool, bool, struct bfd_link_hash_entry **);
struct external_nlist *syms;
bfd_size_type sym_count;
char *strings;
@@ -2875,10 +2872,6 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
return false;
obj_aout_sym_hashes (abfd) = sym_hash;
- add_one_symbol = aout_backend_info (abfd)->add_one_symbol;
- if (add_one_symbol == NULL)
- add_one_symbol = _bfd_generic_link_add_one_symbol;
-
p = syms;
pend = p + sym_count;
for (; p < pend; p++, sym_hash++)
@@ -2951,7 +2944,7 @@ aout_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
break;
}
- if (! ((*add_one_symbol)
+ if (! (_bfd_generic_link_add_one_symbol
(info, abfd, name, flags, section, value, string, copy, false,
(struct bfd_link_hash_entry **) sym_hash)))
return false;
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 2901268..9938108 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -593,7 +593,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
struct internal_extra_pe_aouthdr *extra = &pe->pe_opthdr;
PEAOUTHDR *aouthdr_out = (PEAOUTHDR *) out;
bfd_vma sa, fa, ib;
- IMAGE_DATA_DIRECTORY idata2, idata5, tls;
+ IMAGE_DATA_DIRECTORY idata2, idata5, tls, loadcfg;
sa = extra->SectionAlignment;
fa = extra->FileAlignment;
@@ -602,6 +602,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
idata2 = pe->pe_opthdr.DataDirectory[PE_IMPORT_TABLE];
idata5 = pe->pe_opthdr.DataDirectory[PE_IMPORT_ADDRESS_TABLE];
tls = pe->pe_opthdr.DataDirectory[PE_TLS_TABLE];
+ loadcfg = pe->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE];
if (aouthdr_in->tsize)
{
@@ -651,6 +652,7 @@ _bfd_XXi_swap_aouthdr_out (bfd * abfd, void * in, void * out)
extra->DataDirectory[PE_IMPORT_TABLE] = idata2;
extra->DataDirectory[PE_IMPORT_ADDRESS_TABLE] = idata5;
extra->DataDirectory[PE_TLS_TABLE] = tls;
+ extra->DataDirectory[PE_LOAD_CONFIG_TABLE] = loadcfg;
if (extra->DataDirectory[PE_IMPORT_TABLE].VirtualAddress == 0)
/* Until other .idata fixes are made (pending patch), the entry for
@@ -4403,6 +4405,7 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
struct coff_link_hash_entry *h1;
struct bfd_link_info *info = pfinfo->info;
bool result = true;
+ char name[20];
/* There are a few fields that need to be filled in now while we
have symbol table access.
@@ -4430,8 +4433,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[1] because .idata$2 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_TABLE, ".idata$2");
result = false;
}
@@ -4450,8 +4453,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[1] because .idata$4 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_TABLE, ".idata$4");
result = false;
}
@@ -4471,8 +4474,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[12] because .idata$5 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$5");
result = false;
}
@@ -4491,8 +4494,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE (12)] because .idata$6 is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s is missing"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, ".idata$6");
result = false;
}
}
@@ -4533,17 +4536,16 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[PE_IMPORT_ADDRESS_TABLE(12)]"
- " because .idata$6 is missing"), abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_IMPORT_ADDRESS_TABLE, "__IAT_end__");
result = false;
}
}
}
- h1 = coff_link_hash_lookup (coff_hash_table (info),
- (bfd_get_symbol_leading_char (abfd) != 0
- ? "__tls_used" : "_tls_used"),
- false, false, true);
+ name[0] = bfd_get_symbol_leading_char (abfd);
+ strcpy (name + !!name[0], "_tls_used");
+ h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true);
if (h1 != NULL)
{
if ((h1->root.type == bfd_link_hash_defined
@@ -4558,8 +4560,8 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
else
{
_bfd_error_handler
- (_("%pB: unable to fill in DataDictionary[9] because __tls_used is missing"),
- abfd);
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_TLS_TABLE, name);
result = false;
}
/* According to PECOFF sepcifications by Microsoft version 8.2
@@ -4573,6 +4575,81 @@ _bfd_XXi_final_link_postscript (bfd * abfd, struct coff_final_link_info *pfinfo)
#endif
}
+ name[0] = bfd_get_symbol_leading_char (abfd);
+ strcpy (name + !!name[0], "_load_config_used");
+ h1 = coff_link_hash_lookup (coff_hash_table (info), name, false, false, true);
+ if (h1 != NULL)
+ {
+ char data[4];
+ if ((h1->root.type == bfd_link_hash_defined
+ || h1->root.type == bfd_link_hash_defweak)
+ && h1->root.u.def.section != NULL
+ && h1->root.u.def.section->output_section != NULL)
+ {
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress =
+ (h1->root.u.def.value
+ + h1->root.u.def.section->output_section->vma
+ + h1->root.u.def.section->output_offset
+ - pe_data (abfd)->pe_opthdr.ImageBase);
+
+ if (pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].VirtualAddress
+ & (bfd_arch_bits_per_address (abfd) / bfd_arch_bits_per_byte (abfd)
+ - 1))
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not properly aligned"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+
+ /* The size is stored as the first 4 bytes at _load_config_used. */
+ if (bfd_get_section_contents (abfd,
+ h1->root.u.def.section->output_section, data,
+ h1->root.u.def.section->output_offset + h1->root.u.def.value,
+ 4))
+ {
+ uint32_t size = bfd_get_32 (abfd, data);
+ /* The Microsoft PE format documentation says for compatibility
+ with Windows XP and earlier, the size must be 64 for x86
+ images. */
+ pe_data (abfd)->pe_opthdr.DataDirectory[PE_LOAD_CONFIG_TABLE].Size
+ = (bfd_get_arch (abfd) == bfd_arch_i386
+ && ((bfd_get_mach (abfd) & ~bfd_mach_i386_intel_syntax)
+ == bfd_mach_i386_i386)
+ && ((pe_data (abfd)->pe_opthdr.Subsystem
+ == IMAGE_SUBSYSTEM_WINDOWS_GUI)
+ || (pe_data (abfd)->pe_opthdr.Subsystem
+ == IMAGE_SUBSYSTEM_WINDOWS_CUI))
+ && (pe_data (abfd)->pe_opthdr.MajorSubsystemVersion * 256
+ + pe_data (abfd)->pe_opthdr.MinorSubsystemVersion
+ <= 0x0501))
+ ? 64 : size;
+
+ if (size > h1->root.u.def.section->size - h1->root.u.def.value)
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: size too large for the containing section"),
+ abfd, PE_LOAD_CONFIG_TABLE);
+ result = false;
+ }
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: size can't be read from %s"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+ }
+ else
+ {
+ _bfd_error_handler
+ (_("%pB: unable to fill in DataDirectory[%d]: %s not defined correctly"),
+ abfd, PE_LOAD_CONFIG_TABLE, name);
+ result = false;
+ }
+ }
+
/* If there is a .pdata section and we have linked pdata finally, we
need to sort the entries ascending. */
#if !defined(COFF_WITH_pep) && (defined(COFF_WITH_pex64) || defined(COFF_WITH_peAArch64) || defined(COFF_WITH_peLoongArch64) || defined (COFF_WITH_peRiscV64))
diff --git a/bfd/version.h b/bfd/version.h
index 8cb9007..532112c 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -16,7 +16,7 @@
In releases, the date is not included in either version strings or
sonames. */
-#define BFD_VERSION_DATE 20250403
+#define BFD_VERSION_DATE 20250415
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_package@ @bfd_version_string@
#define REPORT_BUGS_TO @report_bugs_to@
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c
index 446fa5a..b50b17f 100644
--- a/bfd/xcofflink.c
+++ b/bfd/xcofflink.c
@@ -243,6 +243,55 @@ xcoff_get_section_contents (bfd *abfd, asection *sec)
return contents;
}
+/* Read .loader and swap in the header. Sanity check to prevent
+ buffer overflows. Don't bother to check for overlap as that sort
+ of insanity shouldn't lead to incorrect program behaviour. */
+
+static bfd_byte *
+xcoff_get_ldhdr (bfd *abfd, asection *lsec, struct internal_ldhdr *ldhdr)
+{
+ bfd_byte *contents = xcoff_get_section_contents (abfd, lsec);
+ if (contents)
+ {
+ bfd_xcoff_swap_ldhdr_in (abfd, contents, ldhdr);
+ if (ldhdr->l_nsyms != 0)
+ {
+ bfd_vma symoff = bfd_xcoff_loader_symbol_offset (abfd, ldhdr);
+ if (symoff > lsec->size)
+ goto fail;
+ bfd_size_type onesym = bfd_xcoff_ldsymsz (abfd);
+ bfd_size_type syms;
+ if (_bfd_mul_overflow (ldhdr->l_nsyms, onesym, &syms)
+ || syms > lsec->size - symoff)
+ goto fail;
+ }
+ if (ldhdr->l_stlen != 0
+ && (ldhdr->l_stoff > lsec->size
+ || ldhdr->l_stlen > lsec->size - ldhdr->l_stoff))
+ goto fail;
+ if (ldhdr->l_nreloc != 0)
+ {
+ bfd_vma reloff = bfd_xcoff_loader_reloc_offset (abfd, ldhdr);
+ if (reloff > lsec->size)
+ goto fail;
+ bfd_size_type onerel = bfd_xcoff_ldrelsz (abfd);
+ bfd_size_type rels;
+ if (_bfd_mul_overflow (ldhdr->l_nreloc, onerel, &rels)
+ || rels > lsec->size - reloff)
+ goto fail;
+ }
+ if (ldhdr->l_nimpid != 0
+ && (ldhdr->l_impoff > lsec->size
+ || ldhdr->l_istlen > lsec->size - ldhdr->l_impoff))
+ goto fail;
+ }
+ return contents;
+
+ fail:
+ bfd_set_error (bfd_error_file_truncated);
+ return NULL;
+}
+
/* Get the size required to hold the dynamic symbols. */
long
@@ -265,12 +314,10 @@ _bfd_xcoff_get_dynamic_symtab_upper_bound (bfd *abfd)
return -1;
}
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return -1;
- bfd_xcoff_swap_ldhdr_in (abfd, (void *) contents, &ldhdr);
-
return (ldhdr.l_nsyms + 1) * sizeof (asymbol *);
}
@@ -299,12 +346,10 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms)
return -1;
}
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return -1;
- bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
-
strings = (char *) contents + ldhdr.l_stoff;
symbuf = bfd_zalloc (abfd, ldhdr.l_nsyms * sizeof (* symbuf));
@@ -322,9 +367,7 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms)
symbuf->symbol.the_bfd = abfd;
- if (ldsym._l._l_l._l_zeroes == 0)
- symbuf->symbol.name = strings + ldsym._l._l_l._l_offset;
- else
+ if (ldsym._l._l_l._l_zeroes != 0)
{
char *c;
@@ -335,6 +378,10 @@ _bfd_xcoff_canonicalize_dynamic_symtab (bfd *abfd, asymbol **psyms)
c[SYMNMLEN] = '\0';
symbuf->symbol.name = c;
}
+ else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen)
+ symbuf->symbol.name = strings + ldsym._l._l_l._l_offset;
+ else
+ symbuf->symbol.name = _("<corrupt>");
if (ldsym.l_smclas == XMC_XO)
symbuf->symbol.section = bfd_abs_section_ptr;
@@ -384,12 +431,10 @@ _bfd_xcoff_get_dynamic_reloc_upper_bound (bfd *abfd)
return -1;
}
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return -1;
- bfd_xcoff_swap_ldhdr_in (abfd, (struct external_ldhdr *) contents, &ldhdr);
-
return (ldhdr.l_nreloc + 1) * sizeof (arelent *);
}
@@ -419,12 +464,10 @@ _bfd_xcoff_canonicalize_dynamic_reloc (bfd *abfd,
return -1;
}
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return -1;
- bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
-
relbuf = bfd_alloc (abfd, ldhdr.l_nreloc * sizeof (arelent));
if (relbuf == NULL)
return -1;
@@ -905,7 +948,7 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
return false;
}
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return false;
@@ -913,8 +956,6 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
included in the link. */
bfd_section_list_clear (abfd);
- bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
-
strings = (char *) contents + ldhdr.l_stoff;
elsym = contents + bfd_xcoff_loader_symbol_offset(abfd, &ldhdr);
@@ -934,14 +975,16 @@ xcoff_link_add_dynamic_symbols (bfd *abfd, struct bfd_link_info *info)
if ((ldsym.l_smtype & L_EXPORT) == 0)
continue;
- if (ldsym._l._l_l._l_zeroes == 0)
- name = strings + ldsym._l._l_l._l_offset;
- else
+ if (ldsym._l._l_l._l_zeroes != 0)
{
memcpy (nambuf, ldsym._l._l_name, SYMNMLEN);
nambuf[SYMNMLEN] = '\0';
name = nambuf;
}
+ else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen)
+ name = strings + ldsym._l._l_l._l_offset;
+ else
+ continue;
/* Normally we could not call xcoff_link_hash_lookup in an add
symbols routine, since we might not be using an XCOFF hash
@@ -2368,12 +2411,10 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
/* There are no symbols, so don't try to include it. */
return true;
- contents = xcoff_get_section_contents (abfd, lsec);
+ contents = xcoff_get_ldhdr (abfd, lsec, &ldhdr);
if (!contents)
return false;
- bfd_xcoff_swap_ldhdr_in (abfd, contents, &ldhdr);
-
strings = (char *) contents + ldhdr.l_stoff;
elsym = contents + bfd_xcoff_loader_symbol_offset (abfd, &ldhdr);
@@ -2392,14 +2433,16 @@ xcoff_link_check_dynamic_ar_symbols (bfd *abfd,
if ((ldsym.l_smtype & L_EXPORT) == 0)
continue;
- if (ldsym._l._l_l._l_zeroes == 0)
- name = strings + ldsym._l._l_l._l_offset;
- else
+ if (ldsym._l._l_l._l_zeroes != 0)
{
memcpy (nambuf, ldsym._l._l_name, SYMNMLEN);
nambuf[SYMNMLEN] = '\0';
name = nambuf;
}
+ else if (ldsym._l._l_l._l_offset < ldhdr.l_stlen)
+ name = strings + ldsym._l._l_l._l_offset;
+ else
+ continue;
h = bfd_link_hash_lookup (info->hash, name, false, false, true);