mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-29 16:38:05 +08:00
* object.h (Sized_relobj_file::find_shdr): New function.
(Sized_relobj_file::find_special_sections): New function. * object.cc (Sized_relobj_file::find_shdr): New function. (Sized_relobj_file::find_eh_frame): Use find_shdr. (Sized_relobj_file::find_special_sections): New function, split out.. (Sized_relobj_file::do_read_symbols): ..from here. * output.h (Output_data_got::replace_constant): New function. (Output_data_got::num_entries): New function. (Output_data_got::last_got_offset,set_got_size): Use num_entries. (Output_data_got::got_offset): Protected rather than private. (Output_data_got::replace_got_entry): New function. * output.cc (Output_data_got::replace_got_entry): New function. * powerpc.cc (class Powerpc_relobj): New. (class Powerpc_relocate_functions): Delete all psymval variants or convert to value,addend type. Delete pcrela, pcrela_unaligned. Implement _ha functions using corresponding _hi function. (Powerpc_relobj::find_special_sections): New function. (Target_powerpc::do_make_elf_object): New function. (class Output_data_got_powerpc): New. (class Output_data_glink): New. (class Powerpc_scan_relocatable_reloc): New. Many more changes througout file.
This commit is contained in:
@ -1,3 +1,28 @@
|
|||||||
|
2012-08-11 Alan Modra <amodra@gmail.com>
|
||||||
|
|
||||||
|
* object.h (Sized_relobj_file::find_shdr): New function.
|
||||||
|
(Sized_relobj_file::find_special_sections): New function.
|
||||||
|
* object.cc (Sized_relobj_file::find_shdr): New function.
|
||||||
|
(Sized_relobj_file::find_eh_frame): Use find_shdr.
|
||||||
|
(Sized_relobj_file::find_special_sections): New function, split out..
|
||||||
|
(Sized_relobj_file::do_read_symbols): ..from here.
|
||||||
|
* output.h (Output_data_got::replace_constant): New function.
|
||||||
|
(Output_data_got::num_entries): New function.
|
||||||
|
(Output_data_got::last_got_offset,set_got_size): Use num_entries.
|
||||||
|
(Output_data_got::got_offset): Protected rather than private.
|
||||||
|
(Output_data_got::replace_got_entry): New function.
|
||||||
|
* output.cc (Output_data_got::replace_got_entry): New function.
|
||||||
|
* powerpc.cc (class Powerpc_relobj): New.
|
||||||
|
(class Powerpc_relocate_functions): Delete all psymval variants or
|
||||||
|
convert to value,addend type. Delete pcrela, pcrela_unaligned.
|
||||||
|
Implement _ha functions using corresponding _hi function.
|
||||||
|
(Powerpc_relobj::find_special_sections): New function.
|
||||||
|
(Target_powerpc::do_make_elf_object): New function.
|
||||||
|
(class Output_data_got_powerpc): New.
|
||||||
|
(class Output_data_glink): New.
|
||||||
|
(class Powerpc_scan_relocatable_reloc): New.
|
||||||
|
Many more changes througout file.
|
||||||
|
|
||||||
2012-08-09 Nick Clifton <nickc@redhat.com>
|
2012-08-09 Nick Clifton <nickc@redhat.com>
|
||||||
|
|
||||||
* po/vi.po: Updated Vietnamese translation.
|
* po/vi.po: Updated Vietnamese translation.
|
||||||
|
135
gold/object.cc
135
gold/object.cc
@ -510,6 +510,64 @@ Sized_relobj_file<size, big_endian>::check_eh_frame_flags(
|
|||||||
&& (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
|
&& (shdr->get_sh_flags() & elfcpp::SHF_ALLOC) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Find the section header with the given name.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
const unsigned char*
|
||||||
|
Sized_relobj_file<size, big_endian>::find_shdr(
|
||||||
|
const unsigned char* pshdrs,
|
||||||
|
const char* name,
|
||||||
|
const char* names,
|
||||||
|
section_size_type names_size,
|
||||||
|
const unsigned char* hdr) const
|
||||||
|
{
|
||||||
|
const unsigned int shnum = this->shnum();
|
||||||
|
const unsigned char* hdr_end = pshdrs + This::shdr_size * shnum;
|
||||||
|
size_t sh_name = 0;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if (hdr)
|
||||||
|
{
|
||||||
|
// We found HDR last time we were called, continue looking.
|
||||||
|
typename This::Shdr shdr(hdr);
|
||||||
|
sh_name = shdr.get_sh_name();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Look for the next occurrence of NAME in NAMES.
|
||||||
|
// The fact that .shstrtab produced by current GNU tools is
|
||||||
|
// string merged means we shouldn't have both .not.foo and
|
||||||
|
// .foo in .shstrtab, and multiple .foo sections should all
|
||||||
|
// have the same sh_name. However, this is not guaranteed
|
||||||
|
// by the ELF spec and not all ELF object file producers may
|
||||||
|
// be so clever.
|
||||||
|
size_t len = strlen(name) + 1;
|
||||||
|
const char *p = sh_name ? names + sh_name + len : names;
|
||||||
|
p = reinterpret_cast<const char*>(memmem(p, names_size - (p - names),
|
||||||
|
name, len));
|
||||||
|
if (p == NULL)
|
||||||
|
return NULL;
|
||||||
|
sh_name = p - names;
|
||||||
|
hdr = pshdrs;
|
||||||
|
if (sh_name == 0)
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
|
hdr += This::shdr_size;
|
||||||
|
while (hdr < hdr_end)
|
||||||
|
{
|
||||||
|
typename This::Shdr shdr(hdr);
|
||||||
|
if (shdr.get_sh_name() == sh_name)
|
||||||
|
return hdr;
|
||||||
|
hdr += This::shdr_size;
|
||||||
|
}
|
||||||
|
hdr = NULL;
|
||||||
|
if (sh_name == 0)
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Return whether there is a GNU .eh_frame section, given the section
|
// Return whether there is a GNU .eh_frame section, given the section
|
||||||
// headers and the section names.
|
// headers and the section names.
|
||||||
|
|
||||||
@ -520,26 +578,18 @@ Sized_relobj_file<size, big_endian>::find_eh_frame(
|
|||||||
const char* names,
|
const char* names,
|
||||||
section_size_type names_size) const
|
section_size_type names_size) const
|
||||||
{
|
{
|
||||||
const unsigned int shnum = this->shnum();
|
const unsigned char* s = NULL;
|
||||||
const unsigned char* p = pshdrs + This::shdr_size;
|
|
||||||
for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size)
|
|
||||||
{
|
|
||||||
typename This::Shdr shdr(p);
|
|
||||||
if (this->check_eh_frame_flags(&shdr))
|
|
||||||
{
|
|
||||||
if (shdr.get_sh_name() >= names_size)
|
|
||||||
{
|
|
||||||
this->error(_("bad section name offset for section %u: %lu"),
|
|
||||||
i, static_cast<unsigned long>(shdr.get_sh_name()));
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const char* name = names + shdr.get_sh_name();
|
while (1)
|
||||||
if (strcmp(name, ".eh_frame") == 0)
|
{
|
||||||
return true;
|
s = this->find_shdr(pshdrs, ".eh_frame", names, names_size, s);
|
||||||
}
|
if (s == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
typename This::Shdr shdr(s);
|
||||||
|
if (this->check_eh_frame_flags(&shdr))
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return TRUE if this is a section whose contents will be needed in the
|
// Return TRUE if this is a section whose contents will be needed in the
|
||||||
@ -651,39 +701,46 @@ build_compressed_section_map(
|
|||||||
return uncompressed_map;
|
return uncompressed_map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Stash away info for a number of special sections.
|
||||||
|
// Return true if any of the sections found require local symbols to be read.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
bool
|
||||||
|
Sized_relobj_file<size, big_endian>::do_find_special_sections(
|
||||||
|
Read_symbols_data* sd)
|
||||||
|
{
|
||||||
|
const unsigned char* const pshdrs = sd->section_headers->data();
|
||||||
|
const unsigned char* namesu = sd->section_names->data();
|
||||||
|
const char* names = reinterpret_cast<const char*>(namesu);
|
||||||
|
|
||||||
|
if (this->find_eh_frame(pshdrs, names, sd->section_names_size))
|
||||||
|
this->has_eh_frame_ = true;
|
||||||
|
|
||||||
|
if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
|
||||||
|
this->compressed_sections_
|
||||||
|
= build_compressed_section_map(pshdrs, this->shnum(), names,
|
||||||
|
sd->section_names_size, this);
|
||||||
|
return (this->has_eh_frame_
|
||||||
|
|| (!parameters->options().relocatable()
|
||||||
|
&& parameters->options().gdb_index()
|
||||||
|
&& (memmem(names, sd->section_names_size, "debug_info", 12) == 0
|
||||||
|
|| memmem(names, sd->section_names_size, "debug_types",
|
||||||
|
13) == 0)));
|
||||||
|
}
|
||||||
|
|
||||||
// Read the sections and symbols from an object file.
|
// Read the sections and symbols from an object file.
|
||||||
|
|
||||||
template<int size, bool big_endian>
|
template<int size, bool big_endian>
|
||||||
void
|
void
|
||||||
Sized_relobj_file<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
Sized_relobj_file<size, big_endian>::do_read_symbols(Read_symbols_data* sd)
|
||||||
{
|
{
|
||||||
bool need_local_symbols = false;
|
|
||||||
|
|
||||||
this->read_section_data(&this->elf_file_, sd);
|
this->read_section_data(&this->elf_file_, sd);
|
||||||
|
|
||||||
const unsigned char* const pshdrs = sd->section_headers->data();
|
const unsigned char* const pshdrs = sd->section_headers->data();
|
||||||
|
|
||||||
this->find_symtab(pshdrs);
|
this->find_symtab(pshdrs);
|
||||||
|
|
||||||
const unsigned char* namesu = sd->section_names->data();
|
bool need_local_symbols = this->do_find_special_sections(sd);
|
||||||
const char* names = reinterpret_cast<const char*>(namesu);
|
|
||||||
if (memmem(names, sd->section_names_size, ".eh_frame", 10) != NULL)
|
|
||||||
{
|
|
||||||
if (this->find_eh_frame(pshdrs, names, sd->section_names_size))
|
|
||||||
this->has_eh_frame_ = true;
|
|
||||||
}
|
|
||||||
if (memmem(names, sd->section_names_size, ".zdebug_", 8) != NULL)
|
|
||||||
this->compressed_sections_ =
|
|
||||||
build_compressed_section_map(pshdrs, this->shnum(), names,
|
|
||||||
sd->section_names_size, this);
|
|
||||||
|
|
||||||
if (this->has_eh_frame_
|
|
||||||
|| (!parameters->options().relocatable()
|
|
||||||
&& parameters->options().gdb_index()
|
|
||||||
&& (memmem(names, sd->section_names_size, "debug_info", 12) == 0
|
|
||||||
|| memmem(names, sd->section_names_size, "debug_types",
|
|
||||||
13) == 0)))
|
|
||||||
need_local_symbols = true;
|
|
||||||
|
|
||||||
sd->symbols = NULL;
|
sd->symbols = NULL;
|
||||||
sd->symbols_size = 0;
|
sd->symbols_size = 0;
|
||||||
|
@ -349,7 +349,7 @@ class Object
|
|||||||
this->input_file_->file().remove_object();
|
this->input_file_->file().remove_object();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the name of the object as we would report it to the tuser.
|
// Return the name of the object as we would report it to the user.
|
||||||
const std::string&
|
const std::string&
|
||||||
name() const
|
name() const
|
||||||
{ return this->name_; }
|
{ return this->name_; }
|
||||||
@ -2116,6 +2116,15 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
|||||||
Address
|
Address
|
||||||
map_to_kept_section(unsigned int shndx, bool* found) const;
|
map_to_kept_section(unsigned int shndx, bool* found) const;
|
||||||
|
|
||||||
|
// Find the section header with the given NAME. If HDR is non-NULL
|
||||||
|
// then it is a section header returned from a previous call to this
|
||||||
|
// function and the next section header with the same name will be
|
||||||
|
// returned.
|
||||||
|
const unsigned char*
|
||||||
|
find_shdr(const unsigned char* pshdrs, const char* name,
|
||||||
|
const char* names, section_size_type names_size,
|
||||||
|
const unsigned char* hdr) const;
|
||||||
|
|
||||||
// Compute final local symbol value. R_SYM is the local symbol index.
|
// Compute final local symbol value. R_SYM is the local symbol index.
|
||||||
// LV_IN points to a local symbol value containing the input value.
|
// LV_IN points to a local symbol value containing the input value.
|
||||||
// LV_OUT points to a local symbol value storing the final output value,
|
// LV_OUT points to a local symbol value storing the final output value,
|
||||||
@ -2347,6 +2356,11 @@ class Sized_relobj_file : public Sized_relobj<size, big_endian>
|
|||||||
|
|
||||||
typedef std::vector<View_size> Views;
|
typedef std::vector<View_size> Views;
|
||||||
|
|
||||||
|
// Stash away info for a number of special sections.
|
||||||
|
// Return true if any of the sections found require local symbols to be read.
|
||||||
|
virtual bool
|
||||||
|
do_find_special_sections(Read_symbols_data* sd);
|
||||||
|
|
||||||
// This may be overriden by a child class.
|
// This may be overriden by a child class.
|
||||||
virtual void
|
virtual void
|
||||||
do_relocate_sections(const Symbol_table* symtab, const Layout* layout,
|
do_relocate_sections(const Symbol_table* symtab, const Layout* layout,
|
||||||
|
@ -1701,6 +1701,18 @@ Output_data_got<size, big_endian>::add_got_entry_pair(Got_entry got_entry_1,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace GOT entry I with a new value.
|
||||||
|
|
||||||
|
template<int size, bool big_endian>
|
||||||
|
void
|
||||||
|
Output_data_got<size, big_endian>::replace_got_entry(
|
||||||
|
unsigned int i,
|
||||||
|
Got_entry got_entry)
|
||||||
|
{
|
||||||
|
gold_assert(i < this->entries_.size());
|
||||||
|
this->entries_[i] = got_entry;
|
||||||
|
}
|
||||||
|
|
||||||
// Output_data_dynamic::Dynamic_entry methods.
|
// Output_data_dynamic::Dynamic_entry methods.
|
||||||
|
|
||||||
// Write out the entry.
|
// Write out the entry.
|
||||||
|
@ -2257,6 +2257,13 @@ class Output_data_got : public Output_data_got_base
|
|||||||
return got_offset;
|
return got_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Replace GOT entry I with a new constant.
|
||||||
|
void
|
||||||
|
replace_constant(unsigned int i, Valtype constant)
|
||||||
|
{
|
||||||
|
this->replace_got_entry(i, Got_entry(constant));
|
||||||
|
}
|
||||||
|
|
||||||
// Reserve a slot in the GOT for a local symbol.
|
// Reserve a slot in the GOT for a local symbol.
|
||||||
void
|
void
|
||||||
reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
|
reserve_local(unsigned int i, Relobj* object, unsigned int sym_index,
|
||||||
@ -2281,6 +2288,16 @@ class Output_data_got : public Output_data_got_base
|
|||||||
do_reserve_slot(unsigned int i)
|
do_reserve_slot(unsigned int i)
|
||||||
{ this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
|
{ this->free_list_.remove(i * got_size / 8, (i + 1) * got_size / 8); }
|
||||||
|
|
||||||
|
// Return the number of words in the GOT.
|
||||||
|
unsigned int
|
||||||
|
num_entries () const
|
||||||
|
{ return this->entries_.size(); }
|
||||||
|
|
||||||
|
// Return the offset into the GOT of GOT entry I.
|
||||||
|
unsigned int
|
||||||
|
got_offset(unsigned int i) const
|
||||||
|
{ return i * (got_size / 8); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// This POD class holds a single GOT entry.
|
// This POD class holds a single GOT entry.
|
||||||
class Got_entry
|
class Got_entry
|
||||||
@ -2352,20 +2369,19 @@ class Output_data_got : public Output_data_got_base
|
|||||||
unsigned int
|
unsigned int
|
||||||
add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2);
|
add_got_entry_pair(Got_entry got_entry_1, Got_entry got_entry_2);
|
||||||
|
|
||||||
// Return the offset into the GOT of GOT entry I.
|
// Replace GOT entry I with a new value.
|
||||||
unsigned int
|
void
|
||||||
got_offset(unsigned int i) const
|
replace_got_entry(unsigned int i, Got_entry got_entry);
|
||||||
{ return i * (got_size / 8); }
|
|
||||||
|
|
||||||
// Return the offset into the GOT of the last entry added.
|
// Return the offset into the GOT of the last entry added.
|
||||||
unsigned int
|
unsigned int
|
||||||
last_got_offset() const
|
last_got_offset() const
|
||||||
{ return this->got_offset(this->entries_.size() - 1); }
|
{ return this->got_offset(this->num_entries() - 1); }
|
||||||
|
|
||||||
// Set the size of the section.
|
// Set the size of the section.
|
||||||
void
|
void
|
||||||
set_got_size()
|
set_got_size()
|
||||||
{ this->set_current_data_size(this->got_offset(this->entries_.size())); }
|
{ this->set_current_data_size(this->got_offset(this->num_entries())); }
|
||||||
|
|
||||||
// The list of GOT entries.
|
// The list of GOT entries.
|
||||||
Got_entries entries_;
|
Got_entries entries_;
|
||||||
|
1768
gold/powerpc.cc
1768
gold/powerpc.cc
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user