You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
+
/* ELF linker code. */
static boolean elf_link_add_object_symbols
continue;
if (h->root.type != bfd_link_hash_undefined)
{
- defined[i] = true;
+ if (h->root.type != bfd_link_hash_undefweak)
+ defined[i] = true;
continue;
}
int elfsec;
unsigned long link;
- dynbuf = (Elf_External_Dyn *) malloc (s->_raw_size);
+ dynbuf = (Elf_External_Dyn *) malloc ((size_t) s->_raw_size);
if (dynbuf == NULL)
{
bfd_set_error (bfd_error_no_memory);
struct bfd_elf_link_needed_list *n, **pn;
char *fnm, *anm;
- n = bfd_alloc (abfd,
- sizeof (struct bfd_elf_link_needed_list));
+ n = (struct bfd_elf_link_needed_list *)
+ bfd_alloc (abfd,
+ sizeof (struct bfd_elf_link_needed_list));
fnm = bfd_elf_string_from_elf_section (abfd, link,
dyn.d_un.d_val);
if (n == NULL || fnm == NULL)
const char *name;
struct elf_link_hash_entry *h = NULL;
boolean definition;
+ boolean new_weakdef;
elf_swap_symbol_in (abfd, esym, &sym);
false, collect, (struct bfd_link_hash_entry **) sym_hash)))
goto error_return;
+ new_weakdef = false;
if (dynamic
&& definition
&& (flags & BSF_WEAK) != 0
(*sym_hash)->weakdef = weaks;
weaks = *sym_hash;
+ new_weakdef = true;
}
/* Get the alignment of a common symbol. */
new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
if ((old_flags & new_flag) != 0
|| (old_flags & (ELF_LINK_HASH_DEF_REGULAR
- | ELF_LINK_HASH_REF_REGULAR)) != 0)
+ | ELF_LINK_HASH_REF_REGULAR)) != 0
+ || (h->weakdef != NULL
+ && (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_REF_DYNAMIC)) != 0))
dynsym = true;
}
{
if (! _bfd_elf_link_record_dynamic_symbol (info, h))
goto error_return;
+ if (h->weakdef != NULL
+ && ! new_weakdef
+ && h->weakdef->dynindx == -1)
+ {
+ if (! _bfd_elf_link_record_dynamic_symbol (info,
+ h->weakdef))
+ goto error_return;
+ }
}
}
}
if (external_relocs == NULL)
{
- alloc1 = (PTR) malloc (rel_hdr->sh_size);
+ alloc1 = (PTR) malloc ((size_t) rel_hdr->sh_size);
if (alloc1 == NULL)
{
bfd_set_error (bfd_error_no_memory);
bfd_set_error (bfd_error_no_memory);
return false;
}
- memset (s->contents, 0, s->_raw_size);
+ memset (s->contents, 0, (size_t) s->_raw_size);
put_word (output_bfd, bucketcount, s->contents);
put_word (output_bfd, dynsymcount, s->contents + (ARCH_SIZE / 8));
/* If this symbol does not require a PLT entry, and it is not
defined by a dynamic object, or is not referenced by a regular
- object, ignore it. FIXME: Do we need to worry about symbols
- which are defined by one dynamic object and referenced by another
- one? */
+ object, ignore it. We do have to handle a weak defined symbol,
+ even if no regular object refers to it, if we decided to add it
+ to the dynamic symbol table. FIXME: Do we normally need to worry
+ about symbols which are defined by one dynamic object and
+ referenced by another one? */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
- || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0))
+ || ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
+ && (h->weakdef == NULL || h->weakdef->dynindx == -1))))
return true;
/* If we've already adjusted this symbol, don't do it again. This