mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-21 01:12:32 +08:00
Check if a symbol is hidden by linker script.
bfd/ 2011-09-15 H.J. Lu <hongjiu.lu@intel.com> PR ld/12975 * bfd-in.h (bfd_elf_size_dynamic_sections): Remove pointer to struct bfd_elf_version_tree. * elflink.c (elf_info_failed): Remove verdefs. (_bfd_elf_export_symbol): Updated. _bfd_elf_link_assign_sym_version): Likewise. (bfd_elf_size_dynamic_sections): Remove pointer to struct bfd_elf_version_tree. Updated. (bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is hidden by linker script. * linker.c (bfd_hide_sym_by_version): New. * bfd-in2.h: Regenerated. include/ 2011-09-15 H.J. Lu <hongjiu.lu@intel.com> PR ld/12975 * bfdlink.h (bfd_link_info): Add version_info. ld/ 2011-09-15 H.J. Lu <hongjiu.lu@intel.com> PR ld/12975 * ldlang.c (lang_elf_version_info): Removed. (lang_register_vers_node): Replace lang_elf_version_info with link_info.version_info. (lang_add_vers_depend): Likewise. * pe-dll.c (process_def_file_and_drectve): Likewise. * emultempl/solaris2.em (elf_solaris2_before_allocation): Likewise. * ldlang.h (lang_elf_version_info): Removed. * plugin.c (is_visible_from_outside): Check if symbol is hidden by version script. * emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation): Remove lang_elf_version_info. ld/testsuite/ 2011-09-15 H.J. Lu <hongjiu.lu@intel.com> PR ld/12975 * ld-elf/pr12975.d: New. * ld-elf/pr12975.s: Likewise. * ld-elf/pr12975.t: Likewise.
This commit is contained in:
parent
d0bc107f79
commit
fd91d41947
@ -1,3 +1,21 @@
|
||||
2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/12975
|
||||
* bfd-in.h (bfd_elf_size_dynamic_sections): Remove pointer
|
||||
to struct bfd_elf_version_tree.
|
||||
|
||||
* elflink.c (elf_info_failed): Remove verdefs.
|
||||
(_bfd_elf_export_symbol): Updated.
|
||||
_bfd_elf_link_assign_sym_version): Likewise.
|
||||
(bfd_elf_size_dynamic_sections): Remove pointer to struct
|
||||
bfd_elf_version_tree. Updated.
|
||||
(bfd_elf_gc_mark_dynamic_ref_symbol): Check if a symbol is hidden
|
||||
by linker script.
|
||||
|
||||
* linker.c (bfd_hide_sym_by_version): New.
|
||||
|
||||
* bfd-in2.h: Regenerated.
|
||||
|
||||
2011-09-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/13178
|
||||
|
@ -645,8 +645,7 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list
|
||||
(bfd *, struct bfd_link_needed_list **);
|
||||
extern bfd_boolean bfd_elf_size_dynamic_sections
|
||||
(bfd *, const char *, const char *, const char *, const char *, const char *,
|
||||
const char * const *, struct bfd_link_info *, struct bfd_section **,
|
||||
struct bfd_elf_version_tree *);
|
||||
const char * const *, struct bfd_link_info *, struct bfd_section **);
|
||||
extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern void bfd_elf_set_dt_needed_name
|
||||
|
@ -652,8 +652,7 @@ extern bfd_boolean bfd_elf_get_bfd_needed_list
|
||||
(bfd *, struct bfd_link_needed_list **);
|
||||
extern bfd_boolean bfd_elf_size_dynamic_sections
|
||||
(bfd *, const char *, const char *, const char *, const char *, const char *,
|
||||
const char * const *, struct bfd_link_info *, struct bfd_section **,
|
||||
struct bfd_elf_version_tree *);
|
||||
const char * const *, struct bfd_link_info *, struct bfd_section **);
|
||||
extern bfd_boolean bfd_elf_size_dynsym_hash_dynstr
|
||||
(bfd *, struct bfd_link_info *);
|
||||
extern void bfd_elf_set_dt_needed_name
|
||||
@ -6199,6 +6198,9 @@ struct bfd_elf_version_tree * bfd_find_version_for_sym
|
||||
(struct bfd_elf_version_tree *verdefs,
|
||||
const char *sym_name, bfd_boolean *hide);
|
||||
|
||||
bfd_boolean bfd_hide_sym_by_version
|
||||
(struct bfd_elf_version_tree *verdefs, const char *sym_name);
|
||||
|
||||
/* Extracted from simple.c. */
|
||||
bfd_byte *bfd_simple_get_relocated_section_contents
|
||||
(bfd *abfd, asection *sec, bfd_byte *outbuf, asymbol **symbol_table);
|
||||
|
@ -36,7 +36,6 @@
|
||||
struct elf_info_failed
|
||||
{
|
||||
struct bfd_link_info *info;
|
||||
struct bfd_elf_version_tree *verdefs;
|
||||
bfd_boolean failed;
|
||||
};
|
||||
|
||||
@ -1820,20 +1819,14 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data)
|
||||
return TRUE;
|
||||
|
||||
if (h->dynindx == -1
|
||||
&& (h->def_regular
|
||||
|| h->ref_regular))
|
||||
&& (h->def_regular || h->ref_regular)
|
||||
&& ! bfd_hide_sym_by_version (eif->info->version_info,
|
||||
h->root.root.string))
|
||||
{
|
||||
bfd_boolean hide;
|
||||
|
||||
if (eif->verdefs == NULL
|
||||
|| (bfd_find_version_for_sym (eif->verdefs, h->root.root.string, &hide)
|
||||
&& !hide))
|
||||
if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
|
||||
{
|
||||
if (! bfd_elf_link_record_dynamic_symbol (eif->info, h))
|
||||
{
|
||||
eif->failed = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
eif->failed = TRUE;
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1981,7 +1974,7 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
}
|
||||
|
||||
/* Look for the version. If we find it, it is no longer weak. */
|
||||
for (t = sinfo->verdefs; t != NULL; t = t->next)
|
||||
for (t = sinfo->info->version_info; t != NULL; t = t->next)
|
||||
{
|
||||
if (strcmp (t->name, p) == 0)
|
||||
{
|
||||
@ -2050,9 +2043,12 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
|
||||
version_index = 1;
|
||||
/* Don't count anonymous version tag. */
|
||||
if (sinfo->verdefs != NULL && sinfo->verdefs->vernum == 0)
|
||||
if (sinfo->info->version_info != NULL
|
||||
&& sinfo->info->version_info->vernum == 0)
|
||||
version_index = 0;
|
||||
for (pp = &sinfo->verdefs; *pp != NULL; pp = &(*pp)->next)
|
||||
for (pp = &sinfo->info->version_info;
|
||||
*pp != NULL;
|
||||
pp = &(*pp)->next)
|
||||
++version_index;
|
||||
t->vernum = version_index;
|
||||
|
||||
@ -2078,12 +2074,13 @@ _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *h, void *data)
|
||||
|
||||
/* If we don't have a version for this symbol, see if we can find
|
||||
something. */
|
||||
if (h->verinfo.vertree == NULL && sinfo->verdefs != NULL)
|
||||
if (h->verinfo.vertree == NULL && sinfo->info->version_info != NULL)
|
||||
{
|
||||
bfd_boolean hide;
|
||||
|
||||
h->verinfo.vertree = bfd_find_version_for_sym (sinfo->verdefs,
|
||||
h->root.root.string, &hide);
|
||||
h->verinfo.vertree
|
||||
= bfd_find_version_for_sym (sinfo->info->version_info,
|
||||
h->root.root.string, &hide);
|
||||
if (h->verinfo.vertree != NULL && hide)
|
||||
(*bed->elf_backend_hide_symbol) (info, h, TRUE);
|
||||
}
|
||||
@ -5493,8 +5490,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
const char *depaudit,
|
||||
const char * const *auxiliary_filters,
|
||||
struct bfd_link_info *info,
|
||||
asection **sinterpptr,
|
||||
struct bfd_elf_version_tree *verdefs)
|
||||
asection **sinterpptr)
|
||||
{
|
||||
bfd_size_type soname_indx;
|
||||
bfd *dynobj;
|
||||
@ -5671,7 +5667,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
|
||||
eif.info = info;
|
||||
eif.verdefs = verdefs;
|
||||
eif.failed = FALSE;
|
||||
|
||||
/* If we are supposed to export all symbols into the dynamic symbol
|
||||
@ -5687,7 +5682,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
}
|
||||
|
||||
/* Make all global versions with definition. */
|
||||
for (t = verdefs; t != NULL; t = t->next)
|
||||
for (t = info->version_info; t != NULL; t = t->next)
|
||||
for (d = t->globals.list; d != NULL; d = d->next)
|
||||
if (!d->symver && d->literal)
|
||||
{
|
||||
@ -5740,7 +5735,6 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
/* Attach all the symbols to their version information. */
|
||||
asvinfo.info = info;
|
||||
asvinfo.verdefs = verdefs;
|
||||
asvinfo.failed = FALSE;
|
||||
|
||||
elf_link_hash_traverse (elf_hash_table (info),
|
||||
@ -5753,7 +5747,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
{
|
||||
/* Check if all global versions have a definition. */
|
||||
all_defined = TRUE;
|
||||
for (t = verdefs; t != NULL; t = t->next)
|
||||
for (t = info->version_info; t != NULL; t = t->next)
|
||||
for (d = t->globals.list; d != NULL; d = d->next)
|
||||
if (d->literal && !d->symver && !d->script)
|
||||
{
|
||||
@ -5886,6 +5880,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
if (elf_hash_table (info)->dynamic_sections_created)
|
||||
{
|
||||
unsigned long section_sym_count;
|
||||
struct bfd_elf_version_tree *verdefs;
|
||||
asection *s;
|
||||
|
||||
/* Set up the version definition section. */
|
||||
@ -5894,7 +5889,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd,
|
||||
|
||||
/* We may have created additional version definitions if we are
|
||||
just linking a regular application. */
|
||||
verdefs = asvinfo.verdefs;
|
||||
verdefs = info->version_info;
|
||||
|
||||
/* Skip anonymous version tag. */
|
||||
if (verdefs != NULL && verdefs->vernum == 0)
|
||||
@ -11913,7 +11908,9 @@ bfd_elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h, void *inf)
|
||||
|| (!info->executable
|
||||
&& h->def_regular
|
||||
&& ELF_ST_VISIBILITY (h->other) != STV_INTERNAL
|
||||
&& ELF_ST_VISIBILITY (h->other) != STV_HIDDEN)))
|
||||
&& ELF_ST_VISIBILITY (h->other) != STV_HIDDEN
|
||||
&& !bfd_hide_sym_by_version (info->version_info,
|
||||
h->root.root.string))))
|
||||
h->root.u.def.section->flags |= SEC_KEEP;
|
||||
|
||||
return TRUE;
|
||||
|
23
bfd/linker.c
23
bfd/linker.c
@ -3380,3 +3380,26 @@ bfd_find_version_for_sym (struct bfd_elf_version_tree *verdefs,
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
FUNCTION
|
||||
bfd_hide_sym_by_version
|
||||
|
||||
SYNOPSIS
|
||||
bfd_boolean bfd_hide_sym_by_version
|
||||
(struct bfd_elf_version_tree *verdefs, const char *sym_name);
|
||||
|
||||
DESCRIPTION
|
||||
Search an elf version script tree for symbol versioning
|
||||
info for a given symbol. Return TRUE if the symbol is hidden.
|
||||
|
||||
*/
|
||||
|
||||
bfd_boolean
|
||||
bfd_hide_sym_by_version (struct bfd_elf_version_tree *verdefs,
|
||||
const char *sym_name)
|
||||
{
|
||||
bfd_boolean hidden = FALSE;
|
||||
bfd_find_version_for_sym (verdefs, sym_name, &hidden);
|
||||
return hidden;
|
||||
}
|
||||
|
@ -1,3 +1,8 @@
|
||||
2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/12975
|
||||
* bfdlink.h (bfd_link_info): Add version_info.
|
||||
|
||||
2011-07-25 Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE>
|
||||
|
||||
* xregex.h (regoff_t): Define.
|
||||
|
@ -245,6 +245,7 @@ struct flag_info
|
||||
};
|
||||
|
||||
struct bfd_elf_dynamic_list;
|
||||
struct bfd_elf_version_tree;
|
||||
|
||||
/* This structure holds all the information needed to communicate
|
||||
between BFD and the linker when doing a link. */
|
||||
@ -496,6 +497,9 @@ struct bfd_link_info
|
||||
|
||||
/* List of symbols should be dynamic. */
|
||||
struct bfd_elf_dynamic_list *dynamic_list;
|
||||
|
||||
/* The version information. */
|
||||
struct bfd_elf_version_tree *version_info;
|
||||
};
|
||||
|
||||
/* This structures holds a set of callback functions. These are called
|
||||
|
18
ld/ChangeLog
18
ld/ChangeLog
@ -1,3 +1,21 @@
|
||||
2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/12975
|
||||
* ldlang.c (lang_elf_version_info): Removed.
|
||||
(lang_register_vers_node): Replace lang_elf_version_info with
|
||||
link_info.version_info.
|
||||
(lang_add_vers_depend): Likewise.
|
||||
* pe-dll.c (process_def_file_and_drectve): Likewise.
|
||||
* emultempl/solaris2.em (elf_solaris2_before_allocation): Likewise.
|
||||
|
||||
* ldlang.h (lang_elf_version_info): Removed.
|
||||
|
||||
* plugin.c (is_visible_from_outside): Check if symbol is hidden
|
||||
by version script.
|
||||
|
||||
* emultempl/elf32.em (gld${EMULATION_NAME}_before_allocation):
|
||||
Remove lang_elf_version_info.
|
||||
|
||||
2011-09-15 Dmitry Gorbachev <d.g.gorbachev@gmail.com>
|
||||
|
||||
PR ld/13183
|
||||
|
@ -1535,7 +1535,7 @@ gld${EMULATION_NAME}_before_allocation (void)
|
||||
(link_info.output_bfd, command_line.soname, rpath,
|
||||
command_line.filter_shlib, audit, depaudit,
|
||||
(const char * const *) command_line.auxiliary_filters,
|
||||
&link_info, &sinterp, lang_elf_version_info)))
|
||||
&link_info, &sinterp)))
|
||||
einfo ("%P%F: failed to set dynamic section sizes: %E\n");
|
||||
|
||||
${ELF_INTERPRETER_SET_DEFAULT}
|
||||
|
@ -76,7 +76,8 @@ elf_solaris2_before_allocation (void)
|
||||
|
||||
/* Only do this if emitting a shared object and versioning is in place. */
|
||||
if (link_info.shared
|
||||
&& (lang_elf_version_info != NULL || link_info.create_default_symver))
|
||||
&& (link_info.version_info != NULL
|
||||
|| link_info.create_default_symver))
|
||||
{
|
||||
struct bfd_elf_version_expr *globals = NULL, *locals = NULL;
|
||||
struct bfd_elf_version_tree *basever;
|
||||
|
18
ld/ldlang.c
18
ld/ldlang.c
@ -7458,10 +7458,6 @@ lang_leave_overlay (etree_type *lma_expr,
|
||||
|
||||
/* Version handling. This is only useful for ELF. */
|
||||
|
||||
/* This global variable holds the version tree that we build. */
|
||||
|
||||
struct bfd_elf_version_tree *lang_elf_version_info;
|
||||
|
||||
/* If PREV is NULL, return first version pattern matching particular symbol.
|
||||
If PREV is non-NULL, return first version pattern matching particular
|
||||
symbol after PREV (previously returned by lang_vers_match). */
|
||||
@ -7803,8 +7799,8 @@ lang_register_vers_node (const char *name,
|
||||
if (name == NULL)
|
||||
name = "";
|
||||
|
||||
if ((name[0] == '\0' && lang_elf_version_info != NULL)
|
||||
|| (lang_elf_version_info && lang_elf_version_info->name[0] == '\0'))
|
||||
if (link_info.version_info != NULL
|
||||
&& (name[0] == '\0' || link_info.version_info->name[0] == '\0'))
|
||||
{
|
||||
einfo (_("%X%P: anonymous version tag cannot be combined"
|
||||
" with other version tags\n"));
|
||||
@ -7813,7 +7809,7 @@ lang_register_vers_node (const char *name,
|
||||
}
|
||||
|
||||
/* Make sure this node has a unique name. */
|
||||
for (t = lang_elf_version_info; t != NULL; t = t->next)
|
||||
for (t = link_info.version_info; t != NULL; t = t->next)
|
||||
if (strcmp (t->name, name) == 0)
|
||||
einfo (_("%X%P: duplicate version tag `%s'\n"), name);
|
||||
|
||||
@ -7825,7 +7821,7 @@ lang_register_vers_node (const char *name,
|
||||
|
||||
for (e1 = version->globals.list; e1 != NULL; e1 = e1->next)
|
||||
{
|
||||
for (t = lang_elf_version_info; t != NULL; t = t->next)
|
||||
for (t = link_info.version_info; t != NULL; t = t->next)
|
||||
{
|
||||
struct bfd_elf_version_expr *e2;
|
||||
|
||||
@ -7852,7 +7848,7 @@ lang_register_vers_node (const char *name,
|
||||
|
||||
for (e1 = version->locals.list; e1 != NULL; e1 = e1->next)
|
||||
{
|
||||
for (t = lang_elf_version_info; t != NULL; t = t->next)
|
||||
for (t = link_info.version_info; t != NULL; t = t->next)
|
||||
{
|
||||
struct bfd_elf_version_expr *e2;
|
||||
|
||||
@ -7888,7 +7884,7 @@ lang_register_vers_node (const char *name,
|
||||
else
|
||||
version->vernum = 0;
|
||||
|
||||
for (pp = &lang_elf_version_info; *pp != NULL; pp = &(*pp)->next)
|
||||
for (pp = &link_info.version_info; *pp != NULL; pp = &(*pp)->next)
|
||||
;
|
||||
*pp = version;
|
||||
}
|
||||
@ -7904,7 +7900,7 @@ lang_add_vers_depend (struct bfd_elf_version_deps *list, const char *name)
|
||||
ret = (struct bfd_elf_version_deps *) xmalloc (sizeof *ret);
|
||||
ret->next = list;
|
||||
|
||||
for (t = lang_elf_version_info; t != NULL; t = t->next)
|
||||
for (t = link_info.version_info; t != NULL; t = t->next)
|
||||
{
|
||||
if (strcmp (t->name, name) == 0)
|
||||
{
|
||||
|
@ -628,8 +628,6 @@ extern void lang_leave_overlay
|
||||
(etree_type *, int, fill_type *, const char *,
|
||||
lang_output_section_phdr_list *, const char *);
|
||||
|
||||
extern struct bfd_elf_version_tree *lang_elf_version_info;
|
||||
|
||||
extern struct bfd_elf_version_expr *lang_new_vers_pattern
|
||||
(struct bfd_elf_version_expr *, const char *, const char *, bfd_boolean);
|
||||
extern struct bfd_elf_version_tree *lang_new_vers_node
|
||||
|
11
ld/pe-dll.c
11
ld/pe-dll.c
@ -718,13 +718,10 @@ process_def_file_and_drectve (bfd *abfd ATTRIBUTE_UNUSED, struct bfd_link_info *
|
||||
bfd_boolean would_export = symbols[j]->section != &bfd_und_section
|
||||
&& ((symbols[j]->flags & BSF_GLOBAL)
|
||||
|| (symbols[j]->flags == 0));
|
||||
if (lang_elf_version_info && would_export)
|
||||
{
|
||||
bfd_boolean hide = 0;
|
||||
(void) bfd_find_version_for_sym (lang_elf_version_info,
|
||||
symbols[j]->name, &hide);
|
||||
would_export = !hide;
|
||||
}
|
||||
if (link_info.version_info && would_export)
|
||||
would_export
|
||||
= !bfd_hide_sym_by_version (link_info.version_info,
|
||||
symbols[j]->name);
|
||||
if (would_export)
|
||||
{
|
||||
const char *sn = symbols[j]->name;
|
||||
|
@ -454,6 +454,10 @@ is_visible_from_outside (struct ld_plugin_symbol *lsym, asection *section,
|
||||
return TRUE;
|
||||
if (link_info.export_dynamic || link_info.shared)
|
||||
{
|
||||
/* Check if symbol is hidden by version script. */
|
||||
if (bfd_hide_sym_by_version (link_info.version_info,
|
||||
blhe->root.string))
|
||||
return FALSE;
|
||||
/* Only ELF symbols really have visibility. */
|
||||
if (bfd_get_flavour (link_info.output_bfd) == bfd_target_elf_flavour)
|
||||
{
|
||||
|
@ -1,3 +1,10 @@
|
||||
2011-09-15 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/12975
|
||||
* ld-elf/pr12975.d: New.
|
||||
* ld-elf/pr12975.s: Likewise.
|
||||
* ld-elf/pr12975.t: Likewise.
|
||||
|
||||
2011-09-12 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR ld/13178
|
||||
|
10
ld/testsuite/ld-elf/pr12975.d
Normal file
10
ld/testsuite/ld-elf/pr12975.d
Normal file
@ -0,0 +1,10 @@
|
||||
#ld: --gc-sections -shared -version-script pr12975.t
|
||||
#readelf: -s --wide
|
||||
#notarget: arc-*-* d30v-*-* dlx-*-* i960-*-* or32-*-* pj*-*-*
|
||||
#notarget: hppa64-*-* i370-*-* i860-*-* ia64-*-* mep-*-* mn10200-*-*
|
||||
# generic linker targets don't support --gc-sections, nor do a bunch of others
|
||||
|
||||
#failif
|
||||
#...
|
||||
+[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +LOCAL +DEFAULT +[1-9]+ bar
|
||||
#...
|
10
ld/testsuite/ld-elf/pr12975.s
Normal file
10
ld/testsuite/ld-elf/pr12975.s
Normal file
@ -0,0 +1,10 @@
|
||||
.section .text.foo,"ax",%progbits
|
||||
.globl foo
|
||||
.type foo, %function
|
||||
foo:
|
||||
.byte 0
|
||||
.section .text.bar,"ax",%progbits
|
||||
.type bar, %function
|
||||
.globl bar
|
||||
bar:
|
||||
.byte 0
|
6
ld/testsuite/ld-elf/pr12975.t
Normal file
6
ld/testsuite/ld-elf/pr12975.t
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
global:
|
||||
foo;
|
||||
local:
|
||||
*;
|
||||
};
|
Loading…
Reference in New Issue
Block a user