Snapshot. Includes first cut at output relocation sections.
This commit is contained in:
parent
7495b3afc0
commit
c06b7b0ba3
17 changed files with 885 additions and 179 deletions
|
@ -1163,7 +1163,7 @@ class Sym_write
|
|||
internal::Sym_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor classes for Elf relocation table entries.
|
||||
// Accessor classes for an ELF REL relocation entry.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Rel
|
||||
|
@ -1191,6 +1191,30 @@ class Rel
|
|||
const internal::Rel_data<size>* p_;
|
||||
};
|
||||
|
||||
// Writer class for an ELF Rel relocation.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Rel_write
|
||||
{
|
||||
public:
|
||||
Rel_write(unsigned char* p)
|
||||
: p_(reinterpret_cast<internal::Rel_data<size>*>(p))
|
||||
{ }
|
||||
|
||||
void
|
||||
put_r_offset(typename Elf_types<size>::Elf_Addr v)
|
||||
{ this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
void
|
||||
put_r_info(typename Elf_types<size>::Elf_WXword v)
|
||||
{ this->p_->r_info = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
private:
|
||||
internal::Rel_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor class for an ELF Rela relocation.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Rela
|
||||
{
|
||||
|
@ -1221,6 +1245,32 @@ class Rela
|
|||
const internal::Rela_data<size>* p_;
|
||||
};
|
||||
|
||||
// Writer class for an ELF Rela relocation.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
class Rela_write
|
||||
{
|
||||
public:
|
||||
Rela_write(unsigned char* p)
|
||||
: p_(reinterpret_cast<internal::Rela_data<size>*>(p))
|
||||
{ }
|
||||
|
||||
void
|
||||
put_r_offset(typename Elf_types<size>::Elf_Addr v)
|
||||
{ this->p_->r_offset = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
void
|
||||
put_r_info(typename Elf_types<size>::Elf_WXword v)
|
||||
{ this->p_->r_info = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
void
|
||||
put_r_addend(typename Elf_types<size>::Elf_Swxword v)
|
||||
{ this->p_->r_addend = Convert<size, big_endian>::convert_host(v); }
|
||||
|
||||
private:
|
||||
internal::Rela_data<size>* p_;
|
||||
};
|
||||
|
||||
// Accessor classes for entries in the ELF SHT_DYNAMIC section aka
|
||||
// PT_DYNAMIC segment.
|
||||
|
||||
|
|
|
@ -56,7 +56,9 @@ HFILES = \
|
|||
output.h \
|
||||
readsyms.h \
|
||||
reloc.h \
|
||||
reloc-types.h \
|
||||
script.h \
|
||||
script-c.h \
|
||||
stringpool.h \
|
||||
symtab.h \
|
||||
target.h \
|
||||
|
|
|
@ -272,7 +272,9 @@ HFILES = \
|
|||
output.h \
|
||||
readsyms.h \
|
||||
reloc.h \
|
||||
reloc-types.h \
|
||||
script.h \
|
||||
script-c.h \
|
||||
stringpool.h \
|
||||
symtab.h \
|
||||
target.h \
|
||||
|
|
|
@ -96,7 +96,7 @@ class Target_i386 : public Sized_target<32, false>
|
|||
inline bool
|
||||
relocate(const Relocate_info<32, false>*, Target_i386*, size_t relnum,
|
||||
const elfcpp::Rel<32, false>&,
|
||||
unsigned int r_type, Sized_symbol<32>*,
|
||||
unsigned int r_type, const Sized_symbol<32>*,
|
||||
elfcpp::Elf_types<32>::Elf_Addr,
|
||||
unsigned char*, elfcpp::Elf_types<32>::Elf_Addr,
|
||||
off_t);
|
||||
|
@ -106,7 +106,7 @@ class Target_i386 : public Sized_target<32, false>
|
|||
inline void
|
||||
relocate_tls(const Relocate_info<32, false>*, size_t relnum,
|
||||
const elfcpp::Rel<32, false>&,
|
||||
unsigned int r_type, Sized_symbol<32>*,
|
||||
unsigned int r_type, const Sized_symbol<32>*,
|
||||
elfcpp::Elf_types<32>::Elf_Addr,
|
||||
unsigned char*, elfcpp::Elf_types<32>::Elf_Addr, off_t);
|
||||
|
||||
|
@ -529,7 +529,7 @@ Target_i386::Relocate::relocate(const Relocate_info<32, false>* relinfo,
|
|||
size_t relnum,
|
||||
const elfcpp::Rel<32, false>& rel,
|
||||
unsigned int r_type,
|
||||
Sized_symbol<32>* gsym,
|
||||
const Sized_symbol<32>* gsym,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<32>::Elf_Addr address,
|
||||
|
@ -670,7 +670,7 @@ Target_i386::Relocate::relocate_tls(const Relocate_info<32, false>* relinfo,
|
|||
size_t relnum,
|
||||
const elfcpp::Rel<32, false>& rel,
|
||||
unsigned int r_type,
|
||||
Sized_symbol<32>* gsym,
|
||||
const Sized_symbol<32>* gsym,
|
||||
elfcpp::Elf_types<32>::Elf_Addr value,
|
||||
unsigned char* view,
|
||||
elfcpp::Elf_types<32>::Elf_Addr,
|
||||
|
|
|
@ -676,19 +676,24 @@ Layout::create_symtab_sections(int size, const Input_objects* input_objects,
|
|||
// Save space for the dummy symbol at the start of the section. We
|
||||
// never bother to write this out--it will just be left as zero.
|
||||
off += symsize;
|
||||
unsigned int local_symbol_index = 1;
|
||||
|
||||
for (Input_objects::Relobj_iterator p = input_objects->relobj_begin();
|
||||
p != input_objects->relobj_end();
|
||||
++p)
|
||||
{
|
||||
Task_lock_obj<Object> tlo(**p);
|
||||
off = (*p)->finalize_local_symbols(off, &this->sympool_);
|
||||
unsigned int index = (*p)->finalize_local_symbols(local_symbol_index,
|
||||
off,
|
||||
&this->sympool_);
|
||||
off += (index - local_symbol_index) * symsize;
|
||||
local_symbol_index = index;
|
||||
}
|
||||
|
||||
unsigned int local_symcount = (off - startoff) / symsize;
|
||||
unsigned int local_symcount = local_symbol_index;
|
||||
assert(local_symcount * symsize == off - startoff);
|
||||
|
||||
off = symtab->finalize(off, &this->sympool_);
|
||||
off = symtab->finalize(local_symcount, off, &this->sympool_);
|
||||
|
||||
this->sympool_.set_string_offsets();
|
||||
|
||||
|
|
|
@ -128,7 +128,8 @@ Sized_relobj<size, big_endian>::Sized_relobj(
|
|||
output_local_symbol_count_(0),
|
||||
symbols_(NULL),
|
||||
local_symbol_offset_(0),
|
||||
values_(NULL)
|
||||
local_values_(),
|
||||
local_indexes_()
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -505,23 +506,25 @@ Sized_relobj<size, big_endian>::do_add_symbols(Symbol_table* symtab,
|
|||
|
||||
// Finalize the local symbols. Here we record the file offset at
|
||||
// which they should be output, we add their names to *POOL, and we
|
||||
// add their values to THIS->VALUES_. Return the new file offset.
|
||||
// This function is always called from the main thread. The actual
|
||||
// output of the local symbols will occur in a separate task.
|
||||
// add their values to THIS->LOCAL_VALUES_ and their indexes in the
|
||||
// output symbol table to THIS->LOCAL_INDEXES_. Return the symbol
|
||||
// index. This function is always called from the main thread. The
|
||||
// actual output of the local symbols will occur in a separate task.
|
||||
|
||||
template<int size, bool big_endian>
|
||||
off_t
|
||||
Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
|
||||
unsigned int
|
||||
Sized_relobj<size, big_endian>::do_finalize_local_symbols(unsigned int index,
|
||||
off_t off,
|
||||
Stringpool* pool)
|
||||
{
|
||||
assert(this->symtab_shndx_ != -1U);
|
||||
if (this->symtab_shndx_ == 0)
|
||||
{
|
||||
// This object has no symbols. Weird but legal.
|
||||
return off;
|
||||
return index;
|
||||
}
|
||||
|
||||
off = align_address(off, size >> 3);
|
||||
assert(off == static_cast<off_t>(align_address(off, size >> 3)));
|
||||
|
||||
this->local_symbol_offset_ = off;
|
||||
|
||||
|
@ -539,7 +542,8 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
|
|||
const unsigned char* psyms = this->get_view(symtabshdr.get_sh_offset(),
|
||||
locsize);
|
||||
|
||||
this->values_ = new typename elfcpp::Elf_types<size>::Elf_Addr[loccount];
|
||||
this->local_values_.resize(loccount);
|
||||
this->local_indexes_.resize(loccount);
|
||||
|
||||
// Read the symbol names.
|
||||
const unsigned int strtab_shndx = symtabshdr.get_sh_link();
|
||||
|
@ -550,7 +554,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
|
|||
|
||||
// Loop over the local symbols.
|
||||
|
||||
std::vector<Map_to_output>& mo(this->map_to_output());
|
||||
const std::vector<Map_to_output>& mo(this->map_to_output());
|
||||
unsigned int shnum = this->shnum();
|
||||
unsigned int count = 0;
|
||||
// Skip the first, dummy, symbol.
|
||||
|
@ -564,7 +568,7 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
|
|||
if (shndx >= elfcpp::SHN_LORESERVE)
|
||||
{
|
||||
if (shndx == elfcpp::SHN_ABS)
|
||||
this->values_[i] = sym.get_st_value();
|
||||
this->local_values_[i] = sym.get_st_value();
|
||||
else
|
||||
{
|
||||
// FIXME: Handle SHN_XINDEX.
|
||||
|
@ -588,37 +592,46 @@ Sized_relobj<size, big_endian>::do_finalize_local_symbols(off_t off,
|
|||
|
||||
if (mo[shndx].output_section == NULL)
|
||||
{
|
||||
this->values_[i] = 0;
|
||||
this->local_values_[i] = 0;
|
||||
this->local_indexes_[i] = -1U;
|
||||
continue;
|
||||
}
|
||||
|
||||
this->values_[i] = (mo[shndx].output_section->address()
|
||||
+ mo[shndx].offset
|
||||
+ sym.get_st_value());
|
||||
this->local_values_[i] = (mo[shndx].output_section->address()
|
||||
+ mo[shndx].offset
|
||||
+ sym.get_st_value());
|
||||
}
|
||||
|
||||
if (sym.get_st_type() != elfcpp::STT_SECTION)
|
||||
// Decide whether this symbol should go into the output file.
|
||||
|
||||
if (sym.get_st_type() == elfcpp::STT_SECTION)
|
||||
{
|
||||
if (sym.get_st_name() >= strtab_size)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("%s: %s: local symbol %u section name "
|
||||
"out of range: %u >= %u\n"),
|
||||
program_name, this->name().c_str(),
|
||||
i, sym.get_st_name(),
|
||||
static_cast<unsigned int>(strtab_size));
|
||||
gold_exit(false);
|
||||
}
|
||||
|
||||
pool->add(pnames + sym.get_st_name(), NULL);
|
||||
off += sym_size;
|
||||
++count;
|
||||
this->local_indexes_[i] = -1U;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sym.get_st_name() >= strtab_size)
|
||||
{
|
||||
fprintf(stderr,
|
||||
_("%s: %s: local symbol %u section name "
|
||||
"out of range: %u >= %u\n"),
|
||||
program_name, this->name().c_str(),
|
||||
i, sym.get_st_name(),
|
||||
static_cast<unsigned int>(strtab_size));
|
||||
gold_exit(false);
|
||||
}
|
||||
|
||||
const char* name = pnames + sym.get_st_name();
|
||||
pool->add(name, NULL);
|
||||
this->local_indexes_[i] = index;
|
||||
++index;
|
||||
off += sym_size;
|
||||
++count;
|
||||
}
|
||||
|
||||
this->output_local_symbol_count_ = count;
|
||||
|
||||
return off;
|
||||
return index;
|
||||
}
|
||||
|
||||
// Write out the local symbols.
|
||||
|
@ -661,16 +674,20 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
|
|||
unsigned char* oview = of->get_output_view(this->local_symbol_offset_,
|
||||
output_size);
|
||||
|
||||
std::vector<Map_to_output>& mo(this->map_to_output());
|
||||
const std::vector<Map_to_output>& mo(this->map_to_output());
|
||||
|
||||
assert(this->local_values_.size() == loccount);
|
||||
assert(this->local_indexes_.size() == loccount);
|
||||
|
||||
psyms += sym_size;
|
||||
unsigned char* ov = oview;
|
||||
psyms += sym_size;
|
||||
for (unsigned int i = 1; i < loccount; ++i, psyms += sym_size)
|
||||
{
|
||||
elfcpp::Sym<size, big_endian> isym(psyms);
|
||||
|
||||
if (isym.get_st_type() == elfcpp::STT_SECTION)
|
||||
if (this->local_indexes_[i] == -1U)
|
||||
continue;
|
||||
assert(this->local_indexes_[i] != 0);
|
||||
|
||||
unsigned int st_shndx = isym.get_st_shndx();
|
||||
if (st_shndx < elfcpp::SHN_LORESERVE)
|
||||
|
@ -684,8 +701,9 @@ Sized_relobj<size, big_endian>::write_local_symbols(Output_file* of,
|
|||
elfcpp::Sym_write<size, big_endian> osym(ov);
|
||||
|
||||
assert(isym.get_st_name() < strtab_size);
|
||||
osym.put_st_name(sympool->get_offset(pnames + isym.get_st_name()));
|
||||
osym.put_st_value(this->values_[i]);
|
||||
const char* name = pnames + isym.get_st_name();
|
||||
osym.put_st_name(sympool->get_offset(name));
|
||||
osym.put_st_value(this->local_values_[i]);
|
||||
osym.put_st_size(isym.get_st_size());
|
||||
osym.put_st_info(isym.get_st_info());
|
||||
osym.put_st_other(isym.get_st_other());
|
||||
|
|
|
@ -352,10 +352,10 @@ class Relobj : public Object
|
|||
|
||||
// Initial local symbol processing: set the offset where local
|
||||
// symbol information will be stored; add local symbol names to
|
||||
// *POOL; return the offset following the local symbols.
|
||||
off_t
|
||||
finalize_local_symbols(off_t off, Stringpool* pool)
|
||||
{ return this->do_finalize_local_symbols(off, pool); }
|
||||
// *POOL; return the new local symbol index.
|
||||
unsigned int
|
||||
finalize_local_symbols(unsigned int index, off_t off, Stringpool* pool)
|
||||
{ return this->do_finalize_local_symbols(index, off, pool); }
|
||||
|
||||
// Relocate the input sections and write out the local symbols.
|
||||
void
|
||||
|
@ -408,8 +408,8 @@ class Relobj : public Object
|
|||
Read_relocs_data*) = 0;
|
||||
|
||||
// Finalize local symbols--implemented by child class.
|
||||
virtual off_t
|
||||
do_finalize_local_symbols(off_t, Stringpool*) = 0;
|
||||
virtual unsigned int
|
||||
do_finalize_local_symbols(unsigned int, off_t, Stringpool*) = 0;
|
||||
|
||||
// Relocate the input sections and write out the local
|
||||
// symbols--implemented by child class.
|
||||
|
@ -443,6 +443,9 @@ template<int size, bool big_endian>
|
|||
class Sized_relobj : public Relobj
|
||||
{
|
||||
public:
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||
typedef std::vector<Address> Local_values;
|
||||
|
||||
Sized_relobj(const std::string& name, Input_file* input_file, off_t offset,
|
||||
const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
|
||||
|
@ -452,6 +455,16 @@ class Sized_relobj : public Relobj
|
|||
void
|
||||
setup(const typename elfcpp::Ehdr<size, big_endian>&);
|
||||
|
||||
// Return the index of local symbol SYM in the ordinary symbol
|
||||
// table. A value of -1U means that the symbol is not being output.
|
||||
unsigned int
|
||||
symtab_index(unsigned int sym) const
|
||||
{
|
||||
assert(sym < this->local_indexes_.size());
|
||||
assert(this->local_indexes_[sym] != 0);
|
||||
return this->local_indexes_[sym];
|
||||
}
|
||||
|
||||
// Read the symbols.
|
||||
void
|
||||
do_read_symbols(Read_symbols_data*);
|
||||
|
@ -475,8 +488,8 @@ class Sized_relobj : public Relobj
|
|||
Read_relocs_data*);
|
||||
|
||||
// Finalize the local symbols.
|
||||
off_t
|
||||
do_finalize_local_symbols(off_t, Stringpool*);
|
||||
unsigned int
|
||||
do_finalize_local_symbols(unsigned int, off_t, Stringpool*);
|
||||
|
||||
// Relocate the input sections and write out the local symbols.
|
||||
void
|
||||
|
@ -563,7 +576,9 @@ class Sized_relobj : public Relobj
|
|||
// File offset for local symbols.
|
||||
off_t local_symbol_offset_;
|
||||
// Values of local symbols.
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr *values_;
|
||||
Local_values local_values_;
|
||||
// Indexes of local symbols in the output file; -1U if not present.
|
||||
std::vector<unsigned int> local_indexes_;
|
||||
};
|
||||
|
||||
// A class to manage the list of all objects.
|
||||
|
@ -643,9 +658,9 @@ struct Relocate_info
|
|||
// Number of local symbols.
|
||||
unsigned int local_symbol_count;
|
||||
// Values of local symbols.
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr *values;
|
||||
const typename Sized_relobj<size, big_endian>::Local_values* local_values;
|
||||
// Global symbols.
|
||||
Symbol** symbols;
|
||||
const Symbol* const * symbols;
|
||||
// Section index of relocation section.
|
||||
unsigned int reloc_shndx;
|
||||
// Section index of section being relocated.
|
||||
|
|
181
gold/output.cc
181
gold/output.cc
|
@ -366,6 +366,120 @@ Output_section_data::do_out_shndx() const
|
|||
return this->output_section_->out_shndx();
|
||||
}
|
||||
|
||||
// Output_reloc methods.
|
||||
|
||||
// Get the symbol index of a relocation.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
unsigned int
|
||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::get_symbol_index()
|
||||
const
|
||||
{
|
||||
unsigned int index;
|
||||
switch (this->local_sym_index_)
|
||||
{
|
||||
case INVALID_CODE:
|
||||
abort();
|
||||
|
||||
case GSYM_CODE:
|
||||
if (this->u_.gsym == NULL)
|
||||
index = 0;
|
||||
else if (dynamic)
|
||||
index = this->u_.gsym->dynsym_index();
|
||||
else
|
||||
index = this->u_.gsym->symtab_index();
|
||||
break;
|
||||
|
||||
case SECTION_CODE:
|
||||
if (dynamic)
|
||||
index = this->u_.os->dynsym_index();
|
||||
else
|
||||
index = this->u_.os->symtab_index();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (dynamic)
|
||||
{
|
||||
// FIXME: It seems that some targets may need to generate
|
||||
// dynamic relocations against local symbols for some
|
||||
// reasons. This will have to be addressed at some point.
|
||||
abort();
|
||||
}
|
||||
else
|
||||
index = this->u_.object->symtab_index(this->local_sym_index_);
|
||||
break;
|
||||
}
|
||||
assert(index != -1U);
|
||||
return index;
|
||||
}
|
||||
|
||||
// Write out the offset and info fields of a Rel or Rela relocation
|
||||
// entry.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
template<typename Write_rel>
|
||||
void
|
||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write_rel(
|
||||
Write_rel* wr) const
|
||||
{
|
||||
wr->put_r_offset(this->address_);
|
||||
wr->put_r_info(elfcpp::elf_r_info<size>(this->get_symbol_index(),
|
||||
this->type_));
|
||||
}
|
||||
|
||||
// Write out a Rel relocation.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
void
|
||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>::write(
|
||||
unsigned char* pov) const
|
||||
{
|
||||
elfcpp::Rel_write<size, big_endian> orel(pov);
|
||||
this->write_rel(&orel);
|
||||
}
|
||||
|
||||
// Write out a Rela relocation.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
void
|
||||
Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>::write(
|
||||
unsigned char* pov) const
|
||||
{
|
||||
elfcpp::Rela_write<size, big_endian> orel(pov);
|
||||
this->rel_.write_rel(&orel);
|
||||
orel.put_r_addend(this->addend_);
|
||||
}
|
||||
|
||||
// Output_data_reloc_base methods.
|
||||
|
||||
// Write out relocation data.
|
||||
|
||||
template<int sh_type, bool dynamic, int size, bool big_endian>
|
||||
void
|
||||
Output_data_reloc_base<sh_type, dynamic, size, big_endian>::do_write(
|
||||
Output_file* of)
|
||||
{
|
||||
const off_t off = this->offset();
|
||||
const off_t oview_size = this->data_size();
|
||||
unsigned char* const oview = of->get_output_view(off, oview_size);
|
||||
|
||||
unsigned char* pov = oview;
|
||||
for (typename Relocs::const_iterator p = this->relocs_.begin();
|
||||
p != this->relocs_.end();
|
||||
++p)
|
||||
{
|
||||
p->write(pov);
|
||||
pov += reloc_size;
|
||||
}
|
||||
|
||||
assert(pov - oview == oview_size);
|
||||
|
||||
of->write_output_view(off, oview_size, oview);
|
||||
|
||||
// We no longer need the relocation entries.
|
||||
this->relocs_.clear();
|
||||
}
|
||||
|
||||
// Output_data_got::Got_entry methods.
|
||||
|
||||
// Write out the entry.
|
||||
|
@ -439,7 +553,7 @@ Output_data_got<size, big_endian>::do_write(Output_file* of)
|
|||
const int add = size / 8;
|
||||
|
||||
const off_t off = this->offset();
|
||||
const off_t oview_size = this->entries_.size() * add;
|
||||
const off_t oview_size = this->data_size();
|
||||
unsigned char* const oview = of->get_output_view(off, oview_size);
|
||||
|
||||
unsigned char* pov = oview;
|
||||
|
@ -451,6 +565,8 @@ Output_data_got<size, big_endian>::do_write(Output_file* of)
|
|||
pov += add;
|
||||
}
|
||||
|
||||
assert(pov - oview == oview_size);
|
||||
|
||||
of->write_output_view(off, oview_size, oview);
|
||||
|
||||
// We no longer need the GOT entries.
|
||||
|
@ -508,6 +624,8 @@ Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
|
|||
type_(type),
|
||||
flags_(flags),
|
||||
out_shndx_(0),
|
||||
symtab_index_(0),
|
||||
dynsym_index_(0),
|
||||
input_sections_(),
|
||||
first_input_offset_(0),
|
||||
may_add_data_(may_add_data)
|
||||
|
@ -564,12 +682,17 @@ Output_section::add_input_section(Relobj* object, unsigned int shndx,
|
|||
void
|
||||
Output_section::add_output_section_data(Output_section_data* posd)
|
||||
{
|
||||
assert(this->may_add_data_);
|
||||
|
||||
if (this->input_sections_.empty())
|
||||
this->first_input_offset_ = this->data_size();
|
||||
|
||||
this->input_sections_.push_back(Input_section(posd));
|
||||
|
||||
uint64_t addralign = posd->addralign();
|
||||
if (addralign > this->addralign_)
|
||||
this->addralign_ = addralign;
|
||||
|
||||
posd->set_output_section(this);
|
||||
}
|
||||
|
||||
|
@ -627,14 +750,6 @@ Output_section::do_write(Output_file* of)
|
|||
p->write(of);
|
||||
}
|
||||
|
||||
// Output_section_symtab methods.
|
||||
|
||||
Output_section_symtab::Output_section_symtab(const char* name, off_t size)
|
||||
: Output_section(name, elfcpp::SHT_SYMTAB, 0, false)
|
||||
{
|
||||
this->set_data_size(size);
|
||||
}
|
||||
|
||||
// Output_section_strtab methods.
|
||||
|
||||
Output_section_strtab::Output_section_strtab(const char* name,
|
||||
|
@ -1143,6 +1258,54 @@ Output_section::add_input_section<64, true>(
|
|||
const char* secname,
|
||||
const elfcpp::Shdr<64, true>& shdr);
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, false, 32, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, false, 32, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, false, 64, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, false, 64, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, true, 32, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, true, 32, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, true, 64, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_REL, true, 64, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, false, 32, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, false, 32, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, false, 64, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, false, 64, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, true, 32, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, true, 32, true>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, true, 64, false>;
|
||||
|
||||
template
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, true, 64, true>;
|
||||
|
||||
template
|
||||
class Output_data_got<32, false>;
|
||||
|
||||
|
|
367
gold/output.h
367
gold/output.h
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "elfcpp.h"
|
||||
#include "layout.h"
|
||||
#include "reloc-types.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
@ -16,9 +17,11 @@ namespace gold
|
|||
class General_options;
|
||||
class Object;
|
||||
class Output_file;
|
||||
|
||||
class Output_section;
|
||||
template<int size, bool big_endian>
|
||||
class Sized_target;
|
||||
template<int size, bool big_endian>
|
||||
class Sized_relobj;
|
||||
|
||||
// An abtract class for data which has to go into the output file.
|
||||
|
||||
|
@ -361,6 +364,262 @@ class Output_data_common : public Output_section_data
|
|||
{ }
|
||||
};
|
||||
|
||||
// This POD class is used to represent a single reloc in the output
|
||||
// file. This could be a private class within Output_data_reloc, but
|
||||
// the templatization is complex enough that I broke it out into a
|
||||
// separate class. The class is templatized on either elfcpp::SHT_REL
|
||||
// or elfcpp::SHT_RELA, and also on whether this is a dynamic
|
||||
// relocation or an ordinary relocation.
|
||||
|
||||
// A relocation can be against a global symbol, a local symbol, an
|
||||
// output section, or the undefined symbol at index 0. We represent
|
||||
// the latter by using a NULL global symbol.
|
||||
|
||||
template<int sh_type, bool dynamic, int size, bool big_endian>
|
||||
class Output_reloc;
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
{
|
||||
public:
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||
|
||||
// An uninitialized entry. We need this because we want to put
|
||||
// instances of this class into an STL container.
|
||||
Output_reloc()
|
||||
: local_sym_index_(INVALID_CODE)
|
||||
{ }
|
||||
|
||||
// A reloc against a global symbol.
|
||||
Output_reloc(Symbol* gsym, unsigned int type, Address address)
|
||||
: local_sym_index_(GSYM_CODE), type_(type), address_(address)
|
||||
{ this->u_.gsym = gsym; }
|
||||
|
||||
// A reloc against a local symbol.
|
||||
Output_reloc(Sized_relobj<size, big_endian>* object,
|
||||
unsigned int local_sym_index,
|
||||
unsigned int type, Address address)
|
||||
: local_sym_index_(local_sym_index), type_(type), address_(address)
|
||||
{
|
||||
assert(local_sym_index != GSYM_CODE && local_sym_index != INVALID_CODE);
|
||||
this->u_.object = object;
|
||||
}
|
||||
|
||||
// A reloc against the STT_SECTION symbol of an output section.
|
||||
Output_reloc(Output_section* os, unsigned int type, Address address)
|
||||
: local_sym_index_(SECTION_CODE), type_(type), address_(address)
|
||||
{ this->u_.os = os; }
|
||||
|
||||
// Write the reloc entry to an output view.
|
||||
void
|
||||
write(unsigned char* pov) const;
|
||||
|
||||
// Write the offset and info fields to Write_rel.
|
||||
template<typename Write_rel>
|
||||
void write_rel(Write_rel*) const;
|
||||
|
||||
private:
|
||||
// Return the symbol index. We can't do a double template
|
||||
// specialization, so we do a secondary template here.
|
||||
unsigned int
|
||||
get_symbol_index() const;
|
||||
|
||||
// Codes for local_sym_index_.
|
||||
enum
|
||||
{
|
||||
// Global symbol.
|
||||
GSYM_CODE = -1U,
|
||||
// Output section.
|
||||
SECTION_CODE = -2U,
|
||||
// Invalid uninitialized entry.
|
||||
INVALID_CODE = -3U
|
||||
};
|
||||
|
||||
union
|
||||
{
|
||||
// For a local symbol, the object. We will never generate a
|
||||
// relocation against a local symbol in a dynamic object; that
|
||||
// doesn't make sense. And our callers will always be
|
||||
// templatized, so we use Sized_relobj here.
|
||||
Sized_relobj<size, big_endian>* object;
|
||||
// For a global symbol, the symbol. If this is NULL, it indicates
|
||||
// a relocation against the undefined 0 symbol.
|
||||
Symbol* gsym;
|
||||
// For a relocation against an output section, the output section.
|
||||
Output_section* os;
|
||||
} u_;
|
||||
// For a local symbol, the local symbol index. This is GSYM_CODE
|
||||
// for a global symbol, or INVALID_CODE for an uninitialized value.
|
||||
unsigned int local_sym_index_;
|
||||
unsigned int type_;
|
||||
Address address_;
|
||||
};
|
||||
|
||||
// The SHT_RELA version of Output_reloc<>. This is just derived from
|
||||
// the SHT_REL version of Output_reloc, but it adds an addend.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
{
|
||||
public:
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Address;
|
||||
typedef typename elfcpp::Elf_types<size>::Elf_Addr Addend;
|
||||
|
||||
// An uninitialized entry.
|
||||
Output_reloc()
|
||||
: rel_()
|
||||
{ }
|
||||
|
||||
// A reloc against a global symbol.
|
||||
Output_reloc(Symbol* gsym, unsigned int type, Address address, Addend addend)
|
||||
: rel_(gsym, type, address), addend_(addend)
|
||||
{ }
|
||||
|
||||
// A reloc against a local symbol.
|
||||
Output_reloc(Sized_relobj<size, big_endian>* object,
|
||||
unsigned int local_sym_index,
|
||||
unsigned int type, Address address, Addend addend)
|
||||
: rel_(object, local_sym_index, type, address), addend_(addend)
|
||||
{ }
|
||||
|
||||
// A reloc against the STT_SECTION symbol of an output section.
|
||||
Output_reloc(Output_section* os, unsigned int type, Address address,
|
||||
Addend addend)
|
||||
: rel_(os, type, address), addend_(addend)
|
||||
{ }
|
||||
|
||||
// Write the reloc entry to an output view.
|
||||
void
|
||||
write(unsigned char* pov) const;
|
||||
|
||||
private:
|
||||
// The basic reloc.
|
||||
Output_reloc<elfcpp::SHT_REL, dynamic, size, big_endian> rel_;
|
||||
// The addend.
|
||||
Addend addend_;
|
||||
};
|
||||
|
||||
// Output_data_reloc is used to manage a section containing relocs.
|
||||
// SH_TYPE is either elfcpp::SHT_REL or elfcpp::SHT_RELA. DYNAMIC
|
||||
// indicates whether this is a dynamic relocation or a normal
|
||||
// relocation. Output_data_reloc_base is a base class.
|
||||
// Output_data_reloc is the real class, which we specialize based on
|
||||
// the reloc type.
|
||||
|
||||
template<int sh_type, bool dynamic, int size, bool big_endian>
|
||||
class Output_data_reloc_base : public Output_section_data
|
||||
{
|
||||
public:
|
||||
typedef Output_reloc<sh_type, dynamic, size, big_endian> Output_reloc_type;
|
||||
typedef typename Output_reloc_type::Address Address;
|
||||
static const int reloc_size =
|
||||
Reloc_types<sh_type, size, big_endian>::reloc_size;
|
||||
|
||||
// Construct the section.
|
||||
Output_data_reloc_base()
|
||||
: Output_section_data(Output_data::default_alignment(size))
|
||||
{ }
|
||||
|
||||
// Write out the data.
|
||||
void
|
||||
do_write(Output_file*);
|
||||
|
||||
protected:
|
||||
// Add a relocation entry.
|
||||
void
|
||||
add(const Output_reloc_type& reloc)
|
||||
{
|
||||
this->relocs_.push_back(reloc);
|
||||
this->set_data_size(this->relocs_.size() * reloc_size);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef std::vector<Output_reloc_type> Relocs;
|
||||
|
||||
Relocs relocs_;
|
||||
};
|
||||
|
||||
// The class which callers actually create.
|
||||
|
||||
template<int sh_type, bool dynamic, int size, bool big_endian>
|
||||
class Output_data_reloc;
|
||||
|
||||
// The SHT_REL version of Output_data_reloc.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_data_reloc<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
: public Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>
|
||||
{
|
||||
private:
|
||||
typedef Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size,
|
||||
big_endian> Base;
|
||||
|
||||
public:
|
||||
typedef typename Base::Output_reloc_type Output_reloc_type;
|
||||
typedef typename Output_reloc_type::Address Address;
|
||||
|
||||
Output_data_reloc()
|
||||
: Output_data_reloc_base<elfcpp::SHT_REL, dynamic, size, big_endian>()
|
||||
{ }
|
||||
|
||||
// Add a reloc against a global symbol.
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Address address)
|
||||
{ this->add(Output_reloc_type(gsym, type, address)); }
|
||||
|
||||
// Add a reloc against a local symbol.
|
||||
void
|
||||
add_local(Sized_relobj<size, big_endian>* object,
|
||||
unsigned int local_sym_index, unsigned int type, Address address)
|
||||
{ this->add(Output_reloc_type(object, local_sym_index, type, address)); }
|
||||
|
||||
// A reloc against the STT_SECTION symbol of an output section.
|
||||
void
|
||||
add_output_section(Output_section* os, unsigned int type, Address address)
|
||||
{ this->add(Output_reloc_type(os, type, address)); }
|
||||
};
|
||||
|
||||
// The SHT_RELA version of Output_data_reloc.
|
||||
|
||||
template<bool dynamic, int size, bool big_endian>
|
||||
class Output_data_reloc<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
: public Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>
|
||||
{
|
||||
private:
|
||||
typedef Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size,
|
||||
big_endian> Base;
|
||||
|
||||
public:
|
||||
typedef typename Base::Output_reloc_type Output_reloc_type;
|
||||
typedef typename Output_reloc_type::Address Address;
|
||||
typedef typename Output_reloc_type::Addend Addend;
|
||||
|
||||
Output_data_reloc()
|
||||
: Output_data_reloc_base<elfcpp::SHT_RELA, dynamic, size, big_endian>()
|
||||
{ }
|
||||
|
||||
// Add a reloc against a global symbol.
|
||||
void
|
||||
add_global(Symbol* gsym, unsigned int type, Address address, Addend addend)
|
||||
{ this->add(Output_reloc_type(gsym, type, address, addend)); }
|
||||
|
||||
// Add a reloc against a local symbol.
|
||||
void
|
||||
add_local(Sized_relobj<size, big_endian>* object,
|
||||
unsigned int local_sym_index, unsigned int type,
|
||||
Address address, Addend addend)
|
||||
{
|
||||
this->add(Output_reloc_type(object, local_sym_index, type, address,
|
||||
addend));
|
||||
}
|
||||
|
||||
// A reloc against the STT_SECTION symbol of an output section.
|
||||
void
|
||||
add_output_section(Output_section* os, unsigned int type, Address address,
|
||||
Addend addend)
|
||||
{ this->add(Output_reloc_type(os, type, address, addend)); }
|
||||
};
|
||||
|
||||
// Output_data_got is used to manage a GOT. Each entry in the GOT is
|
||||
// for one symbol--either a global symbol or a local symbol in an
|
||||
// object. The target specific code adds entries to the GOT as
|
||||
|
@ -456,8 +715,8 @@ class Output_data_got : public Output_section_data
|
|||
// For a constant, the constant.
|
||||
Valtype constant;
|
||||
} u_;
|
||||
// For a local symbol, the local symbol index. This is -1U for a
|
||||
// global symbol, or -2U for a constant.
|
||||
// For a local symbol, the local symbol index. This is GSYM_CODE
|
||||
// for a global symbol, or CONSTANT_CODE for a constant.
|
||||
unsigned int local_sym_index_;
|
||||
};
|
||||
|
||||
|
@ -501,7 +760,7 @@ class Output_section : public Output_data
|
|||
const elfcpp::Shdr<size, big_endian>& shdr);
|
||||
|
||||
// Add generated data ODATA to this output section.
|
||||
virtual void
|
||||
void
|
||||
add_output_section_data(Output_section_data* posd);
|
||||
|
||||
// Return the section name.
|
||||
|
@ -549,6 +808,58 @@ class Output_section : public Output_data
|
|||
set_addralign(uint64_t v)
|
||||
{ this->addralign_ = v; }
|
||||
|
||||
// Indicate that we need a symtab index.
|
||||
void
|
||||
set_needs_symtab_index()
|
||||
{ this->needs_symtab_index_ = true; }
|
||||
|
||||
// Return whether we need a symtab index.
|
||||
bool
|
||||
needs_symtab_index() const
|
||||
{ return this->needs_symtab_index_; }
|
||||
|
||||
// Get the symtab index.
|
||||
unsigned int
|
||||
symtab_index() const
|
||||
{
|
||||
assert(this->symtab_index_ != 0);
|
||||
return this->symtab_index_;
|
||||
}
|
||||
|
||||
// Set the symtab index.
|
||||
void
|
||||
set_symtab_index(unsigned int index)
|
||||
{
|
||||
assert(index != 0);
|
||||
this->symtab_index_ = index;
|
||||
}
|
||||
|
||||
// Indicate that we need a dynsym index.
|
||||
void
|
||||
set_needs_dynsym_index()
|
||||
{ this->needs_dynsym_index_ = true; }
|
||||
|
||||
// Return whether we need a dynsym index.
|
||||
bool
|
||||
needs_dynsym_index() const
|
||||
{ return this->needs_dynsym_index_; }
|
||||
|
||||
// Get the dynsym index.
|
||||
unsigned int
|
||||
dynsym_index() const
|
||||
{
|
||||
assert(this->dynsym_index_ != 0);
|
||||
return this->dynsym_index_;
|
||||
}
|
||||
|
||||
// Set the dynsym index.
|
||||
void
|
||||
set_dynsym_index(unsigned int index)
|
||||
{
|
||||
assert(index != 0);
|
||||
this->dynsym_index_ = index;
|
||||
}
|
||||
|
||||
// Set the address of the Output_section. For a typical
|
||||
// Output_section, there is nothing to do, but if there are any
|
||||
// Output_section_data objects we need to set the final addresses
|
||||
|
@ -686,13 +997,31 @@ class Output_section : public Output_data
|
|||
elfcpp::Elf_Xword flags_;
|
||||
// The section index.
|
||||
unsigned int out_shndx_;
|
||||
// If there is a STT_SECTION for this output section in the normal
|
||||
// symbol table, this is the symbol index. This starts out as zero.
|
||||
// It is initialized in Layout::finalize() to be the index, or -1U
|
||||
// if there isn't one.
|
||||
unsigned int symtab_index_;
|
||||
// If there is a STT_SECTION for this output section in the dynamic
|
||||
// symbol table, this is the symbol index. This starts out as zero.
|
||||
// It is initialized in Layout::finalize() to be the index, or -1U
|
||||
// if there isn't one.
|
||||
unsigned int dynsym_index_;
|
||||
// The input sections. This will be empty in cases where we don't
|
||||
// need to keep track of them.
|
||||
Input_section_list input_sections_;
|
||||
// The offset of the first entry in input_sections_.
|
||||
off_t first_input_offset_;
|
||||
// Whether we permit adding data.
|
||||
bool may_add_data_;
|
||||
bool may_add_data_ : 1;
|
||||
// Whether this output section needs a STT_SECTION symbol in the
|
||||
// normal symbol table. This will be true if there is a relocation
|
||||
// which needs it.
|
||||
bool needs_symtab_index_ : 1;
|
||||
// Whether this output section needs a STT_SECTION symbol in the
|
||||
// dynamic symbol table. This will be true if there is a dynamic
|
||||
// relocation which needs it.
|
||||
bool needs_dynsym_index_ : 1;
|
||||
};
|
||||
|
||||
// A special Output_section which represents the symbol table
|
||||
|
@ -702,18 +1031,33 @@ class Output_section : public Output_data
|
|||
class Output_section_symtab : public Output_section
|
||||
{
|
||||
public:
|
||||
Output_section_symtab(const char* name, off_t size);
|
||||
Output_section_symtab(const char* name, off_t data_size)
|
||||
: Output_section(name, elfcpp::SHT_SYMTAB, 0, false)
|
||||
{ this->set_data_size(data_size); }
|
||||
|
||||
// The data is written out by Symbol_table::write_globals. We don't
|
||||
// do anything here.
|
||||
void
|
||||
do_write(Output_file*)
|
||||
{ }
|
||||
};
|
||||
|
||||
// We don't expect to see any input sections or data here.
|
||||
// A special Output_section which represents the dynamic symbol table
|
||||
// (SHT_DYNSYM). The actual data is written out by
|
||||
// Symbol_table::write_globals.
|
||||
|
||||
class Output_section_dynsym : public Output_section
|
||||
{
|
||||
public:
|
||||
Output_section_dynsym(const char* name, off_t data_size)
|
||||
: Output_section(name, elfcpp::SHT_DYNSYM, 0, false)
|
||||
{ this->set_data_size(data_size); }
|
||||
|
||||
// The data is written out by Symbol_table::write_globals. We don't
|
||||
// do anything here.
|
||||
void
|
||||
add_output_section_data(Output_section_data*)
|
||||
{ abort(); }
|
||||
do_write(Output_file*)
|
||||
{ }
|
||||
};
|
||||
|
||||
// A special Output_section which holds a string table.
|
||||
|
@ -727,11 +1071,6 @@ class Output_section_strtab : public Output_section
|
|||
void
|
||||
do_write(Output_file*);
|
||||
|
||||
// We don't expect to see any input sections or data here.
|
||||
void
|
||||
add_output_section_data(Output_section_data*)
|
||||
{ abort(); }
|
||||
|
||||
private:
|
||||
Stringpool* contents_;
|
||||
};
|
||||
|
|
|
@ -27,8 +27,10 @@ readsyms.cc
|
|||
readsyms.h
|
||||
reloc.cc
|
||||
reloc.h
|
||||
reloc-types.h
|
||||
resolve.cc
|
||||
script.cc
|
||||
script-c.h
|
||||
script.h
|
||||
stringpool.cc
|
||||
stringpool.h
|
||||
|
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2006-11-14 11:17-0800\n"
|
||||
"POT-Creation-Date: 2006-11-15 16:35-0800\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
|
@ -101,7 +101,7 @@ msgstr ""
|
|||
msgid "%s: %s: dynamic symbol table name section has wrong type: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: dynobj.cc:356 object.cc:421
|
||||
#: dynobj.cc:356 object.cc:422
|
||||
#, c-format
|
||||
msgid "%s: %s: bad section name offset for section %u: %lu\n"
|
||||
msgstr ""
|
||||
|
@ -300,87 +300,87 @@ msgstr ""
|
|||
msgid "%s: %s: section name section has wrong type: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:229
|
||||
#: object.cc:230
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid symbol table name index: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:237
|
||||
#: object.cc:238
|
||||
#, c-format
|
||||
msgid "%s: %s: symbol table name section has wrong type: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:293
|
||||
#: object.cc:294
|
||||
#, c-format
|
||||
msgid "%s: %s: section group %u info %u out of range\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:310
|
||||
#: object.cc:311
|
||||
#, c-format
|
||||
msgid "%s: %s: symbol %u name offset %u out of range\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:344
|
||||
#: object.cc:345
|
||||
#, c-format
|
||||
msgid "%s: %s: section %u in section group %u out of range"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:488
|
||||
#: object.cc:489
|
||||
#, c-format
|
||||
msgid "%s: %s: size of symbols is not multiple of symbol size\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:572
|
||||
#: object.cc:576
|
||||
#, c-format
|
||||
msgid "%s: %s: unknown section index %u for local symbol %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:583
|
||||
#: object.cc:587
|
||||
#, c-format
|
||||
msgid "%s: %s: local symbol %u section index %u out of range\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:605
|
||||
#: object.cc:616
|
||||
#, c-format
|
||||
msgid "%s: %s: local symbol %u section name out of range: %u >= %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:782
|
||||
#: object.cc:800
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported ELF file type %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:801 object.cc:854 object.cc:875
|
||||
#: object.cc:819 object.cc:872 object.cc:893
|
||||
#, c-format
|
||||
msgid "%s: %s: ELF file too short\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:810
|
||||
#: object.cc:828
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid ELF version 0\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:813
|
||||
#: object.cc:831
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported ELF version %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:821
|
||||
#: object.cc:839
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid ELF class 0\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:828
|
||||
#: object.cc:846
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported ELF class %d\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:836
|
||||
#: object.cc:854
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid ELF data encoding\n"
|
||||
msgstr ""
|
||||
|
||||
#: object.cc:843
|
||||
#: object.cc:861
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported ELF data encoding %d\n"
|
||||
msgstr ""
|
||||
|
@ -496,37 +496,37 @@ msgstr ""
|
|||
msgid "%s: -%c: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:538
|
||||
#: output.cc:656
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid alignment %lu for section \"%s\"\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1056
|
||||
#: output.cc:1171
|
||||
#, c-format
|
||||
msgid "%s: %s: open: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1065
|
||||
#: output.cc:1180
|
||||
#, c-format
|
||||
msgid "%s: %s: lseek: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1072
|
||||
#: output.cc:1187
|
||||
#, c-format
|
||||
msgid "%s: %s: write: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1082
|
||||
#: output.cc:1197
|
||||
#, c-format
|
||||
msgid "%s: %s: mmap: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1096
|
||||
#: output.cc:1211
|
||||
#, c-format
|
||||
msgid "%s: %s: munmap: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: output.cc:1104
|
||||
#: output.cc:1219
|
||||
#, c-format
|
||||
msgid "%s: %s: close: %s\n"
|
||||
msgstr ""
|
||||
|
@ -567,62 +567,62 @@ msgstr ""
|
|||
msgid "%s: %s: reloc section %u size %lu uneven"
|
||||
msgstr ""
|
||||
|
||||
#: resolve.cc:141
|
||||
#: resolve.cc:142
|
||||
#, c-format
|
||||
msgid "%s: %s: invalid STB_LOCAL symbol %s in external symbols\n"
|
||||
msgstr ""
|
||||
|
||||
#: resolve.cc:147
|
||||
#: resolve.cc:148
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported symbol binding %d for symbol %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:443 symtab.cc:540
|
||||
#: symtab.cc:446 symtab.cc:543
|
||||
#, c-format
|
||||
msgid "%s: %s: mixing 32-bit and 64-bit ELF objects\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:460
|
||||
#: symtab.cc:463
|
||||
#, c-format
|
||||
msgid "%s: %s: bad global symbol name offset %u at %lu\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:547
|
||||
#: symtab.cc:550
|
||||
#, c-format
|
||||
msgid "%s: %s: too few symbol versions\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:567
|
||||
#: symtab.cc:570
|
||||
#, c-format
|
||||
msgid "%s: %s: bad symbol name offset %u at %lu\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:611
|
||||
#: symtab.cc:614
|
||||
#, c-format
|
||||
msgid "%s: %s: versym for symbol %zu out of range: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:619
|
||||
#: symtab.cc:622
|
||||
#, c-format
|
||||
msgid "%s: %s: versym for symbol %zu has no name: %u\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:1010 symtab.cc:1149
|
||||
#: symtab.cc:1019 symtab.cc:1158
|
||||
#, c-format
|
||||
msgid "%s: %s: unsupported symbol section 0x%x\n"
|
||||
msgstr ""
|
||||
|
||||
#: symtab.cc:1262
|
||||
#: symtab.cc:1274
|
||||
#, c-format
|
||||
msgid "%s: %s: warning: %s\n"
|
||||
msgstr ""
|
||||
|
||||
#: target-reloc.h:181
|
||||
#: target-reloc.h:163
|
||||
#, c-format
|
||||
msgid "%s: %s: reloc has bad offset %zu\n"
|
||||
msgstr ""
|
||||
|
||||
#: target-reloc.h:191
|
||||
#: target-reloc.h:173
|
||||
#, c-format
|
||||
msgid "%s: %s: undefined reference to '%s'\n"
|
||||
msgstr ""
|
||||
|
|
36
gold/reloc-types.h
Normal file
36
gold/reloc-types.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
// reloc-types.h -- ELF relocation templates for gold -*- C++ -*-
|
||||
|
||||
// This header files defines a few convenient templated types for use
|
||||
// when handling ELF relocations.
|
||||
|
||||
#ifndef GOLD_RELOC_TYPES_H
|
||||
#define GOLD_RELOC_TYPES_H
|
||||
|
||||
#include "elfcpp.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
||||
// Pick the ELF relocation accessor class and the size based on
|
||||
// SH_TYPE, which is either elfcpp::SHT_REL or elfcpp::SHT_RELA.
|
||||
|
||||
template<int sh_type, int size, bool big_endian>
|
||||
struct Reloc_types;
|
||||
|
||||
template<int size, bool big_endian>
|
||||
struct Reloc_types<elfcpp::SHT_REL, size, big_endian>
|
||||
{
|
||||
typedef typename elfcpp::Rel<size, big_endian> Reloc;
|
||||
static const int reloc_size = elfcpp::Elf_sizes<size>::rel_size;
|
||||
};
|
||||
|
||||
template<int size, bool big_endian>
|
||||
struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
|
||||
{
|
||||
typedef typename elfcpp::Rela<size, big_endian> Reloc;
|
||||
static const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
|
||||
};
|
||||
|
||||
}; // End namespace gold.
|
||||
|
||||
#endif // !defined(GOLD_RELOC_TYPE_SH)
|
|
@ -391,7 +391,7 @@ Sized_relobj<size, big_endian>::relocate_sections(
|
|||
relinfo.layout = layout;
|
||||
relinfo.object = this;
|
||||
relinfo.local_symbol_count = this->local_symbol_count_;
|
||||
relinfo.values = this->values_;
|
||||
relinfo.local_values = &this->local_values_;
|
||||
relinfo.symbols = this->symbols_;
|
||||
|
||||
const unsigned char* p = pshdrs + This::shdr_size;
|
||||
|
|
|
@ -106,7 +106,8 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
|||
abort();
|
||||
}
|
||||
|
||||
if (to->object() != NULL && to->object()->is_dynamic())
|
||||
if (to->source() == Symbol::FROM_OBJECT
|
||||
&& to->object()->is_dynamic())
|
||||
tobits |= (1 << 1);
|
||||
|
||||
switch (to->shnum())
|
||||
|
@ -174,6 +175,15 @@ Symbol_table::resolve(Sized_symbol<size>* to,
|
|||
break;
|
||||
}
|
||||
|
||||
if ((tobits & (1 << 1)) != (frombits & (1 << 1)))
|
||||
{
|
||||
// This symbol is seen in both a dynamic object and a regular
|
||||
// object. That means that we need the symbol to go into the
|
||||
// dynamic symbol table, so that the dynamic linker can use the
|
||||
// regular symbol to override or define the dynamic symbol.
|
||||
to->set_needs_dynsym_entry();
|
||||
}
|
||||
|
||||
// FIXME: Warn if either but not both of TO and SYM are STT_TLS.
|
||||
|
||||
// We use a giant switch table for symbol resolution. This code is
|
||||
|
|
|
@ -29,6 +29,8 @@ Symbol::init_fields(const char* name, const char* version,
|
|||
{
|
||||
this->name_ = name;
|
||||
this->version_ = version;
|
||||
this->symtab_index_ = 0;
|
||||
this->dynsym_index_ = 0;
|
||||
this->got_offset_ = 0;
|
||||
this->type_ = type;
|
||||
this->binding_ = binding;
|
||||
|
@ -37,6 +39,7 @@ Symbol::init_fields(const char* name, const char* version,
|
|||
this->is_target_special_ = false;
|
||||
this->is_def_ = false;
|
||||
this->is_forwarder_ = false;
|
||||
this->needs_dynsym_entry_ = false;
|
||||
this->in_dyn_ = false;
|
||||
this->has_got_offset_ = false;
|
||||
this->has_warning_ = false;
|
||||
|
@ -204,10 +207,10 @@ Symbol_table::make_forwarder(Symbol* from, Symbol* to)
|
|||
// Resolve the forwards from FROM, returning the real symbol.
|
||||
|
||||
Symbol*
|
||||
Symbol_table::resolve_forwards(Symbol* from) const
|
||||
Symbol_table::resolve_forwards(const Symbol* from) const
|
||||
{
|
||||
assert(from->is_forwarder());
|
||||
Unordered_map<Symbol*, Symbol*>::const_iterator p =
|
||||
Unordered_map<const Symbol*, Symbol*>::const_iterator p =
|
||||
this->forwarders_.find(from);
|
||||
assert(p != this->forwarders_.end());
|
||||
return p->second;
|
||||
|
@ -952,18 +955,22 @@ Symbol_table::define_symbols(const Layout* layout, Target* target, int count,
|
|||
}
|
||||
}
|
||||
|
||||
// Set the final values for all the symbols. Record the file offset
|
||||
// Set the final values for all the symbols. The index of the first
|
||||
// global symbol in the output file is INDEX. Record the file offset
|
||||
// OFF. Add their names to POOL. Return the new file offset.
|
||||
|
||||
off_t
|
||||
Symbol_table::finalize(off_t off, Stringpool* pool)
|
||||
Symbol_table::finalize(unsigned int index, off_t off, Stringpool* pool)
|
||||
{
|
||||
off_t ret;
|
||||
|
||||
assert(index != 0);
|
||||
this->first_global_index_ = index;
|
||||
|
||||
if (this->size_ == 32)
|
||||
ret = this->sized_finalize<32>(off, pool);
|
||||
ret = this->sized_finalize<32>(index, off, pool);
|
||||
else if (this->size_ == 64)
|
||||
ret = this->sized_finalize<64>(off, pool);
|
||||
ret = this->sized_finalize<64>(index, off, pool);
|
||||
else
|
||||
abort();
|
||||
|
||||
|
@ -980,15 +987,17 @@ Symbol_table::finalize(off_t off, Stringpool* pool)
|
|||
|
||||
template<int size>
|
||||
off_t
|
||||
Symbol_table::sized_finalize(off_t off, Stringpool* pool)
|
||||
Symbol_table::sized_finalize(unsigned index, off_t off, Stringpool* pool)
|
||||
{
|
||||
off = align_address(off, size >> 3);
|
||||
this->offset_ = off;
|
||||
|
||||
size_t orig_index = index;
|
||||
|
||||
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||
Symbol_table_type::iterator p = this->table_.begin();
|
||||
size_t count = 0;
|
||||
while (p != this->table_.end())
|
||||
for (Symbol_table_type::iterator p = this->table_.begin();
|
||||
p != this->table_.end();
|
||||
++p)
|
||||
{
|
||||
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(p->second);
|
||||
|
||||
|
@ -1030,12 +1039,7 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool)
|
|||
|
||||
if (os == NULL)
|
||||
{
|
||||
// We should be able to erase this symbol from the
|
||||
// symbol table, but at least with gcc 4.0.2
|
||||
// std::unordered_map::erase doesn't appear to return
|
||||
// the new iterator.
|
||||
// p = this->table_.erase(p);
|
||||
++p;
|
||||
sym->set_symtab_index(-1U);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1082,13 +1086,13 @@ Symbol_table::sized_finalize(off_t off, Stringpool* pool)
|
|||
}
|
||||
|
||||
sym->set_value(value);
|
||||
sym->set_symtab_index(index);
|
||||
pool->add(sym->name(), NULL);
|
||||
++count;
|
||||
++index;
|
||||
off += sym_size;
|
||||
++p;
|
||||
}
|
||||
|
||||
this->output_count_ = count;
|
||||
this->output_count_ = index - orig_index;
|
||||
|
||||
return off;
|
||||
}
|
||||
|
@ -1126,8 +1130,10 @@ Symbol_table::sized_write_globals(const Target*,
|
|||
Output_file* of) const
|
||||
{
|
||||
const int sym_size = elfcpp::Elf_sizes<size>::sym_size;
|
||||
unsigned char* psyms = of->get_output_view(this->offset_,
|
||||
this->output_count_ * sym_size);
|
||||
unsigned int index = this->first_global_index_;
|
||||
const off_t oview_size = this->output_count_ * sym_size;
|
||||
unsigned char* psyms = of->get_output_view(this->offset_, oview_size);
|
||||
|
||||
unsigned char* ps = psyms;
|
||||
for (Symbol_table_type::const_iterator p = this->table_.begin();
|
||||
p != this->table_.end();
|
||||
|
@ -1135,6 +1141,9 @@ Symbol_table::sized_write_globals(const Target*,
|
|||
{
|
||||
Sized_symbol<size>* sym = static_cast<Sized_symbol<size>*>(p->second);
|
||||
|
||||
if (sym->symtab_index() == -1U)
|
||||
continue;
|
||||
|
||||
unsigned int shndx;
|
||||
switch (sym->source())
|
||||
{
|
||||
|
@ -1164,9 +1173,7 @@ Symbol_table::sized_write_globals(const Target*,
|
|||
Relobj* relobj = static_cast<Relobj*>(symobj);
|
||||
off_t secoff;
|
||||
Output_section* os = relobj->output_section(shnum, &secoff);
|
||||
if (os == NULL)
|
||||
continue;
|
||||
|
||||
assert(os != NULL);
|
||||
shndx = os->out_shndx();
|
||||
}
|
||||
}
|
||||
|
@ -1188,6 +1195,9 @@ Symbol_table::sized_write_globals(const Target*,
|
|||
abort();
|
||||
}
|
||||
|
||||
assert(sym->symtab_index() == index);
|
||||
++index;
|
||||
|
||||
elfcpp::Sym_write<size, big_endian> osym(ps);
|
||||
osym.put_st_name(sympool->get_offset(sym->name()));
|
||||
osym.put_st_value(sym->value());
|
||||
|
@ -1200,7 +1210,9 @@ Symbol_table::sized_write_globals(const Target*,
|
|||
ps += sym_size;
|
||||
}
|
||||
|
||||
of->write_output_view(this->offset_, this->output_count_ * sym_size, psyms);
|
||||
assert(ps - psyms == oview_size);
|
||||
|
||||
of->write_output_view(this->offset_, oview_size, psyms);
|
||||
}
|
||||
|
||||
// Warnings functions.
|
||||
|
@ -1254,7 +1266,7 @@ Warnings::note_warnings(Symbol_table* symtab)
|
|||
// symbol for which has a warning.
|
||||
|
||||
void
|
||||
Warnings::issue_warning(Symbol* sym, const std::string& location) const
|
||||
Warnings::issue_warning(const Symbol* sym, const std::string& location) const
|
||||
{
|
||||
assert(sym->has_warning());
|
||||
Warning_table::const_iterator p = this->warnings_.find(sym->name());
|
||||
|
|
|
@ -173,6 +173,17 @@ class Symbol
|
|||
set_forwarder()
|
||||
{ this->is_forwarder_ = true; }
|
||||
|
||||
// Return whether this symbol needs an entry in the dynamic symbol
|
||||
// table.
|
||||
bool
|
||||
needs_dynsym_entry() const
|
||||
{ return this->needs_dynsym_entry_; }
|
||||
|
||||
// Mark this symbol as needing an entry in the dynamic symbol table.
|
||||
void
|
||||
set_needs_dynsym_entry()
|
||||
{ this->needs_dynsym_entry_ = true; }
|
||||
|
||||
// Return whether this symbol was ever seen in a dynamic object.
|
||||
bool
|
||||
in_dyn() const
|
||||
|
@ -183,6 +194,46 @@ class Symbol
|
|||
set_in_dyn()
|
||||
{ this->in_dyn_ = true; }
|
||||
|
||||
// Return the index of this symbol in the output file symbol table.
|
||||
// A value of -1U means that this symbol is not going into the
|
||||
// output file. This starts out as zero, and is set to a non-zero
|
||||
// value by Symbol_table::finalize. It is an error to ask for the
|
||||
// symbol table index before it has been set.
|
||||
unsigned int
|
||||
symtab_index() const
|
||||
{
|
||||
assert(this->symtab_index_ != 0);
|
||||
return this->symtab_index_;
|
||||
}
|
||||
|
||||
// Set the index of the symbol in the output file symbol table.
|
||||
void
|
||||
set_symtab_index(unsigned int index)
|
||||
{
|
||||
assert(index != 0);
|
||||
this->symtab_index_ = index;
|
||||
}
|
||||
|
||||
// Return the index of this symbol in the dynamic symbol table. A
|
||||
// value of -1U means that this symbol is not going into the dynamic
|
||||
// symbol table. This starts out as zero, and is set to a non-zero
|
||||
// during Layout::finalize. It is an error to ask for the dynamic
|
||||
// symbol table index before it has been set.
|
||||
unsigned int
|
||||
dynsym_index() const
|
||||
{
|
||||
assert(this->dynsym_index_ != 0);
|
||||
return this->dynsym_index_;
|
||||
}
|
||||
|
||||
// Set the index of the symbol in the dynamic symbol table.
|
||||
void
|
||||
set_dynsym_index(unsigned int index)
|
||||
{
|
||||
assert(index != 0);
|
||||
this->dynsym_index_ = index;
|
||||
}
|
||||
|
||||
// Return whether this symbol has an entry in the GOT section.
|
||||
bool
|
||||
has_got_offset() const
|
||||
|
@ -334,9 +385,22 @@ class Symbol
|
|||
} in_output_segment;
|
||||
} u_;
|
||||
|
||||
// The index of this symbol in the output file. If the symbol is
|
||||
// not going into the output file, this value is -1U. This field
|
||||
// starts as always holding zero. It is set to a non-zero value by
|
||||
// Symbol_table::finalize.
|
||||
unsigned int symtab_index_;
|
||||
|
||||
// The index of this symbol in the dynamic symbol table. If the
|
||||
// symbol is not going into the dynamic symbol table, this value is
|
||||
// -1U. This field starts as always holding zero. It is set to a
|
||||
// non-zero value during Layout::finalize.
|
||||
unsigned int dynsym_index_;
|
||||
|
||||
// If this symbol has an entry in the GOT section (has_got_offset_
|
||||
// is true), this is the offset.
|
||||
// is true), this is the offset from the start of the GOT section.
|
||||
unsigned int got_offset_;
|
||||
|
||||
// Symbol type.
|
||||
elfcpp::STT type_ : 4;
|
||||
// Symbol binding.
|
||||
|
@ -360,6 +424,8 @@ class Symbol
|
|||
// It forwards to the symbol found in the forwarders_ map of
|
||||
// Symbol_table.
|
||||
bool is_forwarder_ : 1;
|
||||
// True if this symbol needs to be in the dynamic symbol table.
|
||||
bool needs_dynsym_entry_ : 1;
|
||||
// True if we've seen this symbol in a dynamic object.
|
||||
bool in_dyn_ : 1;
|
||||
// True if the symbol has an entry in the GOT section.
|
||||
|
@ -548,7 +614,7 @@ class Warnings
|
|||
|
||||
// Issue a warning for a reference to SYM at LOCATION.
|
||||
void
|
||||
issue_warning(Symbol* sym, const std::string& location) const;
|
||||
issue_warning(const Symbol* sym, const std::string& location) const;
|
||||
|
||||
private:
|
||||
Warnings(const Warnings&);
|
||||
|
@ -667,7 +733,7 @@ class Symbol_table
|
|||
|
||||
// Return the real symbol associated with the forwarder symbol FROM.
|
||||
Symbol*
|
||||
resolve_forwards(Symbol* from) const;
|
||||
resolve_forwards(const Symbol* from) const;
|
||||
|
||||
// Return the size of the symbols in the table.
|
||||
int
|
||||
|
@ -705,15 +771,16 @@ class Symbol_table
|
|||
// Possibly issue a warning for a reference to SYM at LOCATION which
|
||||
// is in OBJ.
|
||||
void
|
||||
issue_warning(Symbol* sym, const std::string& location) const
|
||||
issue_warning(const Symbol* sym, const std::string& location) const
|
||||
{ this->warnings_.issue_warning(sym, location); }
|
||||
|
||||
// Finalize the symbol table after we have set the final addresses
|
||||
// of all the input sections. This sets the final symbol values and
|
||||
// adds the names to *POOL. It records the file offset OFF, and
|
||||
// of all the input sections. This sets the final symbol indexes,
|
||||
// values and adds the names to *POOL. INDEX is the index of the
|
||||
// first global symbol. This records the file offset OFF, and
|
||||
// returns the new file offset.
|
||||
off_t
|
||||
finalize(off_t, Stringpool*);
|
||||
finalize(unsigned int index, off_t off, Stringpool* pool);
|
||||
|
||||
// Write out the global symbols.
|
||||
void
|
||||
|
@ -791,7 +858,7 @@ class Symbol_table
|
|||
// Finalize symbols specialized for size.
|
||||
template<int size>
|
||||
off_t
|
||||
sized_finalize(off_t, Stringpool*);
|
||||
sized_finalize(unsigned int, off_t, Stringpool*);
|
||||
|
||||
// Write globals specialized for size and endianness.
|
||||
template<int size, bool big_endian>
|
||||
|
@ -828,6 +895,9 @@ class Symbol_table
|
|||
// use in archive groups.
|
||||
int saw_undefined_;
|
||||
|
||||
// The index of the first global symbol in the output file.
|
||||
unsigned int first_global_index_;
|
||||
|
||||
// The file offset within the output symtab section where we should
|
||||
// write the table.
|
||||
off_t offset_;
|
||||
|
@ -843,7 +913,7 @@ class Symbol_table
|
|||
Stringpool namepool_;
|
||||
|
||||
// Forwarding symbols.
|
||||
Unordered_map<Symbol*, Symbol*> forwarders_;
|
||||
Unordered_map<const Symbol*, Symbol*> forwarders_;
|
||||
|
||||
// We don't expect there to be very many common symbols, so we keep
|
||||
// a list of them. When we find a common symbol we add it to this
|
||||
|
|
|
@ -6,30 +6,11 @@
|
|||
#include "elfcpp.h"
|
||||
#include "object.h"
|
||||
#include "symtab.h"
|
||||
#include "reloc-types.h"
|
||||
|
||||
namespace gold
|
||||
{
|
||||
|
||||
// Pick the ELF relocation accessor class and the size based on
|
||||
// SH_TYPE, which is either SHT_REL or SHT_RELA.
|
||||
|
||||
template<int sh_type, int size, bool big_endian>
|
||||
struct Reloc_types;
|
||||
|
||||
template<int size, bool big_endian>
|
||||
struct Reloc_types<elfcpp::SHT_REL, size, big_endian>
|
||||
{
|
||||
typedef typename elfcpp::Rel<size, big_endian> Reloc;
|
||||
static const int reloc_size = elfcpp::Elf_sizes<size>::rel_size;
|
||||
};
|
||||
|
||||
template<int size, bool big_endian>
|
||||
struct Reloc_types<elfcpp::SHT_RELA, size, big_endian>
|
||||
{
|
||||
typedef typename elfcpp::Rela<size, big_endian> Reloc;
|
||||
static const int reloc_size = elfcpp::Elf_sizes<size>::rela_size;
|
||||
};
|
||||
|
||||
// This function implements the generic part of reloc scanning. This
|
||||
// is an inline function which takes a class whose operator()
|
||||
// implements the machine specific part of scanning. We do it this
|
||||
|
@ -140,8 +121,9 @@ relocate_section(
|
|||
Relocate relocate;
|
||||
|
||||
unsigned int local_count = relinfo->local_symbol_count;
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr *local_values = relinfo->values;
|
||||
Symbol** global_syms = relinfo->symbols;
|
||||
const typename Sized_relobj<size, big_endian>::Local_values* local_values =
|
||||
relinfo->local_values;
|
||||
const Symbol* const * global_syms = relinfo->symbols;
|
||||
|
||||
for (size_t i = 0; i < reloc_count; ++i, prelocs += reloc_size)
|
||||
{
|
||||
|
@ -153,22 +135,22 @@ relocate_section(
|
|||
unsigned int r_sym = elfcpp::elf_r_sym<size>(r_info);
|
||||
unsigned int r_type = elfcpp::elf_r_type<size>(r_info);
|
||||
|
||||
Sized_symbol<size>* sym;
|
||||
const Sized_symbol<size>* sym;
|
||||
typename elfcpp::Elf_types<size>::Elf_Addr value;
|
||||
|
||||
if (r_sym < local_count)
|
||||
{
|
||||
sym = NULL;
|
||||
value = local_values[r_sym];
|
||||
value = (*local_values)[r_sym];
|
||||
}
|
||||
else
|
||||
{
|
||||
Symbol* gsym = global_syms[r_sym - local_count];
|
||||
const Symbol* gsym = global_syms[r_sym - local_count];
|
||||
assert(gsym != NULL);
|
||||
if (gsym->is_forwarder())
|
||||
gsym = relinfo->symtab->resolve_forwards(gsym);
|
||||
|
||||
sym = static_cast<Sized_symbol<size>*>(gsym);
|
||||
sym = static_cast<const Sized_symbol<size>*>(gsym);
|
||||
value = sym->value();
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue