*pverneed_shndx = -1U;
*pdynamic_shndx = -1U;
+ unsigned int symtab_shndx = 0;
unsigned int xindex_shndx = 0;
unsigned int xindex_link = 0;
const unsigned int shnum = this->shnum();
}
pi = NULL;
break;
+ case elfcpp::SHT_SYMTAB:
+ symtab_shndx = i;
+ pi = NULL;
+ break;
case elfcpp::SHT_GNU_versym:
pi = pversym_shndx;
break;
*pi = i;
}
+
+ // If there is no dynamic symbol table, use the normal symbol table.
+ // On some SVR4 systems, a shared library is stored in an archive.
+ // The version stored in the archive only has a normal symbol table.
+ // It has an SONAME entry which points to another copy in the file
+ // system which has a dynamic symbol table as usual. This is way of
+ // addressing the issues which glibc addresses using GROUP with
+ // libc_nonshared.a.
+ if (this->dynsym_shndx_ == -1U && symtab_shndx != 0)
+ {
+ this->dynsym_shndx_ = symtab_shndx;
+ if (xindex_shndx > 0 && xindex_link == symtab_shndx)
+ {
+ Xindex* xindex = new Xindex(this->elf_file_.large_shndx_offset());
+ xindex->read_symtab_xindex<size, big_endian>(this, xindex_shndx,
+ pshdrs);
+ this->set_xindex(xindex);
+ }
+ }
}
// Read the contents of section SHNDX. PSHDRS points to the section
// Get the dynamic symbols.
typename This::Shdr dynsymshdr(pshdrs
+ this->dynsym_shndx_ * This::shdr_size);
- gold_assert(dynsymshdr.get_sh_type() == elfcpp::SHT_DYNSYM);
sd->symbols = this->get_lasting_view(dynsymshdr.get_sh_offset(),
dynsymshdr.get_sh_size(), true,
this->clear_view_cache_marks();
}
+template<int size, bool big_endian>
+Archive::Should_include
+Sized_dynobj<size, big_endian>::do_should_include_member(
+ Symbol_table*, Read_symbols_data*, std::string*)
+{
+ return Archive::SHOULD_INCLUDE_YES;
+}
+
// Get symbol counts.
template<int size, bool big_endian>
elfcpp::Verdef_write<size, big_endian> vd(pb);
vd.set_vd_version(elfcpp::VER_DEF_CURRENT);
vd.set_vd_flags((this->is_base_ ? elfcpp::VER_FLG_BASE : 0)
- | (this->is_weak_ ? elfcpp::VER_FLG_WEAK : 0));
+ | (this->is_weak_ ? elfcpp::VER_FLG_WEAK : 0)
+ | (this->is_info_ ? elfcpp::VER_FLG_INFO : 0));
vd.set_vd_ndx(this->index());
vd.set_vd_cnt(1 + this->deps_.size());
vd.set_vd_hash(Dynobj::elf_hash(this->name()));
Verdef* const vd = new Verdef(
version,
this->version_script_.get_dependencies(version),
- false, false, false);
+ false, false, false, false);
this->defs_.push_back(vd);
Key key(version_key, 0);
this->version_table_.insert(std::make_pair(key, vd));
name = parameters->options().output_file_name();
name = dynpool->add(name, false, NULL);
Verdef* vdbase = new Verdef(name, std::vector<std::string>(),
- true, false, true);
+ true, false, false, true);
this->defs_.push_back(vdbase);
this->needs_base_version_ = false;
}
// When creating a regular executable, automatically define
// a new version.
Verdef* vd = new Verdef(version, std::vector<std::string>(),
- false, false, false);
+ false, false, false, false);
this->defs_.push_back(vd);
ins.first->second = vd;
}
false, false);
vsym->set_needs_dynsym_entry();
vsym->set_dynsym_index(dynsym_index);
+ vsym->set_is_default();
++dynsym_index;
syms->push_back(vsym);
// The name is already in the dynamic pool.
{
unsigned int version_index;
const char* version = (*p)->version();
- if (version == NULL)
- version_index = elfcpp::VER_NDX_GLOBAL;
- else
+ if (version != NULL)
version_index = this->version_index(symtab, dynpool, *p);
+ else
+ {
+ if ((*p)->is_defined() && !(*p)->is_from_dynobj())
+ version_index = elfcpp::VER_NDX_GLOBAL;
+ else
+ version_index = elfcpp::VER_NDX_LOCAL;
+ }
// If the symbol was defined as foo@V1 instead of foo@@V1, add
// the hidden bit.
if ((*p)->version() != NULL && !(*p)->is_default())