X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=bfd%2Felflink.c;h=f9f804de739dcf0ffefbd18cac767f036bc50222;hb=bde6f3eb6dff94cea1d471e15c6154d55d49820f;hp=d6534f768dea26b3781e16763a691262f0026824;hpb=5dabe7859c287d7cd4ab695c5d6f511336a1031e;p=deliverable%2Fbinutils-gdb.git diff --git a/bfd/elflink.c b/bfd/elflink.c index d6534f768d..f9f804de73 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1,6 +1,6 @@ /* ELF linking support for BFD. Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009 + 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -185,7 +185,7 @@ bfd_boolean _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) { flagword flags; - register asection *s; + asection *s; const struct elf_backend_data *bed; if (! is_elf_hash_table (info->hash)) @@ -570,8 +570,7 @@ bfd_elf_record_link_assignment (bfd *output_bfd, if (provide && hidden) { - const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - + bed = get_elf_backend_data (output_bfd); h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_HIDDEN; (*bed->elf_backend_hide_symbol) (info, h, TRUE); } @@ -634,7 +633,7 @@ bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, return 1; amt = sizeof (*entry); - entry = bfd_alloc (input_bfd, amt); + entry = (struct elf_link_local_dynamic_entry *) bfd_alloc (input_bfd, amt); if (entry == NULL) return 0; @@ -719,7 +718,7 @@ static bfd_boolean elf_link_renumber_hash_table_dynsyms (struct elf_link_hash_entry *h, void *data) { - size_t *count = data; + size_t *count = (size_t *) data; if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; @@ -741,7 +740,7 @@ static bfd_boolean elf_link_renumber_local_hash_table_dynsyms (struct elf_link_hash_entry *h, void *data) { - size_t *count = data; + size_t *count = (size_t *) data; if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; @@ -1184,9 +1183,8 @@ _bfd_elf_merge_symbol (bfd *abfd, was referenced before. */ if (h->ref_regular) { - const struct elf_backend_data *bed - = get_elf_backend_data (abfd); struct elf_link_hash_entry *vh = *sym_hash; + vh->root.type = h->root.type; h->root.type = bfd_link_hash_indirect; (*bed->elf_backend_copy_indirect_symbol) (info, vh, h); @@ -1548,7 +1546,6 @@ _bfd_elf_merge_symbol (bfd *abfd, /* Handle the case where we had a versioned symbol in a dynamic library and now find a definition in a normal object. In this case, we make the versioned symbol point to the normal one. */ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); flip->root.type = h->root.type; flip->root.u.undef.abfd = h->root.u.undef.abfd; h->root.type = bfd_link_hash_indirect; @@ -1624,7 +1621,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, dynamic = (abfd->flags & DYNAMIC) != 0; shortlen = p - name; - shortname = bfd_hash_allocate (&info->hash->table, shortlen + 1); + shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1); if (shortname == NULL) return FALSE; memcpy (shortname, name, shortlen); @@ -1735,7 +1732,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, nondefault: len = strlen (name); - shortname = bfd_hash_allocate (&info->hash->table, len); + shortname = (char *) bfd_hash_allocate (&info->hash->table, len); if (shortname == NULL) return FALSE; memcpy (shortname, name, shortlen); @@ -1809,7 +1806,7 @@ nondefault: static bfd_boolean _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) { - struct elf_info_failed *eif = data; + struct elf_info_failed *eif = (struct elf_info_failed *) data; /* Ignore this if we won't export it. */ if (!eif->info->export_dynamic && !h->dynamic) @@ -1852,7 +1849,7 @@ static bfd_boolean _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, void *data) { - struct elf_find_verdep_info *rinfo = data; + struct elf_find_verdep_info *rinfo = (struct elf_find_verdep_info *) data; Elf_Internal_Verneed *t; Elf_Internal_Vernaux *a; bfd_size_type amt; @@ -1888,7 +1885,7 @@ _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, if (t == NULL) { amt = sizeof *t; - t = bfd_zalloc (rinfo->info->output_bfd, amt); + t = (Elf_Internal_Verneed *) bfd_zalloc (rinfo->info->output_bfd, amt); if (t == NULL) { rinfo->failed = TRUE; @@ -1901,7 +1898,7 @@ _bfd_elf_link_find_version_dependencies (struct elf_link_hash_entry *h, } amt = sizeof *a; - a = bfd_zalloc (rinfo->info->output_bfd, amt); + a = (Elf_Internal_Vernaux *) bfd_zalloc (rinfo->info->output_bfd, amt); if (a == NULL) { rinfo->failed = TRUE; @@ -1942,7 +1939,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) char *p; bfd_size_type amt; - sinfo = data; + sinfo = (struct elf_info_failed *) data; info = sinfo->info; if (h->root.type == bfd_link_hash_warning) @@ -1999,7 +1996,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) struct bfd_elf_version_expr *d; len = p - h->root.root.string; - alc = bfd_malloc (len); + alc = (char *) bfd_malloc (len); if (alc == NULL) { sinfo->failed = TRUE; @@ -2046,7 +2043,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data) return TRUE; amt = sizeof *t; - t = bfd_zalloc (info->output_bfd, amt); + t = (struct bfd_elf_version_tree *) bfd_zalloc (info->output_bfd, amt); if (t == NULL) { sinfo->failed = TRUE; @@ -2148,7 +2145,7 @@ elf_link_read_relocs_from_section (bfd *abfd, return FALSE; } - erela = external_relocs; + erela = (const bfd_byte *) external_relocs; erelaend = erela + shdr->sh_size; irela = internal_relocs; while (erela < erelaend) @@ -2226,9 +2223,9 @@ _bfd_elf_link_read_relocs (bfd *abfd, size = o->reloc_count; size *= bed->s->int_rels_per_ext_rel * sizeof (Elf_Internal_Rela); if (keep_memory) - internal_relocs = alloc2 = bfd_alloc (abfd, size); + internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_alloc (abfd, size); else - internal_relocs = alloc2 = bfd_malloc (size); + internal_relocs = alloc2 = (Elf_Internal_Rela *) bfd_malloc (size); if (internal_relocs == NULL) goto error_return; } @@ -2311,7 +2308,7 @@ _bfd_elf_link_size_reloc_section (bfd *abfd, allocate it with bfd_alloc rather than malloc. Also since we cannot be sure that the contents will actually be filled in, we zero the allocated space. */ - rel_hdr->contents = bfd_zalloc (abfd, rel_hdr->sh_size); + rel_hdr->contents = (unsigned char *) bfd_zalloc (abfd, rel_hdr->sh_size); if (rel_hdr->contents == NULL && rel_hdr->sh_size != 0) return FALSE; @@ -2322,7 +2319,8 @@ _bfd_elf_link_size_reloc_section (bfd *abfd, { struct elf_link_hash_entry **p; - p = bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *)); + p = (struct elf_link_hash_entry **) + bfd_zmalloc (num_rel_hashes * sizeof (struct elf_link_hash_entry *)); if (p == NULL) return FALSE; @@ -2571,7 +2569,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, static bfd_boolean _bfd_elf_adjust_dynamic_symbol (struct elf_link_hash_entry *h, void *data) { - struct elf_info_failed *eif = data; + struct elf_info_failed *eif = (struct elf_info_failed *) data; bfd *dynobj; const struct elf_backend_data *bed; @@ -2752,7 +2750,7 @@ _bfd_elf_link_sec_merge_syms (struct elf_link_hash_entry *h, void *data) && ((sec = h->root.u.def.section)->flags & SEC_MERGE) && sec->sec_info_type == ELF_INFO_TYPE_MERGE) { - bfd *output_bfd = data; + bfd *output_bfd = (bfd *) data; h->root.u.def.value = _bfd_merged_section_offset (output_bfd, @@ -3067,7 +3065,7 @@ _bfd_elf_add_dynamic_entry (struct bfd_link_info *info, BFD_ASSERT (s != NULL); newsize = s->size + bed->s->sizeof_dyn; - newcontents = bfd_realloc (s->contents, newsize); + newcontents = (bfd_byte *) bfd_realloc (s->contents, newsize); if (newcontents == NULL) return FALSE; @@ -3182,7 +3180,7 @@ elf_sort_symbol (const void *arg1, const void *arg2) static bfd_boolean elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data) { - struct elf_strtab_hash *dynstr = data; + struct elf_strtab_hash *dynstr = (struct elf_strtab_hash *) data; if (h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; @@ -3233,6 +3231,8 @@ elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info) case DT_RUNPATH: case DT_FILTER: case DT_AUXILIARY: + case DT_AUDIT: + case DT_DEPAUDIT: dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val); break; default: @@ -3473,7 +3473,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) } sz = s->size; - msg = bfd_alloc (abfd, sz + 1); + msg = (char *) bfd_alloc (abfd, sz + 1); if (msg == NULL) goto error_return; @@ -3524,6 +3524,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) { asection *s; const char *soname = NULL; + char *audit = NULL; struct bfd_link_needed_list *rpath = NULL, *runpath = NULL; int ret; @@ -3585,12 +3586,12 @@ error_free_dyn: unsigned int tagv = dyn.d_un.d_val; amt = sizeof (struct bfd_link_needed_list); - n = bfd_alloc (abfd, amt); + n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); if (n == NULL || fnm == NULL) goto error_free_dyn; amt = strlen (fnm) + 1; - anm = bfd_alloc (abfd, amt); + anm = (char *) bfd_alloc (abfd, amt); if (anm == NULL) goto error_free_dyn; memcpy (anm, fnm, amt); @@ -3608,12 +3609,12 @@ error_free_dyn: unsigned int tagv = dyn.d_un.d_val; amt = sizeof (struct bfd_link_needed_list); - n = bfd_alloc (abfd, amt); + n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); if (n == NULL || fnm == NULL) goto error_free_dyn; amt = strlen (fnm) + 1; - anm = bfd_alloc (abfd, amt); + anm = (char *) bfd_alloc (abfd, amt); if (anm == NULL) goto error_free_dyn; memcpy (anm, fnm, amt); @@ -3634,12 +3635,12 @@ error_free_dyn: unsigned int tagv = dyn.d_un.d_val; amt = sizeof (struct bfd_link_needed_list); - n = bfd_alloc (abfd, amt); + n = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv); if (n == NULL || fnm == NULL) goto error_free_dyn; amt = strlen (fnm) + 1; - anm = bfd_alloc (abfd, amt); + anm = (char *) bfd_alloc (abfd, amt); if (anm == NULL) goto error_free_dyn; memcpy (anm, fnm, amt); @@ -3652,6 +3653,11 @@ error_free_dyn: ; *pn = n; } + if (dyn.d_tag == DT_AUDIT) + { + unsigned int tagv = dyn.d_un.d_val; + audit = bfd_elf_string_from_elf_section (abfd, shlink, tagv); + } } free (dynbuf); @@ -3704,6 +3710,9 @@ error_free_dyn: particular dynamic object more than once. */ if (ret > 0) return TRUE; + + /* Save the DT_AUDIT entry for the linker emulation code. */ + elf_dt_audit (abfd) = audit; } /* If this is a dynamic object, we always link against the .dynsym @@ -3743,7 +3752,7 @@ error_free_dyn: /* We store a pointer to the hash table entry for each external symbol. */ amt = extsymcount * sizeof (struct elf_link_hash_entry *); - sym_hash = bfd_alloc (abfd, amt); + sym_hash = (struct elf_link_hash_entry **) bfd_alloc (abfd, amt); if (sym_hash == NULL) goto error_free_sym; elf_sym_hashes (abfd) = sym_hash; @@ -3763,7 +3772,7 @@ error_free_dyn: Elf_Internal_Shdr *versymhdr; versymhdr = &elf_tdata (abfd)->dynversym_hdr; - extversym = bfd_malloc (versymhdr->sh_size); + extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size); if (extversym == NULL) goto error_free_sym; amt = versymhdr->sh_size; @@ -3865,6 +3874,7 @@ error_free_dyn: bfd_boolean common; unsigned int old_alignment; bfd *old_bfd; + bfd * undef_bfd = NULL; override = FALSE; @@ -4079,7 +4089,7 @@ error_free_dyn: && isym->st_shndx != SHN_UNDEF) ++newlen; - newname = bfd_hash_allocate (&htab->root.table, newlen); + newname = (char *) bfd_hash_allocate (&htab->root.table, newlen); if (newname == NULL) goto error_free_vers; memcpy (newname, name, namelen); @@ -4096,6 +4106,20 @@ error_free_dyn: name = newname; } + /* If this is a definition of a previously undefined symbol + make a note of the bfd that contained the reference in + case we need to refer to it later on in error messages. */ + if (! bfd_is_und_section (sec)) + { + h = elf_link_hash_lookup (elf_hash_table (info), name, FALSE, FALSE, FALSE); + + if (h != NULL + && (h->root.type == bfd_link_hash_undefined + || h->root.type == bfd_link_hash_undefweak) + && h->root.u.undef.abfd) + undef_bfd = h->root.u.undef.abfd; + } + if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value, &old_alignment, sym_hash, &skip, &override, @@ -4361,7 +4385,6 @@ error_free_dyn: if (definition && (sec->flags & SEC_DEBUGGING) && !info->relocatable) { /* We don't want to make debug symbol dynamic. */ - (*bed->elf_backend_hide_symbol) (info, h, TRUE); dynsym = FALSE; } @@ -4384,7 +4407,8 @@ error_free_dyn: { amt = ((isymend - isym + 1) * sizeof (struct elf_link_hash_entry *)); - nondeflt_vers = bfd_malloc (amt); + nondeflt_vers = + (struct elf_link_hash_entry **) bfd_malloc (amt); if (!nondeflt_vers) goto error_free_vers; } @@ -4435,13 +4459,17 @@ error_free_dyn: if ((elf_dyn_lib_class (abfd) & DYN_NO_NEEDED) != 0) { (*_bfd_error_handler) - (_("%s: invalid DSO for symbol `%s' definition"), + (_("%B: undefined reference to symbol '%s'"), + undef_bfd == NULL ? info->output_bfd : undef_bfd, name); + (*_bfd_error_handler) + (_("note: '%s' is defined in DSO %B so try adding it to the linker command line"), abfd, name); - bfd_set_error (bfd_error_bad_value); + bfd_set_error (bfd_error_invalid_operation); goto error_free_vers; } - elf_dyn_lib_class (abfd) &= ~DYN_AS_NEEDED; + elf_dyn_lib_class (abfd) = (enum dynamic_lib_link_class) + (elf_dyn_lib_class (abfd) & ~DYN_AS_NEEDED); add_needed = TRUE; ret = elf_add_dt_needed_tag (abfd, info, soname, add_needed); @@ -4547,7 +4575,7 @@ error_free_dyn: continue; amt = p - h->root.root.string; - shortname = bfd_malloc (amt + 1); + shortname = (char *) bfd_malloc (amt + 1); if (!shortname) goto error_free_vers; memcpy (shortname, h->root.root.string, amt); @@ -4605,7 +4633,7 @@ error_free_dyn: defined symbol, search time for N weak defined symbols will be O(N^2). Binary search will cut it down to O(NlogN). */ amt = extsymcount * sizeof (struct elf_link_hash_entry *); - sorted_sym_hash = bfd_malloc (amt); + sorted_sym_hash = (struct elf_link_hash_entry **) bfd_malloc (amt); if (sorted_sym_hash == NULL) goto error_return; sym_hash = sorted_sym_hash; @@ -4818,7 +4846,8 @@ error_free_dyn: /* Add this bfd to the loaded list. */ struct elf_link_loaded_list *n; - n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list)); + n = (struct elf_link_loaded_list *) + bfd_alloc (abfd, sizeof (struct elf_link_loaded_list)); if (n == NULL) goto error_return; n->abfd = abfd; @@ -4869,7 +4898,7 @@ _bfd_elf_archive_symbol_lookup (bfd *abfd, /* First check with only one `@'. */ len = strlen (name); - copy = bfd_alloc (abfd, len); + copy = (char *) bfd_alloc (abfd, len); if (copy == NULL) return (struct elf_link_hash_entry *) 0 - 1; @@ -4946,8 +4975,8 @@ elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info) return TRUE; amt = c; amt *= sizeof (bfd_boolean); - defined = bfd_zmalloc (amt); - included = bfd_zmalloc (amt); + defined = (bfd_boolean *) bfd_zmalloc (amt); + included = (bfd_boolean *) bfd_zmalloc (amt); if (defined == NULL || included == NULL) goto error_return; @@ -5111,7 +5140,7 @@ struct hash_codes_info static bfd_boolean elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) { - struct hash_codes_info *inf = data; + struct hash_codes_info *inf = (struct hash_codes_info *) data; const char *name; char *p; unsigned long ha; @@ -5128,7 +5157,7 @@ elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data) p = strchr (name, ELF_VER_CHR); if (p != NULL) { - alc = bfd_malloc (p - name + 1); + alc = (char *) bfd_malloc (p - name + 1); if (alc == NULL) { inf->error = TRUE; @@ -5182,7 +5211,7 @@ struct collect_gnu_hash_codes static bfd_boolean elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) { - struct collect_gnu_hash_codes *s = data; + struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; const char *name; char *p; unsigned long ha; @@ -5203,7 +5232,7 @@ elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) p = strchr (name, ELF_VER_CHR); if (p != NULL) { - alc = bfd_malloc (p - name + 1); + alc = (char *) bfd_malloc (p - name + 1); if (alc == NULL) { s->error = TRUE; @@ -5237,7 +5266,7 @@ elf_collect_gnu_hash_codes (struct elf_link_hash_entry *h, void *data) static bfd_boolean elf_renumber_gnu_hash_syms (struct elf_link_hash_entry *h, void *data) { - struct collect_gnu_hash_codes *s = data; + struct collect_gnu_hash_codes *s = (struct collect_gnu_hash_codes *) data; unsigned long int bucket; unsigned long int val; @@ -5349,7 +5378,7 @@ compute_bucket_count (struct bfd_link_info *info, since the size could be large. */ amt = maxsize; amt *= sizeof (unsigned long int); - counts = bfd_malloc (amt); + counts = (unsigned long int *) bfd_malloc (amt); if (counts == NULL) return 0; @@ -5447,6 +5476,8 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, const char *soname, const char *rpath, const char *filter_shlib, + const char *audit, + const char *depaudit, const char * const *auxiliary_filters, struct bfd_link_info *info, asection **sinterpptr, @@ -5599,6 +5630,28 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } } + if (audit != NULL) + { + bfd_size_type indx; + + indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, audit, + TRUE); + if (indx == (bfd_size_type) -1 + || !_bfd_elf_add_dynamic_entry (info, DT_AUDIT, indx)) + return FALSE; + } + + if (depaudit != NULL) + { + bfd_size_type indx; + + indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, depaudit, + TRUE); + if (indx == (bfd_size_type) -1 + || !_bfd_elf_add_dynamic_entry (info, DT_DEPAUDIT, indx)) + return FALSE; + } + eif.info = info; eif.verdefs = verdefs; eif.failed = FALSE; @@ -5631,7 +5684,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, verlen = strlen (verstr); newlen = namelen + verlen + 3; - newname = bfd_malloc (newlen); + newname = (char *) bfd_malloc (newlen); if (newname == NULL) return FALSE; memcpy (newname, name, namelen); @@ -5869,7 +5922,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } s->size = size; - s->contents = bfd_alloc (output_bfd, s->size); + s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); if (s->contents == NULL && s->size != 0) return FALSE; @@ -6107,7 +6160,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, } s->size = size; - s->contents = bfd_alloc (output_bfd, s->size); + s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); if (s->contents == NULL) return FALSE; @@ -6267,7 +6320,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) && (s->flags & SEC_EXCLUDE) == 0) { s->size = dynsymcount * sizeof (Elf_External_Versym); - s->contents = bfd_zalloc (output_bfd, s->size); + s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); if (s->contents == NULL) return FALSE; @@ -6287,7 +6340,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) if (dynsymcount != 0) { - s->contents = bfd_alloc (output_bfd, s->size); + s->contents = (unsigned char *) bfd_alloc (output_bfd, s->size); if (s->contents == NULL) return FALSE; @@ -6314,7 +6367,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) time store the values in an array so that we could use them for optimizations. */ amt = dynsymcount * sizeof (unsigned long int); - hashcodes = bfd_malloc (amt); + hashcodes = (unsigned long int *) bfd_malloc (amt); if (hashcodes == NULL) return FALSE; hashinf.hashcodes = hashcodes; @@ -6343,7 +6396,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) BFD_ASSERT (s != NULL); hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize; s->size = ((2 + bucketcount + dynsymcount) * hash_entry_size); - s->contents = bfd_zalloc (output_bfd, s->size); + s->contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); if (s->contents == NULL) return FALSE; @@ -6366,7 +6419,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) time store the values in an array so that we could use them for optimizations. */ amt = dynsymcount * 2 * sizeof (unsigned long int); - cinfo.hashcodes = bfd_malloc (amt); + cinfo.hashcodes = (long unsigned int *) bfd_malloc (amt); if (cinfo.hashcodes == NULL) return FALSE; @@ -6402,7 +6455,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) BFD_ASSERT (cinfo.min_dynindx == -1); free (cinfo.hashcodes); s->size = 5 * 4 + bed->s->arch_size / 8; - contents = bfd_zalloc (output_bfd, s->size); + contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); if (contents == NULL) return FALSE; s->contents = contents; @@ -6446,14 +6499,14 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) maskwords = 1 << (maskbitslog2 - cinfo.shift1); amt = bucketcount * sizeof (unsigned long int) * 2; amt += maskwords * sizeof (bfd_vma); - cinfo.bitmask = bfd_malloc (amt); + cinfo.bitmask = (bfd_vma *) bfd_malloc (amt); if (cinfo.bitmask == NULL) { free (cinfo.hashcodes); return FALSE; } - cinfo.counts = (void *) (cinfo.bitmask + maskwords); + cinfo.counts = (long unsigned int *) (cinfo.bitmask + maskwords); cinfo.indx = cinfo.counts + bucketcount; cinfo.symindx = dynsymcount - cinfo.nsyms; memset (cinfo.bitmask, 0, maskwords * sizeof (bfd_vma)); @@ -6475,7 +6528,7 @@ bfd_elf_size_dynsym_hash_dynstr (bfd *output_bfd, struct bfd_link_info *info) s->size = (4 + bucketcount + cinfo.nsyms) * 4; s->size += cinfo.maskbits / 8; - contents = bfd_zalloc (output_bfd, s->size); + contents = (unsigned char *) bfd_zalloc (output_bfd, s->size); if (contents == NULL) { free (cinfo.bitmask); @@ -6599,7 +6652,8 @@ _bfd_elf_link_hash_newfunc (struct bfd_hash_entry *entry, subclass. */ if (entry == NULL) { - entry = bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)); + entry = (struct bfd_hash_entry *) + bfd_hash_allocate (table, sizeof (struct elf_link_hash_entry)); if (entry == NULL) return entry; } @@ -6740,7 +6794,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd) struct elf_link_hash_table *ret; bfd_size_type amt = sizeof (struct elf_link_hash_table); - ret = bfd_malloc (amt); + ret = (struct elf_link_hash_table *) bfd_malloc (amt); if (ret == NULL) return NULL; @@ -6883,7 +6937,7 @@ bfd_elf_get_bfd_needed_list (bfd *abfd, goto error_return; amt = sizeof *l; - l = bfd_alloc (abfd, amt); + l = (struct bfd_link_needed_list *) bfd_alloc (abfd, amt); if (l == NULL) goto error_return; @@ -6955,7 +7009,7 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf) struct elf_symbuf_head *ssymbuf, *ssymhead; bfd_size_type i, shndx_count, total_size; - indbuf = bfd_malloc2 (symcount, sizeof (*indbuf)); + indbuf = (Elf_Internal_Sym **) bfd_malloc2 (symcount, sizeof (*indbuf)); if (indbuf == NULL) return NULL; @@ -6975,7 +7029,7 @@ elf_create_symbuf (bfd_size_type symcount, Elf_Internal_Sym *isymbuf) total_size = ((shndx_count + 1) * sizeof (*ssymbuf) + (indbufend - indbuf) * sizeof (*ssym)); - ssymbuf = bfd_malloc (total_size); + ssymbuf = (struct elf_symbuf_head *) bfd_malloc (total_size); if (ssymbuf == NULL) { free (indbuf); @@ -7056,8 +7110,8 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, result = FALSE; isymbuf1 = NULL; isymbuf2 = NULL; - ssymbuf1 = elf_tdata (bfd1)->symbuf; - ssymbuf2 = elf_tdata (bfd2)->symbuf; + ssymbuf1 = (struct elf_symbuf_head *) elf_tdata (bfd1)->symbuf; + ssymbuf2 = (struct elf_symbuf_head *) elf_tdata (bfd2)->symbuf; if (ssymbuf1 == NULL) { @@ -7131,8 +7185,10 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, if (count1 == 0 || count2 == 0 || count1 != count2) goto done; - symtable1 = bfd_malloc (count1 * sizeof (struct elf_symbol)); - symtable2 = bfd_malloc (count2 * sizeof (struct elf_symbol)); + symtable1 = (struct elf_symbol *) + bfd_malloc (count1 * sizeof (struct elf_symbol)); + symtable2 = (struct elf_symbol *) + bfd_malloc (count2 * sizeof (struct elf_symbol)); if (symtable1 == NULL || symtable2 == NULL) goto done; @@ -7173,8 +7229,10 @@ bfd_elf_match_symbols_in_sections (asection *sec1, asection *sec2, goto done; } - symtable1 = bfd_malloc (symcount1 * sizeof (struct elf_symbol)); - symtable2 = bfd_malloc (symcount2 * sizeof (struct elf_symbol)); + symtable1 = (struct elf_symbol *) + bfd_malloc (symcount1 * sizeof (struct elf_symbol)); + symtable2 = (struct elf_symbol *) + bfd_malloc (symcount2 * sizeof (struct elf_symbol)); if (symtable1 == NULL || symtable2 == NULL) goto done; @@ -7878,8 +7936,8 @@ struct elf_link_sort_rela static int elf_link_sort_cmp1 (const void *A, const void *B) { - const struct elf_link_sort_rela *a = A; - const struct elf_link_sort_rela *b = B; + const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; + const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; int relativea, relativeb; relativea = a->type == reloc_class_relative; @@ -7903,8 +7961,8 @@ elf_link_sort_cmp1 (const void *A, const void *B) static int elf_link_sort_cmp2 (const void *A, const void *B) { - const struct elf_link_sort_rela *a = A; - const struct elf_link_sort_rela *b = B; + const struct elf_link_sort_rela *a = (const struct elf_link_sort_rela *) A; + const struct elf_link_sort_rela *b = (const struct elf_link_sort_rela *) B; int copya, copyb; if (a->u.offset < b->u.offset) @@ -8104,7 +8162,7 @@ elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) count = dynamic_relocs->size / ext_size; if (count == 0) return 0; - sort = bfd_zmalloc (sort_elt * count); + sort = (bfd_byte *) bfd_zmalloc (sort_elt * count); if (sort == NULL) { @@ -8273,7 +8331,8 @@ elf_link_output_sym (struct elf_final_link_info *finfo, bfd_size_type amt; amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); - destshndx = bfd_realloc (destshndx, amt * 2); + destshndx = (Elf_External_Sym_Shndx *) bfd_realloc (destshndx, + amt * 2); if (destshndx == NULL) return 0; finfo->symshndxbuf = destshndx; @@ -8399,7 +8458,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info, /* Read in any version definitions. */ versymhdr = &elf_tdata (input)->dynversym_hdr; - extversym = bfd_malloc (versymhdr->sh_size); + extversym = (Elf_External_Versym *) bfd_malloc (versymhdr->sh_size); if (extversym == NULL) goto error_ret; @@ -8467,7 +8526,7 @@ elf_link_check_versioned_symbol (struct bfd_link_info *info, static bfd_boolean elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) { - struct elf_outext_info *eoinfo = data; + struct elf_outext_info *eoinfo = (struct elf_outext_info *) data; struct elf_final_link_info *finfo = eoinfo->finfo; bfd_boolean strip; Elf_Internal_Sym sym; @@ -8577,9 +8636,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) strip = FALSE; /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do unless it is a forced local symbol. */ + nothing else to do unless it is a forced local symbol or a + STT_GNU_IFUNC symbol. */ if (strip && h->dynindx == -1 + && h->type != STT_GNU_IFUNC && !h->forced_local) return TRUE; @@ -8587,7 +8648,11 @@ elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) sym.st_size = h->size; sym.st_other = h->other; if (h->forced_local) - sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); + { + sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); + /* Turn off visibility on local symbol. */ + sym.st_other &= ~ELF_ST_VISIBILITY (-1); + } else if (h->unique_global) sym.st_info = ELF_ST_INFO (STB_GNU_UNIQUE, h->type); else if (h->root.type == bfd_link_hash_undefweak @@ -9809,8 +9874,8 @@ elf_reloc_link_order (bfd *output_bfd, bfd_boolean ok; const char *sym_name; - size = bfd_get_reloc_size (howto); - buf = bfd_zmalloc (size); + size = (bfd_size_type) bfd_get_reloc_size (howto); + buf = (bfd_byte *) bfd_zmalloc (size); if (buf == NULL) return FALSE; rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); @@ -10043,9 +10108,9 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) bfd_boolean emit_relocs; bfd *dynobj; struct elf_final_link_info finfo; - register asection *o; - register struct bfd_link_order *p; - register bfd *sub; + asection *o; + struct bfd_link_order *p; + bfd *sub; bfd_size_type max_contents_size; bfd_size_type max_external_reloc_size; bfd_size_type max_internal_reloc_count; @@ -10368,7 +10433,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) finfo.symbuf_size = max_sym_count; amt = finfo.symbuf_size; amt *= bed->s->sizeof_sym; - finfo.symbuf = bfd_malloc (amt); + finfo.symbuf = (bfd_byte *) bfd_malloc (amt); if (finfo.symbuf == NULL) goto error_return; if (elf_numsections (abfd) > (SHN_LORESERVE & 0xFFFF)) @@ -10377,7 +10442,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; finfo.shndxbuf_size = amt; amt *= sizeof (Elf_External_Sym_Shndx); - finfo.symshndxbuf = bfd_zmalloc (amt); + finfo.symshndxbuf = (Elf_External_Sym_Shndx *) bfd_zmalloc (amt); if (finfo.symshndxbuf == NULL) goto error_return; } @@ -10428,7 +10493,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) files. */ if (max_contents_size != 0) { - finfo.contents = bfd_malloc (max_contents_size); + finfo.contents = (bfd_byte *) bfd_malloc (max_contents_size); if (finfo.contents == NULL) goto error_return; } @@ -10444,7 +10509,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) { amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; amt *= sizeof (Elf_Internal_Rela); - finfo.internal_relocs = bfd_malloc (amt); + finfo.internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt); if (finfo.internal_relocs == NULL) goto error_return; } @@ -10452,22 +10517,22 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (max_sym_count != 0) { amt = max_sym_count * bed->s->sizeof_sym; - finfo.external_syms = bfd_malloc (amt); + finfo.external_syms = (bfd_byte *) bfd_malloc (amt); if (finfo.external_syms == NULL) goto error_return; amt = max_sym_count * sizeof (Elf_Internal_Sym); - finfo.internal_syms = bfd_malloc (amt); + finfo.internal_syms = (Elf_Internal_Sym *) bfd_malloc (amt); if (finfo.internal_syms == NULL) goto error_return; amt = max_sym_count * sizeof (long); - finfo.indices = bfd_malloc (amt); + finfo.indices = (long int *) bfd_malloc (amt); if (finfo.indices == NULL) goto error_return; amt = max_sym_count * sizeof (asection *); - finfo.sections = bfd_malloc (amt); + finfo.sections = (asection **) bfd_malloc (amt); if (finfo.sections == NULL) goto error_return; } @@ -10475,7 +10540,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (max_sym_shndx_count != 0) { amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); - finfo.locsym_shndx = bfd_malloc (amt); + finfo.locsym_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt); if (finfo.locsym_shndx == NULL) goto error_return; } @@ -10494,9 +10559,10 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0) { - struct bfd_link_order *o = sec->map_tail.link_order; - if (o != NULL) - size = o->offset + o->size; + struct bfd_link_order *ord = sec->map_tail.link_order; + + if (ord != NULL) + size = ord->offset + ord->size; } end = sec->vma + size; } @@ -10659,13 +10725,11 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) asection *s; bfd_byte *dest; - sym.st_size = e->isym.st_size; - sym.st_other = e->isym.st_other; - - /* Copy the internal symbol as is. + /* Copy the internal symbol and turn off visibility. Note that we saved a word of storage and overwrote the original st_name with the dynstr_index. */ sym = e->isym; + sym.st_other &= ~ELF_ST_VISIBILITY (-1); s = bfd_section_from_elf_index (e->input_bfd, e->isym.st_shndx); @@ -11080,7 +11144,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) if (attr_section) { - bfd_byte *contents = bfd_malloc (attr_size); + bfd_byte *contents = (bfd_byte *) bfd_malloc (attr_size); if (contents == NULL) return FALSE; /* Bail out and fail. */ bfd_elf_set_obj_attr_contents (abfd, contents, attr_size); @@ -11267,6 +11331,8 @@ _bfd_elf_gc_mark_hook (asection *sec, struct elf_link_hash_entry *h, Elf_Internal_Sym *sym) { + const char *sec_name; + if (h != NULL) { switch (h->root.type) @@ -11278,6 +11344,33 @@ _bfd_elf_gc_mark_hook (asection *sec, case bfd_link_hash_common: return h->root.u.c.p->section; + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + /* To work around a glibc bug, keep all XXX input sections + when there is an as yet undefined reference to __start_XXX + or __stop_XXX symbols. The linker will later define such + symbols for orphan input sections that have a name + representable as a C identifier. */ + if (strncmp (h->root.root.string, "__start_", 8) == 0) + sec_name = h->root.root.string + 8; + else if (strncmp (h->root.root.string, "__stop_", 7) == 0) + sec_name = h->root.root.string + 7; + else + sec_name = NULL; + + if (sec_name && *sec_name != '\0') + { + bfd *i; + + for (i = info->input_bfds; i; i = i->link_next) + { + sec = bfd_get_section_by_name (i, sec_name); + if (sec) + sec->flags |= SEC_KEEP; + } + } + break; + default: break; } @@ -11422,7 +11515,8 @@ elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *data) && !h->root.u.def.section->gc_mark && !(h->root.u.def.section->owner->flags & DYNAMIC)) { - struct elf_gc_sweep_symbol_info *inf = data; + struct elf_gc_sweep_symbol_info *inf = + (struct elf_gc_sweep_symbol_info *) data; (*inf->hide_symbol) (inf->info, h, TRUE); } @@ -11462,9 +11556,10 @@ elf_gc_sweep (bfd *abfd, struct bfd_link_info *info) o->gc_mark = first->gc_mark; } else if ((o->flags & (SEC_DEBUGGING | SEC_LINKER_CREATED)) != 0 - || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0) + || (o->flags & (SEC_ALLOC | SEC_LOAD | SEC_RELOC)) == 0 + || elf_section_data (o)->this_hdr.sh_type == SHT_NOTE) { - /* Keep debug and special sections. */ + /* Keep debug, special and SHT_NOTE sections. */ o->gc_mark = 1; } @@ -11803,7 +11898,8 @@ bfd_elf_gc_record_vtinherit (bfd *abfd, win: if (!child->vtable) { - child->vtable = bfd_zalloc (abfd, sizeof (*child->vtable)); + child->vtable = (struct elf_link_virtual_table_entry *) + bfd_zalloc (abfd, sizeof (*child->vtable)); if (!child->vtable) return FALSE; } @@ -11835,7 +11931,8 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, if (!h->vtable) { - h->vtable = bfd_zalloc (abfd, sizeof (*h->vtable)); + h->vtable = (struct elf_link_virtual_table_entry *) + bfd_zalloc (abfd, sizeof (*h->vtable)); if (!h->vtable) return FALSE; } @@ -11868,7 +11965,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, if (ptr) { - ptr = bfd_realloc (ptr - 1, bytes); + ptr = (bfd_boolean *) bfd_realloc (ptr - 1, bytes); if (ptr != NULL) { @@ -11880,7 +11977,7 @@ bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, } } else - ptr = bfd_zmalloc (bytes); + ptr = (bfd_boolean *) bfd_zmalloc (bytes); if (ptr == NULL) return FALSE; @@ -11906,7 +12003,7 @@ struct alloc_got_off_arg { static bfd_boolean elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) { - struct alloc_got_off_arg *gofarg = arg; + struct alloc_got_off_arg *gofarg = (struct alloc_got_off_arg *) arg; bfd *obfd = gofarg->info->output_bfd; const struct elf_backend_data *bed = get_elf_backend_data (obfd); @@ -12006,7 +12103,7 @@ bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) bfd_boolean bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) { - struct elf_reloc_cookie *rcookie = cookie; + struct elf_reloc_cookie *rcookie = (struct elf_reloc_cookie *) cookie; if (rcookie->bad_symtab) rcookie->rel = rcookie->rels; @@ -12482,7 +12579,7 @@ _bfd_elf_get_dynamic_reloc_section (bfd * abfd, section does not exist it is created and attached to the DYNOBJ bfd and stored in the SRELOC field of SEC's elf_section_data structure. - + ALIGNMENT is the alignment for the newly created section and IS_RELA defines whether the name should be .rela. or .rel.. The section name is looked up in the @@ -12527,3 +12624,15 @@ _bfd_elf_make_dynamic_reloc_section (asection * sec, return reloc_sec; } + +/* Copy the ELF symbol type associated with a linker hash entry. */ +void +_bfd_elf_copy_link_hash_symbol_type (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_hash_entry * hdest, + struct bfd_link_hash_entry * hsrc) +{ + struct elf_link_hash_entry *ehdest = (struct elf_link_hash_entry *)hdest; + struct elf_link_hash_entry *ehsrc = (struct elf_link_hash_entry *)hsrc; + + ehdest->type = ehsrc->type; +}