bfd/
2003-04-27 H.J. Lu <hjl@gnu.org> * elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New. (ELF_LINK_DYNAMIC_WEAK): New. * elflink.h (elf_merge_symbol): Add one argument to indicate if a symbol should be skipped. Ignore definitions in dynamic objects for symbols with non-default visibility. (elf_add_default_symbol): Adjusted. (elf_link_add_object_symbols): Check if a symbol should be skipped. Don't merge the visibility field with the one from a dynamic object. (elf_link_check_versioned_symbol): Use undef_bfd. (elf_link_output_extsym): Warn if a forced local symbol is referenced from dynamic objects. Make non-weak undefined symbol with non-default visibility a fatal error. ld/testsuite/ 2003-04-27 H.J. Lu <hjl@gnu.org> * ld-elfvsb/elfvsb.dat: Updated. * ld-elfvsb/elfvsb.exp: Likewise. * ld-elfvsb/main.c: Likewise. * ld-elfvsb/sh1.c: Likewise. * ld-elfvsb/sh2.c: Likewise.
This commit is contained in:
parent
e4c4d240a3
commit
1b1fe8feb3
9 changed files with 316 additions and 14 deletions
|
@ -1,3 +1,20 @@
|
||||||
|
2003-04-27 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
|
* elf-bfd.h (ELF_LINK_DYNAMIC_DEF): New.
|
||||||
|
(ELF_LINK_DYNAMIC_WEAK): New.
|
||||||
|
|
||||||
|
* elflink.h (elf_merge_symbol): Add one argument to indicate if
|
||||||
|
a symbol should be skipped. Ignore definitions in dynamic
|
||||||
|
objects for symbols with non-default visibility.
|
||||||
|
(elf_add_default_symbol): Adjusted.
|
||||||
|
(elf_link_add_object_symbols): Check if a symbol should be
|
||||||
|
skipped. Don't merge the visibility field with the one from
|
||||||
|
a dynamic object.
|
||||||
|
(elf_link_check_versioned_symbol): Use undef_bfd.
|
||||||
|
(elf_link_output_extsym): Warn if a forced local symbol is
|
||||||
|
referenced from dynamic objects. Make non-weak undefined symbol
|
||||||
|
with non-default visibility a fatal error.
|
||||||
|
|
||||||
2003-04-27 Daniel Jacobowitz <drow@mvista.com>
|
2003-04-27 Daniel Jacobowitz <drow@mvista.com>
|
||||||
|
|
||||||
* configure.in: Bump version on HEAD to 2.14.90.
|
* configure.in: Bump version on HEAD to 2.14.90.
|
||||||
|
|
|
@ -204,6 +204,10 @@ struct elf_link_hash_entry
|
||||||
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
|
/* Symbol is referenced by a non-GOT/non-PLT relocation. This is
|
||||||
not currently set by all the backends. */
|
not currently set by all the backends. */
|
||||||
#define ELF_LINK_NON_GOT_REF 010000
|
#define ELF_LINK_NON_GOT_REF 010000
|
||||||
|
/* Symbol has a definition in a shared object. */
|
||||||
|
#define ELF_LINK_DYNAMIC_DEF 020000
|
||||||
|
/* Symbol is weak in all shared objects. */
|
||||||
|
#define ELF_LINK_DYNAMIC_WEAK 040000
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Records local symbols to be emitted in the dynamic symbol table. */
|
/* Records local symbols to be emitted in the dynamic symbol table. */
|
||||||
|
|
123
bfd/elflink.h
123
bfd/elflink.h
|
@ -42,7 +42,7 @@ static bfd_boolean elf_merge_symbol
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, const char *,
|
PARAMS ((bfd *, struct bfd_link_info *, const char *,
|
||||||
Elf_Internal_Sym *, asection **, bfd_vma *,
|
Elf_Internal_Sym *, asection **, bfd_vma *,
|
||||||
struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *,
|
struct elf_link_hash_entry **, bfd_boolean *, bfd_boolean *,
|
||||||
bfd_boolean *, bfd_boolean));
|
bfd_boolean *, bfd_boolean *, bfd_boolean));
|
||||||
static bfd_boolean elf_add_default_symbol
|
static bfd_boolean elf_add_default_symbol
|
||||||
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
|
PARAMS ((bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
|
||||||
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
|
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
|
||||||
|
@ -463,7 +463,7 @@ elf_link_add_archive_symbols (abfd, info)
|
||||||
a shared object. */
|
a shared object. */
|
||||||
|
|
||||||
static bfd_boolean
|
static bfd_boolean
|
||||||
elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash, skip,
|
||||||
override, type_change_ok, size_change_ok, dt_needed)
|
override, type_change_ok, size_change_ok, dt_needed)
|
||||||
bfd *abfd;
|
bfd *abfd;
|
||||||
struct bfd_link_info *info;
|
struct bfd_link_info *info;
|
||||||
|
@ -472,6 +472,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
asection **psec;
|
asection **psec;
|
||||||
bfd_vma *pvalue;
|
bfd_vma *pvalue;
|
||||||
struct elf_link_hash_entry **sym_hash;
|
struct elf_link_hash_entry **sym_hash;
|
||||||
|
bfd_boolean *skip;
|
||||||
bfd_boolean *override;
|
bfd_boolean *override;
|
||||||
bfd_boolean *type_change_ok;
|
bfd_boolean *type_change_ok;
|
||||||
bfd_boolean *size_change_ok;
|
bfd_boolean *size_change_ok;
|
||||||
|
@ -484,6 +485,7 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
bfd *oldbfd;
|
bfd *oldbfd;
|
||||||
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
|
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
|
||||||
|
|
||||||
|
*skip = FALSE;
|
||||||
*override = FALSE;
|
*override = FALSE;
|
||||||
|
|
||||||
sec = *psec;
|
sec = *psec;
|
||||||
|
@ -606,6 +608,57 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|
||||||
else
|
else
|
||||||
olddef = TRUE;
|
olddef = TRUE;
|
||||||
|
|
||||||
|
/* We need to rememeber if a symbol has a definition in a dynamic
|
||||||
|
object or is weak in all dynamic objects. Internal and hidden
|
||||||
|
visibility will make it unavailable to dynamic objects. */
|
||||||
|
if (newdyn && (h->elf_link_hash_flags & ELF_LINK_DYNAMIC_DEF) == 0)
|
||||||
|
{
|
||||||
|
if (!bfd_is_und_section (sec))
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_DEF;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Check if this symbol is weak in all dynamic objects. If it
|
||||||
|
is the first time we see it in a dynamic object, we mark
|
||||||
|
if it is weak. Otherwise, we clear it. */
|
||||||
|
if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
|
||||||
|
{
|
||||||
|
if (bind == STB_WEAK)
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_WEAK;
|
||||||
|
}
|
||||||
|
else if (bind != STB_WEAK)
|
||||||
|
h->elf_link_hash_flags &= ~ELF_LINK_DYNAMIC_WEAK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If the old symbol has non-default visibility, we ignore the new
|
||||||
|
definition from a dynamic object. */
|
||||||
|
if (newdyn
|
||||||
|
&& ELF_ST_VISIBILITY (h->other)
|
||||||
|
&& !bfd_is_und_section (sec))
|
||||||
|
{
|
||||||
|
*skip = TRUE;
|
||||||
|
/* Make sure this symbol is dynamic. */
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
|
||||||
|
/* FIXME: Should we check type and size for protected symbol? */
|
||||||
|
return _bfd_elf_link_record_dynamic_symbol (info, h);
|
||||||
|
}
|
||||||
|
else if (!newdyn
|
||||||
|
&& ELF_ST_VISIBILITY (sym->st_other)
|
||||||
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
|
||||||
|
{
|
||||||
|
/* If the new symbol with non-default visibility comes from a
|
||||||
|
relocatable file and the old definition comes from a dynamic
|
||||||
|
object, we remove the old definition. */
|
||||||
|
h->root.type = bfd_link_hash_new;
|
||||||
|
h->root.u.undef.abfd = NULL;
|
||||||
|
h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
|
||||||
|
h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
|
||||||
|
/* FIXME: Should we check type and size for protected symbol? */
|
||||||
|
h->size = 0;
|
||||||
|
h->type = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
|
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
|
||||||
symbol, respectively, appears to be a common symbol in a dynamic
|
symbol, respectively, appears to be a common symbol in a dynamic
|
||||||
object. If a symbol appears in an uninitialized section, and is
|
object. If a symbol appears in an uninitialized section, and is
|
||||||
|
@ -934,6 +987,7 @@ elf_add_default_symbol (abfd, info, h, name, sym, psec, value,
|
||||||
{
|
{
|
||||||
bfd_boolean type_change_ok;
|
bfd_boolean type_change_ok;
|
||||||
bfd_boolean size_change_ok;
|
bfd_boolean size_change_ok;
|
||||||
|
bfd_boolean skip;
|
||||||
char *shortname;
|
char *shortname;
|
||||||
struct elf_link_hash_entry *hi;
|
struct elf_link_hash_entry *hi;
|
||||||
struct bfd_link_hash_entry *bh;
|
struct bfd_link_hash_entry *bh;
|
||||||
|
@ -989,7 +1043,7 @@ elf_add_default_symbol (abfd, info, h, name, sym, psec, value,
|
||||||
size_change_ok = FALSE;
|
size_change_ok = FALSE;
|
||||||
sec = *psec;
|
sec = *psec;
|
||||||
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
||||||
&hi, &override, &type_change_ok,
|
&hi, &skip, &override, &type_change_ok,
|
||||||
&size_change_ok, dt_needed))
|
&size_change_ok, dt_needed))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1098,7 +1152,7 @@ elf_add_default_symbol (abfd, info, h, name, sym, psec, value,
|
||||||
size_change_ok = FALSE;
|
size_change_ok = FALSE;
|
||||||
sec = *psec;
|
sec = *psec;
|
||||||
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
if (! elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
|
||||||
&hi, &override, &type_change_ok,
|
&hi, &skip, &override, &type_change_ok,
|
||||||
&size_change_ok, dt_needed))
|
&size_change_ok, dt_needed))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -1740,6 +1794,7 @@ elf_link_add_object_symbols (abfd, info)
|
||||||
{
|
{
|
||||||
Elf_Internal_Versym iver;
|
Elf_Internal_Versym iver;
|
||||||
unsigned int vernum = 0;
|
unsigned int vernum = 0;
|
||||||
|
bfd_boolean skip;
|
||||||
|
|
||||||
if (ever != NULL)
|
if (ever != NULL)
|
||||||
{
|
{
|
||||||
|
@ -1837,10 +1892,14 @@ elf_link_add_object_symbols (abfd, info)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! elf_merge_symbol (abfd, info, name, isym, &sec, &value,
|
if (! elf_merge_symbol (abfd, info, name, isym, &sec, &value,
|
||||||
sym_hash, &override, &type_change_ok,
|
sym_hash, &skip, &override,
|
||||||
&size_change_ok, dt_needed))
|
&type_change_ok, &size_change_ok,
|
||||||
|
dt_needed))
|
||||||
goto error_free_vers;
|
goto error_free_vers;
|
||||||
|
|
||||||
|
if (skip)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (override)
|
if (override)
|
||||||
definition = FALSE;
|
definition = FALSE;
|
||||||
|
|
||||||
|
@ -2020,9 +2079,10 @@ elf_link_add_object_symbols (abfd, info)
|
||||||
h->type = ELF_ST_TYPE (isym->st_info);
|
h->type = ELF_ST_TYPE (isym->st_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If st_other has a processor-specific meaning, specific code
|
/* If st_other has a processor-specific meaning, specific
|
||||||
might be needed here. */
|
code might be needed here. We never merge the visibility
|
||||||
if (isym->st_other != 0)
|
attribute with the one from a dynamic object. */
|
||||||
|
if (isym->st_other != 0 && !dynamic)
|
||||||
{
|
{
|
||||||
unsigned char hvis, symvis, other, nvis;
|
unsigned char hvis, symvis, other, nvis;
|
||||||
|
|
||||||
|
@ -2089,7 +2149,7 @@ elf_link_add_object_symbols (abfd, info)
|
||||||
override, dt_needed))
|
override, dt_needed))
|
||||||
goto error_free_vers;
|
goto error_free_vers;
|
||||||
|
|
||||||
if (definition && (abfd->flags & DYNAMIC) == 0)
|
if (definition && !dynamic)
|
||||||
{
|
{
|
||||||
char *p = strchr (name, ELF_VER_CHR);
|
char *p = strchr (name, ELF_VER_CHR);
|
||||||
if (p != NULL && p[1] != ELF_VER_CHR)
|
if (p != NULL && p[1] != ELF_VER_CHR)
|
||||||
|
@ -6106,7 +6166,7 @@ elf_link_check_versioned_symbol (info, h)
|
||||||
|
|
||||||
if ((undef_bfd->flags & DYNAMIC) == 0
|
if ((undef_bfd->flags & DYNAMIC) == 0
|
||||||
|| info->hash->creator->flavour != bfd_target_elf_flavour
|
|| info->hash->creator->flavour != bfd_target_elf_flavour
|
||||||
|| elf_dt_soname (h->root.u.undef.abfd) == NULL)
|
|| elf_dt_soname (undef_bfd) == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
for (loaded = elf_hash_table (info)->loaded;
|
for (loaded = elf_hash_table (info)->loaded;
|
||||||
|
@ -6273,6 +6333,28 @@ elf_link_output_extsym (h, data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* We should also warn if a forced local symbol is referenced from
|
||||||
|
shared libraries. */
|
||||||
|
if (! finfo->info->relocateable
|
||||||
|
&& (! finfo->info->shared || ! finfo->info->allow_shlib_undefined)
|
||||||
|
&& (h->elf_link_hash_flags
|
||||||
|
& (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC
|
||||||
|
| ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK))
|
||||||
|
== (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC))
|
||||||
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
(_("%s: %s symbol `%s' in %s is referenced by DSO"),
|
||||||
|
bfd_get_filename (finfo->output_bfd),
|
||||||
|
ELF_ST_VISIBILITY (h->other) == STV_INTERNAL
|
||||||
|
? "internal"
|
||||||
|
: ELF_ST_VISIBILITY (h->other) == STV_HIDDEN
|
||||||
|
? "hidden" : "local",
|
||||||
|
h->root.root.string,
|
||||||
|
bfd_archive_filename (h->root.u.def.section->owner));
|
||||||
|
eoinfo->failed = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* We don't want to output symbols that have never been mentioned by
|
/* We don't want to output symbols that have never been mentioned by
|
||||||
a regular file, or that we have been told to strip. However, if
|
a regular file, or that we have been told to strip. However, if
|
||||||
h->indx is set to -2, the symbol is used by a reloc and we must
|
h->indx is set to -2, the symbol is used by a reloc and we must
|
||||||
|
@ -6433,10 +6515,25 @@ elf_link_output_extsym (h, data)
|
||||||
sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
|
sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a symbol is not defined locally, we clear the visibility field. */
|
/* If a non-weak symbol with non-default visibility is not defined
|
||||||
|
locally, it is a fatal error. */
|
||||||
if (! finfo->info->relocateable
|
if (! finfo->info->relocateable
|
||||||
|
&& ELF_ST_VISIBILITY (sym.st_other)
|
||||||
|
&& ELF_ST_BIND (sym.st_info) != STB_WEAK
|
||||||
|
&& h->root.type != bfd_link_hash_undefweak
|
||||||
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
|
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
|
||||||
sym.st_other &= ~ ELF_ST_VISIBILITY (-1);
|
{
|
||||||
|
(*_bfd_error_handler)
|
||||||
|
(_("%s: %s symbol `%s' isn't defined"),
|
||||||
|
bfd_get_filename (finfo->output_bfd),
|
||||||
|
ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED
|
||||||
|
? "protected"
|
||||||
|
: ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL
|
||||||
|
? "internal" : "hidden",
|
||||||
|
h->root.root.string);
|
||||||
|
eoinfo->failed = TRUE;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* If this symbol should be put in the .dynsym section, then put it
|
/* If this symbol should be put in the .dynsym section, then put it
|
||||||
there now. We already know the symbol index. We also fill in
|
there now. We already know the symbol index. We also fill in
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
2003-04-27 H.J. Lu <hjl@gnu.org>
|
||||||
|
|
||||||
|
* ld-elfvsb/elfvsb.dat: Updated.
|
||||||
|
* ld-elfvsb/elfvsb.exp: Likewise.
|
||||||
|
* ld-elfvsb/main.c: Likewise.
|
||||||
|
* ld-elfvsb/sh1.c: Likewise.
|
||||||
|
* ld-elfvsb/sh2.c: Likewise.
|
||||||
|
|
||||||
2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
|
2003-04-26 Stephane Carrez <stcarrez@nerim.fr>
|
||||||
|
|
||||||
* ld-m68hc11/bug-3331.d: New test.
|
* ld-m68hc11/bug-3331.d: New test.
|
||||||
|
|
|
@ -20,3 +20,7 @@ main_visibility_check () == 1
|
||||||
visibility_checkvar () == 1
|
visibility_checkvar () == 1
|
||||||
visibility_checkvarptr () == 1
|
visibility_checkvarptr () == 1
|
||||||
main_visibility_checkvar () == 1
|
main_visibility_checkvar () == 1
|
||||||
|
main_visibility_checkcom () == 1
|
||||||
|
shlib_visibility_checkcom () == 1
|
||||||
|
main_visibility_checkweak () == 1
|
||||||
|
shlib_visibility_checkweak () == 1
|
||||||
|
|
|
@ -144,6 +144,8 @@ proc visibility_test { visibility progname testname main sh1 sh2 dat args } {
|
||||||
pass "$testname"
|
pass "$testname"
|
||||||
} else { if { [ string match $visibility "hidden_undef_def" ]
|
} else { if { [ string match $visibility "hidden_undef_def" ]
|
||||||
&& [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
|
&& [regexp ".*/main.c.*: undefined reference to \`visibility\'" $link_output]
|
||||||
|
&& [regexp ".*/main.c.*: undefined reference to \`visibility_def\'" $link_output]
|
||||||
|
&& [regexp ".*/main.c.*: undefined reference to \`visibility_func\'" $link_output]
|
||||||
&& [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
|
&& [regexp ".*/main.c.*: undefined reference to \`visibility_var\'" $link_output] } {
|
||||||
pass "$testname"
|
pass "$testname"
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -42,6 +42,18 @@ extern int visibility_checkvar ();
|
||||||
extern int visibility_checkvarptr ();
|
extern int visibility_checkvarptr ();
|
||||||
extern int visibility_varval ();
|
extern int visibility_varval ();
|
||||||
extern void *visibility_varptr ();
|
extern void *visibility_varptr ();
|
||||||
|
extern int shlib_visibility_checkcom ();
|
||||||
|
extern int shlib_visibility_checkweak ();
|
||||||
|
|
||||||
|
int shlib_visibility_com = 1;
|
||||||
|
|
||||||
|
int shlib_visibility_var_weak = 1;
|
||||||
|
|
||||||
|
int
|
||||||
|
shlib_visibility_func_weak ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef HIDDEN_WEAK_TEST
|
#ifdef HIDDEN_WEAK_TEST
|
||||||
#define WEAK_TEST
|
#define WEAK_TEST
|
||||||
|
@ -81,6 +93,23 @@ main_visibility_checkvar ()
|
||||||
return visibility_varval () != visibility_var
|
return visibility_varval () != visibility_var
|
||||||
&& visibility_varptr () != &visibility_var;
|
&& visibility_varptr () != &visibility_var;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef PROTECTED_UNDEF_TEST
|
||||||
|
int shared_data = 1;
|
||||||
|
asm (".protected shared_data");
|
||||||
|
|
||||||
|
int
|
||||||
|
shared_func ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
asm (".protected shared_func");
|
||||||
|
|
||||||
|
extern int * shared_data_p ();
|
||||||
|
typedef int (*func) ();
|
||||||
|
extern func shared_func_p ();
|
||||||
|
#endif
|
||||||
#else
|
#else
|
||||||
static int
|
static int
|
||||||
main_visibility_check ()
|
main_visibility_check ()
|
||||||
|
@ -121,10 +150,57 @@ shlib_overriddencall2 ()
|
||||||
return 8;
|
return 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HIDDEN_NORMAL_TEST
|
||||||
|
int visibility_com;
|
||||||
|
asm (".hidden visibility_com");
|
||||||
|
|
||||||
|
int
|
||||||
|
main_visibility_checkcom ()
|
||||||
|
{
|
||||||
|
return visibility_com == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main_visibility_checkweak ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#elif defined (HIDDEN_UNDEF_TEST)
|
||||||
|
extern int visibility_def;
|
||||||
|
asm (".hidden visibility_def");
|
||||||
|
extern int visibility_func ();
|
||||||
|
asm (".hidden visibility_func");
|
||||||
|
|
||||||
|
int
|
||||||
|
main_visibility_checkcom ()
|
||||||
|
{
|
||||||
|
return &visibility_def != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main_visibility_checkweak ()
|
||||||
|
{
|
||||||
|
return &visibility_func != NULL;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
main_visibility_checkcom ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main_visibility_checkweak ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int
|
int
|
||||||
main ()
|
main ()
|
||||||
{
|
{
|
||||||
int (*p) ();
|
int (*p) ();
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
printf ("mainvar == %d\n", mainvar);
|
printf ("mainvar == %d\n", mainvar);
|
||||||
printf ("overriddenvar == %d\n", overriddenvar);
|
printf ("overriddenvar == %d\n", overriddenvar);
|
||||||
|
@ -173,6 +249,27 @@ main ()
|
||||||
visibility_checkvarptr ());
|
visibility_checkvarptr ());
|
||||||
printf ("main_visibility_checkvar () == %d\n",
|
printf ("main_visibility_checkvar () == %d\n",
|
||||||
main_visibility_checkvar ());
|
main_visibility_checkvar ());
|
||||||
return 0;
|
printf ("main_visibility_checkcom () == %d\n",
|
||||||
|
main_visibility_checkcom ());
|
||||||
|
printf ("shlib_visibility_checkcom () == %d\n",
|
||||||
|
shlib_visibility_checkcom ());
|
||||||
|
printf ("main_visibility_checkweak () == %d\n",
|
||||||
|
main_visibility_checkweak ());
|
||||||
|
printf ("shlib_visibility_checkweak () == %d\n",
|
||||||
|
shlib_visibility_checkweak ());
|
||||||
|
|
||||||
|
#if !defined (PROTECTED_UNDEF_TEST) && defined (PROTECTED_TEST)
|
||||||
|
if (&shared_data != shared_data_p ())
|
||||||
|
ret = 1;
|
||||||
|
p = shared_func_p ();
|
||||||
|
if (shared_func != p)
|
||||||
|
ret = 1;
|
||||||
|
if (shared_data != *shared_data_p ())
|
||||||
|
ret = 1;
|
||||||
|
if (shared_func () != (*p) () )
|
||||||
|
ret = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -323,3 +323,54 @@ asm (".protected visibility");
|
||||||
asm (".protected visibility_var");
|
asm (".protected visibility_var");
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HIDDEN_NORMAL_TEST
|
||||||
|
int shlib_visibility_com;
|
||||||
|
asm (".hidden shlib_visibility_com");
|
||||||
|
|
||||||
|
int
|
||||||
|
shlib_visibility_checkcom ()
|
||||||
|
{
|
||||||
|
return shlib_visibility_com == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
shlib_visibility_checkweak ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int
|
||||||
|
shlib_visibility_checkcom ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
shlib_visibility_checkweak ()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef PROTECTED_TEST
|
||||||
|
int shared_data = 100;
|
||||||
|
|
||||||
|
int *
|
||||||
|
shared_data_p ()
|
||||||
|
{
|
||||||
|
return &shared_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
shared_func ()
|
||||||
|
{
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
shared_func_p ()
|
||||||
|
{
|
||||||
|
return shared_func;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -5,6 +5,10 @@
|
||||||
the shared library. */
|
the shared library. */
|
||||||
int shlibvar2 = 4;
|
int shlibvar2 = 4;
|
||||||
|
|
||||||
|
/* This variable is defined here, and shouldn't be used to resolve a
|
||||||
|
reference with non-default visibility in another shared library. */
|
||||||
|
int visibility_com = 2;
|
||||||
|
|
||||||
/* This function is called by another file in the shared library. */
|
/* This function is called by another file in the shared library. */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -21,4 +25,22 @@ visibility ()
|
||||||
}
|
}
|
||||||
|
|
||||||
int visibility_var = 2;
|
int visibility_var = 2;
|
||||||
|
|
||||||
|
int visibility_def = 2;
|
||||||
|
|
||||||
|
int
|
||||||
|
visibility_func ()
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HIDDEN_WEAK_TEST
|
||||||
|
int visibility_var_weak = 2;
|
||||||
|
|
||||||
|
int
|
||||||
|
visibility_func_weak ()
|
||||||
|
{
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue