// dynobj.cc -- dynamic object support for gold
+// Copyright 2006, 2007 Free Software Foundation, Inc.
+// Written by Ian Lance Taylor <iant@google.com>.
+
+// This file is part of gold.
+
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; either version 3 of the License, or
+// (at your option) any later version.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+// MA 02110-1301, USA.
+
#include "gold.h"
#include <vector>
#include <cstring>
#include "elfcpp.h"
+#include "parameters.h"
#include "symtab.h"
#include "dynobj.h"
gold_exit(false);
}
- *view = this->get_lasting_view(shdr.get_sh_offset(), shdr.get_sh_size());
+ *view = this->get_lasting_view(shdr.get_sh_offset(), shdr.get_sh_size(),
+ false);
*view_size = shdr.get_sh_size();
*view_info = shdr.get_sh_info();
}
const off_t dynamic_size = dynamicshdr.get_sh_size();
const unsigned char* pdynamic = this->get_view(dynamicshdr.get_sh_offset(),
- dynamic_size);
+ dynamic_size, false);
const unsigned int link = dynamicshdr.get_sh_link();
if (link != strtab_shndx)
}
strtab_size = strtabshdr.get_sh_size();
- strtabu = this->get_view(strtabshdr.get_sh_offset(), strtab_size);
+ strtabu = this->get_view(strtabshdr.get_sh_offset(), strtab_size, false);
}
for (const unsigned char* p = pdynamic;
gold_assert(dynsymshdr.get_sh_type() == elfcpp::SHT_DYNSYM);
sd->symbols = this->get_lasting_view(dynsymshdr.get_sh_offset(),
- dynsymshdr.get_sh_size());
+ dynsymshdr.get_sh_size(), false);
sd->symbols_size = dynsymshdr.get_sh_size();
// Get the symbol names.
}
sd->symbol_names = this->get_lasting_view(strtabshdr.get_sh_offset(),
- strtabshdr.get_sh_size());
+ strtabshdr.get_sh_size(),
+ true);
sd->symbol_names_size = strtabshdr.get_sh_size();
// Get the version information.
template<int size, bool big_endian>
void
-Sized_dynobj<size, big_endian>::do_layout(const General_options&,
- Symbol_table* symtab,
+Sized_dynobj<size, big_endian>::do_layout(Symbol_table* symtab,
Layout*,
Read_symbols_data* sd)
{
// symbol table.
void
-Dynobj::create_elf_hash_table(const Target* target,
- const std::vector<Symbol*>& dynsyms,
+Dynobj::create_elf_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
* 4);
unsigned char* phash = new unsigned char[hashlen];
- if (target->is_big_endian())
- Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash, hashlen);
+ if (parameters->is_big_endian())
+ {
+#if defined(HAVE_TARGET_32_BIG) || defined(HAVE_TARGET_64_BIG)
+ Dynobj::sized_create_elf_hash_table<true>(bucket, chain, phash,
+ hashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash, hashlen);
+ {
+#if defined(HAVE_TARGET_32_LITTLE) || defined(HAVE_TARGET_64_LITTLE)
+ Dynobj::sized_create_elf_hash_table<false>(bucket, chain, phash,
+ hashlen);
+#else
+ gold_unreachable();
+#endif
+ }
*pphash = phash;
*phashlen = hashlen;
// symbol table.
void
-Dynobj::create_gnu_hash_table(const Target* target,
- const std::vector<Symbol*>& dynsyms,
+Dynobj::create_gnu_hash_table(const std::vector<Symbol*>& dynsyms,
unsigned int local_dynsym_count,
unsigned char** pphash,
unsigned int* phashlen)
// For the actual data generation we call out to a templatized
// function.
- int size = target->get_size();
- bool big_endian = target->is_big_endian();
+ int size = parameters->get_size();
+ bool big_endian = parameters->is_big_endian();
if (size == 32)
{
if (big_endian)
- Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_32_BIG
+ Dynobj::sized_create_gnu_hash_table<32, true>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_32_LITTLE
+ Dynobj::sized_create_gnu_hash_table<32, false>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
}
else if (size == 64)
{
if (big_endian)
- Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_64_BIG
+ Dynobj::sized_create_gnu_hash_table<64, true>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
else
- Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms,
- dynsym_hashvals,
- unhashed_dynsym_index,
- pphash,
- phashlen);
+ {
+#ifdef HAVE_TARGET_64_LITTLE
+ Dynobj::sized_create_gnu_hash_table<64, false>(hashed_dynsyms,
+ dynsym_hashvals,
+ unhashed_dynsym_index,
+ pphash,
+ phashlen);
+#else
+ gold_unreachable();
+#endif
+ }
}
else
gold_unreachable();
const char* version = dynpool->add(sym->version(), &version_key);
if (!sym->is_from_dynobj())
- this->add_def(options, sym, version, version_key);
+ {
+ if (parameters->output_is_shared())
+ this->add_def(options, sym, version, version_key);
+ }
else
{
// This is a version reference.
// If we are creating a shared object, it is an error to
// find a definition of a symbol with a version which is not
// in the version script.
- if (options->is_shared())
+ if (parameters->output_is_shared())
{
fprintf(stderr, _("%s: symbol %s has undefined version %s\n"),
program_name, sym->name(), version);
elfcpp::STV_DEFAULT, 0,
false);
vsym->set_needs_dynsym_entry();
+ vsym->set_dynsym_index(dynsym_index);
++dynsym_index;
syms->push_back(vsym);
// The name is already in the dynamic pool.
Key k;
if (!sym->is_from_dynobj())
- k = Key(version_key, 0);
+ {
+ if (!parameters->output_is_shared())
+ return elfcpp::VER_NDX_GLOBAL;
+ k = Key(version_key, 0);
+ }
else
{
Object* object = sym->object();