diff options
author | Ian Lance Taylor <ian@airs.com> | 2008-05-06 22:24:26 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 2008-05-06 22:24:26 +0000 |
commit | 8bdcdf2c7708338645fa9bc512a3cc0f2e438a80 (patch) | |
tree | 7d52c57dc3c214c17b5c6c2b0b916a3c73469e1c /gold/symtab.cc | |
parent | b5dd68e23111c3ca966a99118e032fc0cd817f9b (diff) | |
download | gdb-8bdcdf2c7708338645fa9bc512a3cc0f2e438a80.zip gdb-8bdcdf2c7708338645fa9bc512a3cc0f2e438a80.tar.gz gdb-8bdcdf2c7708338645fa9bc512a3cc0f2e438a80.tar.bz2 |
* symtab.cc (Symbol_table::add_from_dynobj): If we see a protected
symbol, change it to have default visibility.
* testsuite/protected_1.cc: New file.
* testsuite/protected_2.cc: New file.
* testsuite/protected_3.cc: New file.
* testsuite/protected_main_1.cc: New file.
* testsuite/protected_main_2.cc: New file.
* testsuite/protected_main_3.cc: New file.
* testsuite/Makefile.am (check_PROGRAMS): Add protected_1.
(protected_1_SOURCES, protected_1_DEPENDENCIES): Define.
(protected_1_LDFLAGS, protected_1_LDADD): Define.
(protected_1.so): New target.
(protected_1_pic.o, protected_2_pic.o): New targets.
(protected_3_pic.o): New target.
(check_PROGRAMS): Add protected_2.
(protected_2_SOURCES, protected_2_DEPENDENCIES): Define.
(protected_2_LDFLAGS, protected_2_LDADD): Define.
* testsuite/Makefile.in: Rebuild.
Diffstat (limited to 'gold/symtab.cc')
-rw-r--r-- | gold/symtab.cc | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/gold/symtab.cc b/gold/symtab.cc index 170a209..522ca62 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -942,7 +942,21 @@ Symbol_table::add_from_dynobj( || sym.get_st_visibility() == elfcpp::STV_HIDDEN) continue; - unsigned int st_name = sym.get_st_name(); + // A protected symbol in a shared library must be treated as a + // normal symbol when viewed from outside the shared library. + // Implement this by overriding the visibility here. + elfcpp::Sym<size, big_endian>* psym = &sym; + unsigned char symbuf[sym_size]; + elfcpp::Sym<size, big_endian> sym2(symbuf); + if (sym.get_st_visibility() == elfcpp::STV_PROTECTED) + { + memcpy(symbuf, p, sym_size); + elfcpp::Sym_write<size, big_endian> sw(symbuf); + sw.put_st_other(elfcpp::STV_DEFAULT, sym.get_st_nonvis()); + psym = &sym2; + } + + unsigned int st_name = psym->get_st_name(); if (st_name >= sym_name_size) { dynobj->error(_("bad symbol name offset %u at %zu"), @@ -953,7 +967,7 @@ Symbol_table::add_from_dynobj( const char* name = sym_names + st_name; bool is_ordinary; - unsigned int st_shndx = dynobj->adjust_sym_shndx(i, sym.get_st_shndx(), + unsigned int st_shndx = dynobj->adjust_sym_shndx(i, psym->get_st_shndx(), &is_ordinary); Sized_symbol<size>* res; @@ -963,7 +977,7 @@ Symbol_table::add_from_dynobj( Stringpool::Key name_key; name = this->namepool_.add(name, true, &name_key); res = this->add_from_object(dynobj, name, name_key, NULL, 0, - false, sym, st_shndx, is_ordinary, + false, *psym, st_shndx, is_ordinary, st_shndx); } else @@ -998,7 +1012,7 @@ Symbol_table::add_from_dynobj( { // This symbol does not have a version. res = this->add_from_object(dynobj, name, name_key, NULL, 0, - false, sym, st_shndx, is_ordinary, + false, *psym, st_shndx, is_ordinary, st_shndx); } else @@ -1030,14 +1044,14 @@ Symbol_table::add_from_dynobj( && !is_ordinary && name_key == version_key) res = this->add_from_object(dynobj, name, name_key, NULL, 0, - false, sym, st_shndx, is_ordinary, + false, *psym, st_shndx, is_ordinary, st_shndx); else { const bool def = (!hidden && st_shndx != elfcpp::SHN_UNDEF); res = this->add_from_object(dynobj, name, name_key, version, - version_key, def, sym, st_shndx, + version_key, def, *psym, st_shndx, is_ordinary, st_shndx); } } @@ -1047,7 +1061,7 @@ Symbol_table::add_from_dynobj( // earlier object, in which case it can't be aliased here. if (st_shndx != elfcpp::SHN_UNDEF && is_ordinary - && sym.get_st_type() == elfcpp::STT_OBJECT + && psym->get_st_type() == elfcpp::STT_OBJECT && res->source() == Symbol::FROM_OBJECT && res->object() == dynobj) object_symbols.push_back(res); |