diff options
author | Clément Chigot <clement.chigot@atos.net> | 2021-11-23 15:45:28 +0100 |
---|---|---|
committer | Clément Chigot <clement.chigot@atos.net> | 2022-01-12 09:08:25 +0100 |
commit | a8bc481f352d61bb2962e983a1c1c1fdad0230b7 (patch) | |
tree | 0571c01cecab210414116d89f49e005de17a0404 /bfd/xcofflink.c | |
parent | 59e31fd742a53e8404039e1c4be4ba192672287c (diff) | |
download | binutils-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.zip binutils-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.tar.gz binutils-a8bc481f352d61bb2962e983a1c1c1fdad0230b7.tar.bz2 |
ld: add hidden and internal visibility support for XCOFF
This patch adds a primary support for hidden and internal visibility in
GNU linker for XCOFF format.
The protected visibility isn't yet supported.
PR 22085
bfd/ChangeLog:
* xcofflink.c (xcoff_dynamic_definition_p): Add hidden
and internal visibility support.
(xcoff_link_add_symbols): Likewise.
(xcoff_auto_export_p): Likewise.
(bfd_xcoff_export_symbol): Likewise.
(xcoff_link_input_bfd): Likewise.
ld/ChangeLog:
* testsuite/ld-vsb/main.c: Adapt for XCOFF.
* testsuite/ld-vsb/sh1.c: Likewse.
* testsuite/ld-vsb/vsb.exp: Likewise.
* testsuite/ld-vsb/visibility-1-xcoff-32.d: New test.
* testsuite/ld-vsb/visibility-1-xcoff-64.d: New test.
* testsuite/ld-vsb/visibility-2-xcoff-32.d: New test.
* testsuite/ld-vsb/visibility-2-xcoff-64.d: New test.
* testsuite/ld-vsb/xcoffvsb.dat: New test.
Diffstat (limited to 'bfd/xcofflink.c')
-rw-r--r-- | bfd/xcofflink.c | 50 |
1 files changed, 48 insertions, 2 deletions
diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index ba07ba7..6e99472 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -798,10 +798,14 @@ xcoff_dynamic_definition_p (struct xcoff_link_hash_entry *h, || h->root.type == bfd_link_hash_undefweak)) return true; - /* If H is currently undefined, LDSYM defines it. */ + /* If H is currently undefined, LDSYM defines it. + However, if H has a hidden visibility, LDSYM must not + define it. */ if ((h->flags & XCOFF_DEF_DYNAMIC) == 0 && (h->root.type == bfd_link_hash_undefined - || h->root.type == bfd_link_hash_undefweak)) + || h->root.type == bfd_link_hash_undefweak) + && (h->visibility != SYM_V_HIDDEN + && h->visibility != SYM_V_INTERNAL)) return true; return false; @@ -1243,6 +1247,7 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) bfd_byte *linenos; } *reloc_info = NULL; bfd_size_type amt; + unsigned short visibility; keep_syms = obj_coff_keep_syms (abfd); @@ -1480,6 +1485,9 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) } } + /* Record visibility. */ + visibility = sym.n_type & SYM_V_MASK; + /* Pick up the csect auxiliary information. */ if (sym.n_numaux == 0) { @@ -2058,6 +2066,22 @@ xcoff_link_add_symbols (bfd *abfd, struct bfd_link_info *info) /* Try not to give this error too many times. */ (*sym_hash)->flags &= ~XCOFF_MULTIPLY_DEFINED; } + + + /* If the symbol is hidden or internal, completely undo + any dynamic link state. */ + if ((*sym_hash)->flags & XCOFF_DEF_DYNAMIC + && (visibility == SYM_V_HIDDEN + || visibility == SYM_V_INTERNAL)) + (*sym_hash)->flags &= ~XCOFF_DEF_DYNAMIC; + else + { + /* Keep the most constraining visibility. */ + unsigned short hvis = (*sym_hash)->visibility; + if (visibility && ( !hvis || visibility < hvis)) + (*sym_hash)->visibility = visibility; + } + } /* _bfd_generic_link_add_one_symbol may call the linker to @@ -2650,6 +2674,11 @@ xcoff_auto_export_p (struct bfd_link_info *info, if (h->root.root.string[0] == '.') return false; + /* Don't export hidden or internal symbols. */ + if (h->visibility == SYM_V_HIDDEN + || h->visibility == SYM_V_INTERNAL) + return false; + /* We don't export a symbol which is being defined by an object included from an archive which contains a shared object. The rationale is that if an archive contains both an unshared and @@ -3248,6 +3277,19 @@ bfd_xcoff_export_symbol (bfd *output_bfd, if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) return true; + /* As AIX linker, symbols exported with hidden visibility are + silently ignored. */ + if (h->visibility == SYM_V_HIDDEN) + return true; + + if (h->visibility == SYM_V_INTERNAL) + { + _bfd_error_handler (_("%pB: cannot export internal symbol `%s`."), + output_bfd, h->root.root.string); + bfd_set_error (bfd_error_bad_value); + return false; + } + h->flags |= XCOFF_EXPORT; /* FIXME: I'm not at all sure what syscall is supposed to mean, so @@ -4572,6 +4614,10 @@ xcoff_link_input_bfd (struct xcoff_final_link_info *flinfo, - (*csectpp)->vma); } + /* Update visibility. */ + isym.n_type &= ~SYM_V_MASK; + isym.n_type |= (*sym_hash)->visibility; + /* Output the symbol. */ bfd_coff_swap_sym_out (output_bfd, (void *) &isym, (void *) outsym); |