summaryrefslogtreecommitdiff
path: root/bfd/elflink.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elflink.c')
-rw-r--r--bfd/elflink.c47
1 files changed, 42 insertions, 5 deletions
diff --git a/bfd/elflink.c b/bfd/elflink.c
index c42c6e135bd..f8029b0c384 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -3234,6 +3234,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:
@@ -3525,6 +3527,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;
@@ -3653,6 +3656,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);
@@ -3705,6 +3713,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
@@ -5451,6 +5462,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,
@@ -5603,6 +5616,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;
@@ -8597,7 +8632,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
@@ -10669,13 +10708,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);